summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAttila Veghelyi <aveghelyi@dension.com>2023-06-29 16:24:54 +0200
committerAttila Veghelyi <aveghelyi@dension.com>2023-06-29 16:24:54 +0200
commit925d0670c45e1100e412070fa0ce2405604f219a (patch)
tree9bb4412d148bc80751b7a02023cd3e0167f588e7
downloadOpenProgrammer-925d0670c45e1100e412070fa0ce2405604f219a.tar.gz
OpenProgrammer-925d0670c45e1100e412070fa0ce2405604f219a.zip
Init repo
-rw-r--r--.gitignore3
-rw-r--r--24c02.hex18
-rw-r--r--I2CSPI.c243
-rw-r--r--I2CSPI.h2
-rw-r--r--Makefile_op52
-rw-r--r--Makefile_opgui67
-rw-r--r--coff.c207
-rw-r--r--coff.h208
-rw-r--r--common.h5
-rw-r--r--common_op.h114
-rw-r--r--common_opgui.h117
-rw-r--r--deviceRW.c1248
-rw-r--r--deviceRW.h52
-rw-r--r--fileIO.c835
-rw-r--r--fileIO.h8
-rw-r--r--gpl-2.0.txt339
-rw-r--r--hid-example.c182
-rw-r--r--hid_test.c575
-rw-r--r--icd.c1541
-rw-r--r--icd.h185
-rw-r--r--icons.c546
-rw-r--r--ihex.c15
-rw-r--r--instructions.h99
-rw-r--r--op.c1358
-rw-r--r--opgui.c2503
-rw-r--r--opgui.glade3797
-rw-r--r--progAVR.c2450
-rw-r--r--progAVR.h8
-rw-r--r--progEEPROM.c2311
-rw-r--r--progEEPROM.h12
-rw-r--r--progP12.c666
-rw-r--r--progP12.h3
-rw-r--r--progP16.c6546
-rw-r--r--progP16.h20
-rw-r--r--progP18.c2662
-rw-r--r--progP18.h6
-rw-r--r--progP24.c3917
-rw-r--r--progP24.h7
-rw-r--r--progP32.c2454
-rw-r--r--progP32.h4
-rw-r--r--read.pngbin0 -> 1305 bytes
-rw-r--r--read_eeprom.sh1
-rw-r--r--readme98
-rw-r--r--resources.xml10
-rw-r--r--strings.c1070
-rw-r--r--strings.h282
-rw-r--r--style.css3
-rw-r--r--sys.pngbin0 -> 312 bytes
-rw-r--r--write.pngbin0 -> 1228 bytes
49 files changed, 36849 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..a51f015
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+*.[ado]
+op
+opgui
diff --git a/24c02.hex b/24c02.hex
new file mode 100644
index 0000000..ff0489b
--- /dev/null
+++ b/24c02.hex
@@ -0,0 +1,18 @@
+:020000040000FA
+:100000004828000000000000A8000308A9001030E4
+:100010008506A003031D1428A1030F3021052730F6
+:1000200003192830A00026140B111F302405031DCE
+:100030003C2819302506031D3C2810302006031DDE
+:100040003C28271C252827103C28FF302C050319A5
+:100050003C2800302406031935283C30AA00230828
+:10006000AA022C082A0203183C28AC03A71C3B2830
+:10007000A00A27143C28A0032908830028080900A7
+:100080000000000000000000000000000000000070
+:1000900083160313803081002830850000308600ED
+:1000A000831207309F00A0308B0007308500FF309F
+:1000B00086003230A5002830A0000E30A2000F309C
+:1000C000A3000430AB000030A400A600A70081000C
+:1000D000261C7028B220CB20A61C7028A610342124
+:1000E0000630051A103E8500FF302406261D7A28AA
+:1000F000FE309C208600AD20FF308600A320053016
+:00000001FF
diff --git a/I2CSPI.c b/I2CSPI.c
new file mode 100644
index 0000000..e911792
--- /dev/null
+++ b/I2CSPI.c
@@ -0,0 +1,243 @@
+/*
+ * I2CSPI.c - algorithms to interface generic I2C/SPI devices
+ * Copyright (C) 2010-2022 Alberto Maccioni
+ *
+ * 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/>
+ */
+
+
+//configure for GUI or command-line
+#include "common.h"
+#ifdef __GTK_H__
+#define _GTKGUI
+#endif
+
+
+#ifdef _GTKGUI
+ #define printM(id) PrintMessageI2C(id);
+#else
+ #define printM(id) printf(id);
+#endif
+
+#define CS 8
+#define HLD 16
+
+void I2CReceive(int mode,int speed,int N,BYTE *buffer)
+// I2C/SPI receive
+// mode:
+// 0 = I2C 8bit
+// 1 = I2C 16bit
+// 2 = SPI 00
+// 3 = SPI 01
+// 4 = SPI 10
+// 5 = SPI 11
+// speed:
+// 0 = 100 kbps
+// 1 = 200 kbps
+// 2 = 300/400 kbps (SPI/I2C)
+// 3 = 500/800 kbps (SPI/I2C)
+{
+ int j=0;
+ if(N<0) N=0;
+ if(N>60) N=60;
+ if(mode<0) mode=0;
+ if(mode>5) mode=5;
+ if(speed<0) speed=0;
+ if(speed>3) speed=3;
+ if(saveLog){
+ OpenLogFile(); //"Log.txt"
+ fprintf(logfile,"I2C-SPI receive\tmode=%d\tspeed=%d\n",mode,speed);
+ }
+ bufferU[j++]=VREG_DIS; //Disable HV reg
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ if(mode<2){ //I2C mode
+ bufferU[j++]=I2C_INIT;
+ bufferU[j++]=(speed<<3)+(speed>0?0x40:0); //enable slew control if >100k
+ }
+ else{ //SPI mode
+ bufferU[j++]=EXT_PORT; //CS=1
+ bufferU[j++]=CS;
+ bufferU[j++]=0;
+ bufferU[j++]=EXT_PORT; //CS=0
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=SPI_INIT;
+ bufferU[j++]=speed+((mode-2)<<2);
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ if(mode==0){ //I2C read
+ bufferU[j++]=I2C_READ;
+ bufferU[j++]=N>(DIMBUF-4)?DIMBUF-4:N;
+ bufferU[j++]=buffer[0]; //Control byte
+ bufferU[j++]=buffer[1]; //Address;
+ }
+ else if(mode==1){ //I2C read 16bit
+ bufferU[j++]=I2C_READ2;
+ bufferU[j++]=N>(DIMBUF-4)?DIMBUF-4:N;
+ bufferU[j++]=buffer[0]; //Control byte
+ bufferU[j++]=buffer[1]; //Address H;
+ bufferU[j++]=buffer[2]; //Address L;
+ }
+ else if(mode>=2){ //SPI read
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=N>(DIMBUF-5)?DIMBUF-5:N;
+ bufferU[j++]=EXT_PORT; //CS=1
+ bufferU[j++]=CS;
+ bufferU[j++]=0;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(10);
+ if(saveLog){
+ CloseLogFile();
+ }
+ if(bufferI[0]==I2C_READ||bufferI[0]==I2C_READ2||bufferI[0]==SPI_READ){
+ if(bufferI[1]==0xFD){
+ printM(strings[S_I2CAckErr]); //"acknowledge error"
+ }
+ else if(bufferI[1]>0xFA){
+ printM(strings[S_InsErr]); //"unknown instruction"
+ }
+ else{
+ char str[1024]="";
+ char t[16]="";
+ int i;
+ if(mode==0) sprintf(str,"> %02X %02X\r\n",bufferU[2],bufferU[3]);
+ else if(mode==1) sprintf(str,"> %02X %02X\r\n",bufferU[2],bufferU[3]);
+ strcat(str,"< ");
+ for(i=0;i<bufferI[1];i++){
+ sprintf(t,"%02X ",bufferI[i+2]);
+ strcat(str,t);
+ if(i&&i%16==15){
+ strcat(str,"\r\n");
+ }
+ }
+ strcat(str,"\r\n");
+ printM(str);
+ fflush(stdout);
+ }
+ }
+ else printM(strings[S_ComErr]);
+}
+
+void I2CSend(int mode,int speed,int N,BYTE *buffer)
+{
+// I2C/SPI send
+// mode:
+// 0 = I2C 8bit
+// 1 = I2C 16bit
+// 2 = SPI 00
+// 3 = SPI 01
+// 4 = SPI 10
+// 5 = SPI 11
+// speed:
+// 0 = 100 kbps
+// 1 = 200 kbps
+// 2 = 300/400 kbps (SPI/I2C)
+// 3 = 500/800 kbps (SPI/I2C)
+ int i,j=0;
+ if(N<0) N=0;
+ if(N>57) N=57;
+ if(mode<0) mode=0;
+ if(mode>5) mode=5;
+ if(speed<0) speed=0;
+ if(speed>3) speed=3;
+ if(saveLog){
+ OpenLogFile(); //"Log.txt"
+ fprintf(logfile,"I2C-SPI send\tmode=%d\tspeed=%d\n",mode,speed);
+ }
+ bufferU[j++]=VREG_DIS; //Disable HV reg
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ if(mode<2){ //I2C mode
+ bufferU[j++]=I2C_INIT;
+ bufferU[j++]=(speed<<3)+(speed>0?0x40:0); //enable slew control if >100k
+ }
+ else{ //SPI mode
+ bufferU[j++]=EXT_PORT; //CS=1
+ bufferU[j++]=CS;
+ bufferU[j++]=0;
+ bufferU[j++]=EXT_PORT; //CS=0
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=SPI_INIT;
+ bufferU[j++]=speed+((mode-2)<<2);
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ if(mode==0){ //I2C write
+ bufferU[j++]=I2C_WRITE;
+ bufferU[j++]=N>(DIMBUF-5)?DIMBUF-5:N;
+ bufferU[j++]=buffer[0]; //Control byte
+ bufferU[j++]=buffer[1]; //Address
+ for(i=0;i<bufferU[1];i++) bufferU[j++]=buffer[i+2];
+ }
+ else if(mode==1){ //I2C write 16bit
+ bufferU[j++]=I2C_WRITE;
+ bufferU[j++]=N+1>(DIMBUF-5)?DIMBUF-5:N+1;
+ bufferU[j++]=buffer[0]; //Control byte
+ bufferU[j++]=buffer[1]; //Address
+ bufferU[j++]=buffer[2]; //Address L
+ for(i=0;i<bufferU[1]-1;i++) bufferU[j++]=buffer[i+3];
+ }
+ if(mode>=2){ //SPI write
+ bufferU[j++]=SPI_WRITE;
+ bufferU[j++]=N>(DIMBUF-5)?DIMBUF-5:N;
+ for(i=0;i<bufferU[1];i++) bufferU[j++]=buffer[i];
+ bufferU[j++]=EXT_PORT; //CS=1
+ bufferU[j++]=CS;
+ bufferU[j++]=0;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(20);
+ if(saveLog){
+ CloseLogFile();
+ }
+ if(bufferI[0]==I2C_WRITE||bufferI[0]==SPI_WRITE){
+ if(bufferI[1]==0xFD){
+ printM(strings[S_I2CAckErr]); //"acknowledge error"
+ }
+ else if(bufferI[1]>0xFA){
+ printM(strings[S_InsErr]); //"unknown instruction"
+ }
+ else{
+ char str[1024];
+ char t[16];
+ int n=2;
+ int i;
+ sprintf(str,"> ");
+ if(mode<2) n=4;
+ for(i=0;i<bufferU[1];i++){
+ sprintf(t,"%02X ",(BYTE)bufferU[i+n]);
+ strcat(str,t);
+ if(i&&i%16==15){
+ strcat(str,"\r\n");
+ }
+ }
+ strcat(str,"\r\n");
+ printM(str);
+ }
+ }
+ else printM(strings[S_ComErr]); //"communication error \r\n"
+}
+
diff --git a/I2CSPI.h b/I2CSPI.h
new file mode 100644
index 0000000..b3af575
--- /dev/null
+++ b/I2CSPI.h
@@ -0,0 +1,2 @@
+void I2CReceive(int mode,int speed,int N,BYTE *buffer);
+void I2CSend(int mode,int speed,int N,BYTE *buffer);
diff --git a/Makefile_op b/Makefile_op
new file mode 100644
index 0000000..2593383
--- /dev/null
+++ b/Makefile_op
@@ -0,0 +1,52 @@
+# equivalent to #define in c code
+VERSION = 0.12.0
+CC = gcc
+CFLAGS = '-DVERSION="$(VERSION)"' -w -Os -s #size
+#CFLAGS = -w -O3 -s
+#CFLAGS = -w -g #debug
+OBJECTS = op.o \
+ progP12.o \
+ progP16.o \
+ progP18.o \
+ progP24.o \
+ progEEPROM.o \
+ progAVR.o \
+ fileIO.o \
+ deviceRW.o \
+ I2CSPI.o \
+ strings.o
+
+UNAME := $(shell uname)
+ifneq (, $(findstring _NT-, $(UNAME)))
+ OPFLAG =
+else
+ OPFLAG = -lrt
+endif
+
+all: op
+
+op : $(OBJECTS)
+ $(CC) $(CFLAGS) $(OBJECTS) -o op $(OPFLAG)
+ rm $(OBJECTS)
+
+%.o : %.c
+ $(CC) $(CFLAGS) -c $<
+
+clean:
+ rm -f op $(OBJECTS)
+
+prefix := /usr/local
+
+install: op
+ test -d $(prefix) || mkdir $(prefix)
+ test -d $(prefix)/bin || mkdir $(prefix)/bin
+ install -m 0755 op $(prefix)/bin;
+
+package:
+ @echo "Creating op_$(VERSION).tar.gz"
+ @mkdir op-$(VERSION)
+ @cp *.c *.h gpl-2.0.txt Makefile readme utils/*.c op-$(VERSION)
+ @tar -czf op_$(VERSION).tar.gz op-$(VERSION)
+ @rm -rf op-$(VERSION)
+
+.PHONY: all clean install package
diff --git a/Makefile_opgui b/Makefile_opgui
new file mode 100644
index 0000000..9a15ef7
--- /dev/null
+++ b/Makefile_opgui
@@ -0,0 +1,67 @@
+# equivalent to #define in c code
+VERSION = 0.12.1
+CC = gcc
+PREFIX = /usr/local
+
+CFLAGS = '-DVERSION="$(VERSION)"' `pkg-config --libs --cflags gtk+-3.0`
+CFLAGS += -DOPGUI
+CFLAGS += -Os -s #size
+#CFLAGS += -O3 -s #speed
+#CFLAGS += -g #debug
+
+OBJECTS = opgui.o \
+ deviceRW.o \
+ progP12.o \
+ progP16.o \
+ progP18.o \
+ progP24.o \
+ progEEPROM.o \
+ progAVR.o \
+ fileIO.o \
+ I2CSPI.o \
+ coff.o \
+ icd.o \
+ strings.o \
+ resources.o
+# progP32.o \
+
+# Check if we are running on windows
+UNAME := $(shell uname)
+ifneq (, $(findstring _NT-, $(UNAME)))
+ CFLAGS += -mwindows
+else
+ CFLAGS += -lrt
+endif
+
+
+# Targets
+all: opgui
+
+opgui : $(OBJECTS)
+ $(CC) -o $@ $(OBJECTS) $(CFLAGS)
+ rm $(OBJECTS) resources.c
+
+%.o : %.c
+ $(CC) $(CFLAGS) -c $<
+
+resources.c: resources.xml opgui.glade
+ glib-compile-resources resources.xml --target=resources.c --generate-source
+
+clean:
+ rm -f opgui $(OBJECTS) resources.c
+
+install: all
+ #test -d $(prefix) || mkdir $(prefix)
+ #test -d $(prefix)/bin || mkdir $(prefix)/bin
+ @echo "Installing opgui"
+ mkdir -p $(PREFIX)/bin
+ install -m 0755 opgui $(PREFIX)/bin;
+
+package:
+ @echo "Creating opgui_$(VERSION).tar.gz"
+ @mkdir opgui-$(VERSION)
+ @cp *.c *.h *.png gpl-2.0.txt Makefile readme resources.xml opgui.glade style.css opgui-$(VERSION)
+ @tar -czf opgui_$(VERSION).tar.gz opgui-$(VERSION)
+ @rm -rf opgui-$(VERSION)
+
+.PHONY: all clean install package
diff --git a/coff.c b/coff.c
new file mode 100644
index 0000000..fc3120e
--- /dev/null
+++ b/coff.c
@@ -0,0 +1,207 @@
+// COFF file parser
+// COFF file structure:
+// file header
+// optional header
+// sections(name, address, size, raw data pointer, reloc entry, ptr to first line, number of lines)
+// relocation entries
+// symbols (name, value, section, type, class) + optional info
+// lines (source file symbol, line number, address of code)
+// symbol table
+// string table
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "coff.h"
+
+// Analyze COFF file named filename, extract code labels in label[address], undefined labels in ulabel[address],
+// info about each symbol (name, source line, source file index) in source_info,
+// list of source files (index, name, file pointer) in s_files, raw data in data[0x2200]
+int analyzeCOFF(char *filename,char* label[LMAX],char* ulabel[ULMAX],struct src_i source_info[LMAX],struct srcfile **s_files_p,unsigned short data[0x2200],struct symbol **sym_p, int* nsym)
+{
+ int i,j,k;
+ FILE*f=fopen(filename,"rb");
+ if(!f) return 0;
+ scnhdr_t* sections;
+ filehdr_t FileHeader;
+ opthdr_t OptHeader;
+ fread((char*)&FileHeader,sizeof(filehdr_t),1,f); //file header
+/* printf("File header:\nmagic %X, sections %d, time %d, symbol ptr %d, nsymbol %d, opt size %d, flags %X\n",\
+ FileHeader.f_magic,FileHeader.f_nscns,FileHeader.f_timdat,FileHeader.f_symptr,FileHeader.f_nsyms,FileHeader.f_opthdr,FileHeader.f_flags);*/
+ if(FileHeader.f_opthdr==18){ //optional header
+ fread((char*)&OptHeader,2,1,f);
+ fread((char*)&OptHeader+4,16,1,f);
+/* printf("Optional header:\nmagic %X, version %X, processor %X, rom width %d, data width %d\n",\
+ OptHeader.magic,OptHeader.vstamp,OptHeader.proc_type,OptHeader.rom_width_bits,OptHeader.ram_width_bits);*/
+ }
+ sections=(scnhdr_t*)malloc(sizeof(scnhdr_t)*FileHeader.f_nscns);
+ for(i=0;i<FileHeader.f_nscns;i++){
+ fread(&sections[i],40,1,f);
+ }
+ if(fseek(f,FileHeader.f_symptr+FileHeader.f_nsyms*20,SEEK_SET)) printf("seek error\n");
+ int strsize=0,strN=0;
+ char* strtable,**strings;
+ fread((char*)&strsize,4,1,f);
+ strtable=malloc(strsize);
+ strtable[0]=strtable[1]=strtable[2]=strtable[3]=0;
+ fread(&strtable[4],strsize-4,1,f);
+ for(i=4;i<strsize;i++) if(strtable[i]==0) strN++; //count end of string
+ strings=malloc(strN*sizeof(char*));
+ if(strN) strings[0]=&strtable[4];
+ j=1;
+ for(i=4;i<strsize&&j<strN;i++){
+ if(strtable[i]==0){
+ strings[j]=&strtable[i+1];
+ j++;
+ }
+ }
+ char* name,null[]="";
+ for(i=0;i<FileHeader.f_nscns;i++){
+ if(sections[i]._s._s_name[0]) name=sections[i]._s._s_name;
+ else if(sections[i]._s._s_s._s_zeroes==0) name=&strtable[sections[i]._s._s_s._s_offset];
+ else name=null;
+/* printf("Section %d:\nname \"%s\", Paddr %X, Vaddr %X, size %d\nrawptr %d, relptr %d, lineptr %d, Nreloc %d, Nlines %d, flags %X\n",\
+ i,name,sections[i].s_paddr,sections[i].s_vaddr,sections[i].s_size,sections[i].s_scnptr,sections[i].s_relptr,\
+ sections[i].s_lnnoptr,sections[i].s_nreloc,sections[i].s_nlnno,sections[i].s_flags);*/
+ }
+ syment_t symbol;
+ for(i=0;i<LMAX;i++) label[i]=0;
+ for(i=0;i<ULMAX;i++) ulabel[i]=0;
+ int filemax=0;
+ *nsym=0;
+ if(fseek(f,FileHeader.f_symptr,SEEK_SET)) printf("seek error\n");
+ // read all symbols
+ for(i=0;i<FileHeader.f_nsyms;i++){
+ j=fread((void*)&symbol, 1,14,f);
+ j=fread((void*)&symbol+16,1,6,f);
+ if(symbol._n._n_name[0]) name=symbol._n._n_name;
+ else if(symbol._n._n_n._n_zeroes==0) name=&strtable[symbol._n._n_n._n_offset];
+ else name=null;
+ if(symbol.n_sclass==6&&symbol.n_value<LMAX){ //code labels
+ if(label[symbol.n_value]==0){
+ label[symbol.n_value]=malloc(strlen(name)+1);
+ strcpy(label[symbol.n_value],name);
+ }
+ else{
+ printf("conflicting labels at address %X: %s vs. %s\n",(unsigned int)symbol.n_value,label[symbol.n_value],name);
+/* char* temp=malloc(strlen(label[symbol.n_value])+strlen(name)+2);
+ sprintf(temp,"%s %s",label[symbol.n_value],name);
+ free(label[symbol.n_value]);
+ label[symbol.n_value]=temp;*/
+ }
+ }
+ //if(symbol.n_sclass==7&&includesym&&symbol.n_value==0x3fff) includesym=0;
+ if(symbol.n_sclass==7&&symbol.n_value<ULMAX&&symbol.n_scnum>0&&sections[symbol.n_scnum-1].s_size>0){ //store symbols defined in non-empty sections up to ULMAX
+ if(ulabel[symbol.n_value]==0){
+ ulabel[symbol.n_value]=malloc(strlen(name)+1);
+ strcpy(ulabel[symbol.n_value],name);
+ }
+ else{
+ printf("conflicting labels at address %X: %s vs. %s\n",(unsigned int)symbol.n_value,ulabel[symbol.n_value],name);
+/* char* temp=malloc(strlen(ulabel[symbol.n_value])+strlen(name)+2);
+ sprintf(temp,"%s %s",ulabel[symbol.n_value],name);
+ free(ulabel[symbol.n_value]);
+ ulabel[symbol.n_value]=temp;*/
+ }
+// printf("%d %s\n",symbol.n_value,name);
+ }
+ if(symbol.n_sclass==7){
+ //store all symbols in the sym_p array
+ (*nsym)++;
+ *sym_p=realloc(*sym_p,(*nsym)*sizeof(struct symbol));
+ (*sym_p)[*nsym-1].name=strdup(name);
+ (*sym_p)[*nsym-1].value=symbol.n_value;
+ }
+/* printf("\"%s\", Value %X, Section %d, type %X, Storage class %d, Naux %d, %d\n",\
+ name,symbol.n_value,symbol.n_scnum,symbol.n_type,symbol.n_sclass,symbol.n_numaux,i);*/
+ // store file info in s_files
+ if(symbol.n_sclass==103){ //type C_FILE
+ aux_file_t aux;
+ fread(&aux,20,1,f);
+ symbol.n_numaux--;
+// printf("-> \"%s\", line %d, flags %X\n",&strtable[aux.x_offset],aux.x_incline,aux.x_flags);
+ filemax++;
+ *s_files_p=realloc(*s_files_p,filemax*sizeof(struct srcfile));
+ (*s_files_p)[filemax-1].name=strdup(&strtable[aux.x_offset]);
+ (*s_files_p)[filemax-1].ptr=0;
+ (*s_files_p)[filemax-1].l_srcndx=i;
+ (*s_files_p)[filemax-1].nlines=0;
+ (*s_files_p)[filemax-1].lineptr=NULL;
+// printf("%s, idx %d, a %X, i=%d\n",(*s_files_p)[filemax-1].name,(*s_files_p)[filemax-1].l_srcndx,&(*s_files_p)[filemax-1],filemax-1);
+ i++;
+ }
+ i+=symbol.n_numaux;
+ for(j=symbol.n_numaux;j;j--)fread(&symbol,20,1,f);
+ }
+// printf("filemax=%d a[0]=%X\n",filemax,&s_files[0]);
+ // read line info for all sections (line physical address should be unique)
+ struct coff_lineno line;
+ for(i=0;i<LMAX;i++){
+ source_info[i].label=0;
+ source_info[i].src_file=0;
+ source_info[i].src_line=0;
+ }
+ for(i=0;i<FileHeader.f_nscns;i++){
+// printf("lines in section %d:\n",i);
+ if(fseek(f,sections[i].s_lnnoptr,SEEK_SET)) printf("seek error\n");
+ for(j=0;j<sections[i].s_nlnno;j++){
+ fread((void*)&line,6,1,f);
+ fread((void*)&line+8,6,1,f);
+ fread((void*)&line+16,4,1,f);
+ if(line.l_paddr<DATA_MAX){
+ source_info[line.l_paddr].label=0;
+ for(k=0;k<filemax;k++){
+ if((*s_files_p)[k].l_srcndx==line.l_srcndx){
+ source_info[line.l_paddr].src_file=k;
+ if((*s_files_p)[k].ptr==0){
+ //printf("file %s (%X), nlines %d, k=%d, a=%X\n",(*s_files_p)[k].name,(*s_files_p)[k].name,(*s_files_p)[k].nlines,k,s_files_p[k]);
+ scanSourceFile(&(*s_files_p)[k]);
+ }
+ k=filemax+10;
+ }
+ }
+ if(k==filemax)source_info[line.l_paddr].src_file=-1; //no source found
+ source_info[line.l_paddr].src_line=line.l_lnno;
+ }
+ }
+ }
+ unsigned char* raw;
+ for(i=0;i<0x2200;i++) data[i]=0xFFFF;
+ // read raw data in data[0x2200]
+ for(i=0;i<FileHeader.f_nscns;i++){
+ if(sections[i].s_size>0){
+ if(fseek(f,sections[i].s_scnptr,SEEK_SET)) printf("seek error\n");
+ raw=malloc(sections[i].s_size);
+ fread(raw,sections[i].s_size,1,f);
+ if((sections[i].s_paddr+sections[i].s_size/2)<0x2200)memcpy(&data[sections[i].s_paddr],raw,sections[i].s_size);
+ free(raw);
+ }
+ }
+ free(strtable);
+ free(strings);
+ free(raw);
+ return 1;
+}
+
+//open a source file and store a pointer for each line
+FILE* scanSourceFile(struct srcfile *s_files_p){
+// printf("Scansource ptr %X, file %s, nlines %d\n",s_files_p,(*s_files_p).name,(*s_files_p).nlines);
+ FILE* f=fopen((*s_files_p).name,"rb");
+ char line[4096];
+ long int p;
+ char* i;
+ (*s_files_p).ptr=f;
+ if(!f) return f;
+ (*s_files_p).nlines=1; //line # start from index 1
+ p=ftell(f);
+ for(i=fgets(line,4096,f);i;){
+ (*s_files_p).lineptr=realloc((*s_files_p).lineptr,((*s_files_p).nlines+1)*sizeof(long int));
+ (*s_files_p).lineptr[(*s_files_p).nlines]=p;
+ //printf("nlines%d ptr%d %s",(*s_files_p).nlines,p,line);
+ (*s_files_p).nlines++;
+ p=ftell(f);
+ i=fgets(line,4096,f);
+ }
+// printf("file %s, nlines %d\n",(*s_files_p).name,(*s_files_p).nlines);
+ return f;
+}
diff --git a/coff.h b/coff.h
new file mode 100644
index 0000000..1175c04
--- /dev/null
+++ b/coff.h
@@ -0,0 +1,208 @@
+// COFF file parser
+// COFF file structure:
+// file header
+// optional header
+// sections(name, address, size, raw data pointer, reloc entry, ptr to first line, number of lines)
+// relocation entries
+// symbols (name, value, section, type, class) + optional info
+// lines (source file symbol, line number, address of code)
+// symbol table
+// string table
+
+#define LMAX 0x2200
+#define DATA_MAX 0x2200
+#define ULMAX 0x400
+
+typedef struct filehdr
+{
+ unsigned short f_magic;
+ unsigned short f_nscns;
+ unsigned long f_timdat;
+ unsigned long f_symptr;
+ unsigned long f_nsyms;
+ unsigned short f_opthdr;
+ unsigned short f_flags;
+} filehdr_t;
+
+typedef struct opthdr
+{
+ unsigned short magic;
+ unsigned long vstamp;
+ unsigned long proc_type;
+ unsigned long rom_width_bits;
+ unsigned long ram_width_bits;
+} opthdr_t;
+
+typedef struct scnhdr
+{
+ union
+ {
+ char _s_name[8]; /* section name is a string */
+ struct
+ {
+ unsigned long _s_zeroes;
+ unsigned long _s_offset;
+ }_s_s;
+ }_s;
+ unsigned long s_paddr;
+ unsigned long s_vaddr;
+ unsigned long s_size;
+ unsigned long s_scnptr;
+ unsigned long s_relptr;
+ unsigned long s_lnnoptr;
+ unsigned short s_nreloc;
+ unsigned short s_nlnno;
+ unsigned long s_flags;
+} scnhdr_t;
+
+typedef struct reloc
+{
+ unsigned long r_vaddr;
+ unsigned long r_symndx;
+ short r_offset;
+ unsigned short r_type;
+} reloc_t;
+
+#define SYMNMLEN 8
+typedef struct syment
+{
+ union
+ {
+ char _n_name[SYMNMLEN];
+ struct
+ {
+ unsigned long _n_zeroes;
+ unsigned long _n_offset;
+ } _n_n;
+ char *_n_nptr[2];
+ } _n;
+ unsigned long n_value;
+ short n_scnum;
+ unsigned long n_type;
+ char n_sclass;
+ unsigned char n_numaux;
+} syment_t;
+
+typedef struct coff_lineno
+{
+ unsigned long l_srcndx;
+ unsigned short l_lnno;
+ unsigned long l_paddr;
+ unsigned short l_flags;
+ unsigned long l_fcnndx;
+} coff_lineno_t;
+
+typedef struct aux_file
+{
+ unsigned long x_offset;
+ unsigned long x_incline;
+ unsigned char x_flags;
+ char _unused[11];
+} aux_file_t;
+
+typedef struct aux_scn
+{
+ unsigned long x_scnlen;
+ unsigned short x_nreloc;
+ unsigned short x_nlinno;
+ char _unused[12];
+} aux_scn_t;
+
+typedef struct aux_tag
+{
+ char _unused[6];
+ unsigned short x_size;
+ char _unused2[4];
+ unsigned long x_endndx;
+ char _unused3[4];
+} aux_tag_t;
+
+typedef struct aux_eos
+{
+ unsigned long x_tagndx;
+ char _unused[2];
+ unsigned short x_size;
+ char _unused2[12];
+} aux_eos_t;
+
+typedef struct aux_fcn
+{
+ unsigned long x_tagndx;
+ unsigned long x_size;
+ unsigned long x_lnnoptr;
+ unsigned long x_endndx;
+ short x_actscnum;
+ char _unused[2];
+} aux_fcn_t;
+
+typedef struct aux_fcn_calls
+{
+ unsigned long x_calleendx;
+ unsigned long x_is_interrupt;
+ char _unused[12];
+} aux_fcn_calls_t;
+
+#define X_DIMNUM 4
+typedef struct aux_arr
+{
+ unsigned long x_tagndx;
+ unsigned short x_lnno;
+ unsigned short x_size;
+ unsigned short x_dimen[X_DIMNUM];
+ char _unused[4];
+} aux_arr_t;
+
+typedef struct aux_eobf
+{
+ char _unused[4];
+ unsigned short x_lnno;
+ char _unused2[14];
+} aux_eobf_t;
+
+typedef struct aux_bobf
+{
+ char _unused[4];
+ unsigned short x_lnno;
+ char _unused2[6];
+ unsigned long x_endndx;
+ char _unused3[4];
+} aux_bobf_t;
+
+typedef struct aux_var
+{
+ unsigned long x_tagndx;
+ char _unused[2];
+ unsigned short x_size;
+ char _unused2[12];
+} aux_var_t;
+
+typedef struct aux_field
+{
+ char _unused[6];
+ unsigned short x_size;
+ char _unused2[12];
+} aux_field_t;
+
+struct src_i
+{
+ char* label;
+ int src_file;
+ int src_line;
+};
+
+struct srcfile {
+ unsigned long l_srcndx;
+ char* name;
+ FILE* ptr;
+ int nlines;
+ long int *lineptr; //line pointer array
+};
+
+struct symbol {
+ char* name;
+ int value;
+};
+
+FILE* scanSourceFile(struct srcfile *s_files_p);
+int analyzeCOFF(char *filename,char* label[LMAX],char* ulabel[ULMAX],struct src_i source_info[LMAX],\
+ struct srcfile **s_files_p,unsigned short data[0x2200],struct symbol **sym_p, int* nsym);
diff --git a/common.h b/common.h
new file mode 100644
index 0000000..59ab489
--- /dev/null
+++ b/common.h
@@ -0,0 +1,5 @@
+#ifdef OPGUI
+ #include "common_opgui.h"
+#else
+ #include "common_op.h"
+#endif
diff --git a/common_op.h b/common_op.h
new file mode 100644
index 0000000..c1f688a
--- /dev/null
+++ b/common_op.h
@@ -0,0 +1,114 @@
+#ifndef _COMMON_DECLARATIONS
+#define _COMMON_DECLARATIONS
+//#define DEBUG
+#define _APPNAME "OP"
+#define _CMD
+
+#if !defined _WIN32 && !defined __CYGWIN__
+//linux:
+ #include <sys/ioctl.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <asm/types.h>
+ #include <fcntl.h>
+ #include <linux/hiddev.h>
+ #include <linux/hidraw.h>
+ #include <linux/input.h>
+ #include <sys/timeb.h>
+ #include <stdint.h>
+ #include <errno.h>
+#else
+//windows
+ #include <windows.h>
+ #include <setupapi.h>
+ #include <hidusage.h>
+ #include <hidpi.h>
+ #include <math.h>
+ #include <sys/timeb.h>
+ #include <wchar.h>
+#endif
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <ctype.h>
+#include <getopt.h>
+#include <string.h>
+#include "strings.h"
+#include "instructions.h"
+
+typedef unsigned long DWORD;
+typedef unsigned short WORD;
+typedef unsigned char BYTE;
+
+//to use the same code of windows version
+#define PrintMessage printf
+#define PrintMessage1 printf
+#define PrintMessage2 printf
+#define PrintMessage3 printf
+#define PrintMessage4 printf
+#define PrintStatus(s,p1,p2) printf("\b\b\b\b%3d%%",p1); fflush(stdout);
+#define PrintStatusSetup() printf(" ");
+#define PrintStatusEnd() printf("\b\b\b\b");
+#define PrintStatusClear() //only for GUI
+#define COL 16
+//Version defined in makefile
+#if !defined VERSION
+ #define VERSION "unknown"
+#endif
+#define G (12.0/34*1024/5) //=72,2823529412
+#define LOCK 1
+#define FUSE 2
+#define FUSE_H 4
+#define FUSE_X 8
+#define CAL 16
+#define SLOW 256
+
+#if !defined _WIN32 && !defined __CYGWIN__ //Linux
+ #define SYSNAME "Linux"
+ #define DIMBUF 64
+ DWORD GetTickCount();
+ extern unsigned char bufferU[128],bufferI[128];
+#else //Windows
+ #define SYSNAME "Windows"
+ #define DIMBUF 64
+ extern unsigned char bufferU0[128],bufferI0[128];
+ extern unsigned char *bufferU,*bufferI;
+ extern DWORD NumberOfBytesRead,BytesWritten;
+ extern ULONG Result;
+ extern HANDLE WriteHandle,ReadHandle;
+ extern OVERLAPPED HIDOverlapped;
+ extern HANDLE hEventObject;
+#endif
+
+extern char str[4096];
+extern int saveLog;
+extern char** strings;
+extern int fd;
+extern int saveLog,programID,MinDly,load_osccal,load_BKosccal;
+extern int use_osccal,use_BKosccal;
+extern int load_calibword,max_err;
+extern int AVRlock,AVRfuse,AVRfuse_h,AVRfuse_x;
+extern int ICDenable,ICDaddr;
+extern int FWVersion,HwID;
+extern FILE* logfile;
+extern char LogFileName[512];
+extern char loadfile[512],savefile[512];
+extern WORD *memCODE_W;
+extern int size,sizeW,sizeEE,sizeCONFIG,sizeUSERID;
+extern unsigned char *memCODE,*memEE,memID[64],memCONFIG[48],memUSERID[8];
+extern double hvreg;
+extern int RWstop;
+
+int StartHVReg(double V);
+void msDelay(double delay);
+void DisplayEE();
+void PrintMessageI2C(const char *msg);
+int CheckV33Regulator(void);
+void OpenLogFile(void);
+void WriteLogIO();
+void CloseLogFile();
+unsigned int htoi(const char *hex, int length);
+void PacketIO(double delay);
+#endif
diff --git a/common_opgui.h b/common_opgui.h
new file mode 100644
index 0000000..e8b1afa
--- /dev/null
+++ b/common_opgui.h
@@ -0,0 +1,117 @@
+#ifndef _COMMON_DECLARATIONS
+#define _COMMON_DECLARATIONS
+//#define DEBUG
+#define _APPNAME "OPGUI"
+
+#if !defined _WIN32 && !defined __CYGWIN__
+//linux:
+ #include <sys/ioctl.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <asm/types.h>
+ #include <fcntl.h>
+ #include <linux/hiddev.h>
+ #include <linux/hidraw.h>
+ #include <linux/input.h>
+ #include <sys/timeb.h>
+ #include <stdint.h>
+ #include <errno.h>
+#else
+//windows
+ #include <windows.h>
+ #include <setupapi.h>
+ #include <hidusage.h>
+ #include <hidpi.h>
+ #include <math.h>
+ #include <sys/timeb.h>
+ #include <wchar.h>
+#endif
+
+#include <gtk/gtk.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <ctype.h>
+#include <getopt.h>
+#include <string.h>
+#include "strings.h"
+#include "instructions.h"
+
+typedef unsigned long DWORD;
+typedef unsigned short WORD;
+typedef unsigned char BYTE;
+
+//to use the same code of windows version
+#define PrintMessage1(s,p) {sprintf(str,s,p); PrintMessage(str);}
+#define PrintMessage2(s,p1,p2) {sprintf(str,s,p1,p2); PrintMessage(str);}
+#define PrintMessage3(s,p1,p2,p3) {sprintf(str,s,p1,p2,p3); PrintMessage(str);}
+#define PrintMessage4(s,p1,p2,p3,p4) {sprintf(str,s,p1,p2,p3,p4); PrintMessage(str);}
+#define PrintStatus(s,p1,p2) {sprintf(str,s,p1,p2); gtk_statusbar_push(GTK_STATUSBAR(status_bar),statusID,str);while (gtk_events_pending ()) gtk_main_iteration();}
+#define PrintStatusSetup() //only needed for console version
+#define PrintStatusEnd() //only needed for console version
+#define PrintStatusClear() gtk_statusbar_push(GTK_STATUSBAR(status_bar),statusID,"");
+
+#define COL 16
+//Version defined in makefile
+#if !defined VERSION
+ #define VERSION "unknown"
+#endif
+#define G (12.0/34*1024/5) //=72,2823529412
+#define LOCK 1
+#define FUSE 2
+#define FUSE_H 4
+#define FUSE_X 8
+#define CAL 16
+#define SLOW 256
+
+#if !defined _WIN32 && !defined __CYGWIN__ //Linux
+ #define SYSNAME "Linux"
+ #define DIMBUF 64
+ DWORD GetTickCount();
+ extern unsigned char bufferU[128],bufferI[128];
+#else //Windows
+ #define SYSNAME "Windows"
+ #define DIMBUF 64
+ extern unsigned char bufferU0[128],bufferI0[128];
+ extern unsigned char *bufferU,*bufferI;
+ extern DWORD NumberOfBytesRead,BytesWritten;
+ extern ULONG Result;
+ extern HANDLE WriteHandle,ReadHandle;
+ extern OVERLAPPED HIDOverlapped;
+ extern HANDLE hEventObject;
+#endif
+
+extern int statusID;
+extern GtkWidget *status_bar;
+extern char str[4096];
+extern int saveLog;
+extern char** strings;
+extern int fd;
+extern int saveLog,programID,MinDly,load_osccal,load_BKosccal;
+extern int use_osccal,use_BKosccal;
+extern int load_calibword,max_err;
+extern int AVRlock,AVRfuse,AVRfuse_h,AVRfuse_x;
+extern int ICDenable,ICDaddr;
+extern int FWVersion,HwID;
+extern FILE* logfile;
+extern char LogFileName[512];
+extern char loadfile[512],savefile[512];
+extern WORD *memCODE_W;
+extern int size,sizeW,sizeEE,sizeCONFIG,sizeUSERID;
+extern unsigned char *memCODE,*memEE,memID[64],memCONFIG[48],memUSERID[8];
+extern double hvreg;
+extern int RWstop;
+
+int StartHVReg(double V);
+void msDelay(double delay);
+void DisplayEE();
+void PrintMessage(const char *msg);
+void PrintMessageI2C(const char *msg);
+int CheckV33Regulator(void);
+void OpenLogFile(void);
+void WriteLogIO();
+void CloseLogFile();
+unsigned int htoi(const char *hex, int length);
+void PacketIO(double delay);
+#endif
diff --git a/deviceRW.c b/deviceRW.c
new file mode 100644
index 0000000..127a7b6
--- /dev/null
+++ b/deviceRW.c
@@ -0,0 +1,1248 @@
+/*
+ * deviceRW.c - Read-write calls for various devices
+ * Copyright (C) 2010-2022 Alberto Maccioni
+ *
+ * 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/>
+ */
+
+//configure for GUI or command-line
+#include "common.h"
+#include "progP12.h"
+#include "progP16.h"
+#include "progP18.h"
+#include "progP24.h"
+#include "progEEPROM.h"
+#include "progAVR.h"
+//#include "progP32.h"
+
+#ifdef __GTK_H__
+#define _GTKGUI
+#endif
+
+#include "deviceRW.h"
+
+char* devices[]={
+"10F200","10F202","10F204","10F206","10F220","10F222",
+"10F320","10F322",
+"12C508","12C508A","12C509","12C509A","12F508","12F509","12F510","12F519",
+"12F609","12F615","12F617","12F629","12F635","12C671","12C672","12CE673","12CE674","12F675","12F683",
+"12F752",
+"12F529T39","12F529T48",
+"12F1501","12F1571","12F1572","12F1612","12F1822","12F1840",
+"16F505","16F506","16F526","16F527","16F54","16F57","16F570","16F59",
+"16F610","16F616","16F627","16F627A","16F628","16F628A","16F630","16F631",
+"16F636","16F639","16F648A","16F676","16F677","16F684","16F685","16F687",
+"16F688","16F689","16F690",
+"16F707","16F716","16F72","16F720","16F721","16F722","16F722A","16F723","16F723A",
+"16F724","16F726","16F727","16F73","16F737","16F74","16F747","16F753","16F76",
+"16F767","16F77","16F777","16F785",
+"16F818","16F819","16C83","16F83","16F83A","16C84","16F84","16F84A","16F87","16F870","16F871","16F872",
+"16F873","16F873A","16F874","16F874A","16F876","16F876A","16F877","16F877A",
+"16F88","16F882","16F883","16F884","16F886","16F887",
+"16F913","16F914","16F916","16F917","16F946",
+"16F1454","16F1455","16F1459",
+"16F1503","16F1507","16F1508","16F1509","16F1512","16F1513","16F1516","16F1517","16F1518","16F1519",
+"16F1526","16F1527","16LF1554","16LF1559","16F1574","16F1575","16F1578","16F1579",
+"16F1613","16F1614","16F1615","16F1618","16F1619",
+"16F1703","16F1704","16F1705","16F1707","16F1708","16F1709","16F1713","16F1716","16F1717","16F1718","16F1719",
+"16F1764","16F1765","16F1768","16F1769","16F1773","16F1776","16F1777","16F17784","16F1779",
+"16F1782","16F1783","16F1784","16F1786","16F1787","16F1788","16F1789",
+"16F1823","16F1824","16F1825","16F1826","16F1827","16F1828","16F1829","16F1847",
+"16LF1902","16LF1903","16LF1904","16LF1906","16LF1907",
+"16F1933","16F1934","16F1936","16F1937","16F1938","16F1939","16F1946","16F1947",
+"16F15213","16F15214","16F15223""16F15224","16F15225","16F15243","16F15244","16F15245",
+"16F15254","16F15255","16F15256","16F15274","16F15275","16F15276",
+"16F15313","16F15323","16F15324","16F15325","16F15344","16F15345","16F15354","16F15355","16F15356",
+"16F15375","16F15376","16F15385","16F15386",
+"16F17114","16F17115","16F17124","16F17125","16F17126","16F17144","16F17145","16F17146",
+"16F17154","16F17155","16F17156","16F17174","16F17175","16F17176",
+"16F18013","16F18014","16F18015","16F18023","16F18024","16F18025","16F18026","16F18044","16F18045","16F18046",
+"16F18054","16F18055","16F18056","16F18074","16F18075","16F18076",
+"16F18114","16F18115","16F18124","16F18125","16F18126","16F18144","16F18145","16F18146",
+"16F18154","16F18155","16F18156","16F18174","16F18175","16F18176",
+"16F18313","16F18323","16F18324","16F18325","16F18326","16F18344","16F18345","16F18346",
+"16F18424","16F18425","16F18426","16F18444","16F18445","16F18446","16F18455","16F18456",
+"16F18854","16F18855","16F18856","16F18857","16F18875","16F18876","16F18877",
+"16F19155","16F19156","16F19175","16F19176","16F19185","16F19186","16F19195","16F19196","16F19197",
+"18F04Q40","18F04Q41","18F05Q40","18F05Q41","18F06Q40","18F06Q41","18F14Q40","18F14Q41","18F15Q40","18F15Q41","18F16Q40","18F16Q41",
+"18F242","18F248","18F252","18F258","18F442","18F448","18F452","18F458",
+"18F1220","18F1230","18F1320","18F1330","18F13K22","18F13K50","18F14K22","18F14K50",
+"18F2220","18F2221","18F2320","18F23K20","18F23K22","18F2321","18F2331","18F2410",
+"18F24J10","18F24J11","18F2420","18F24K20","18F24K22","18F2423","18F2431","18F2439",
+"18F2450","18F24J50","18F24K50","18F2455","18F2458","18F24Q71","18F2480",
+"18F2510","18F25J10","18F25J11","18F2515","18F2520","18F25K20","18F25K22","18F2523",
+"18F2525","18F2539","18F25K42","18F25Q43","18F2550","18F25J50","18F25K50","18F2553","18F25Q71","18F2580","18F25K80","18F25K83","18F2585",
+"18F2610","18F26J11","18F26J13","18F2620","18F26K20","18F26K22","18F26K42","18F26Q43","18F26J50","18F26K50",
+"18F26J53","18F26Q71","18F2680","18F26K80","18F2682","18F26K83","18F26Q83","18F26Q84","18F2685",
+"18F27J13","18F27K42","18F27Q43","18F27J53","18F27Q83","18F27Q84",
+"18F4220","18F4221","18F4320","18F43K20","18F43K22","18F4321","18F4331",
+"18F4410","18F44J10","18F44J11","18F4420","18F44K20","18F44K22","18F4423","18F4431",
+"18F4439","18F4450","18F44J50","18F4455","18F4458","18F44Q71","18F4480",
+"18F4510","18F45J10","18F45J11","18F4515","18F4520","18F45K20","18F45K22","18F4523",
+"18F4525","18F4539","18F45K42","18F45Q43","18F4550","18F45J50","18F45K50","18F4553","18F45Q71","18F4580","18F45K80","18F4585",
+"18F4610","18F46J11","18F46J13","18F4620","18F46K20","18F46K22","18F46K42","18F46Q43","18F46J50","18F46K50",
+"18F46J53","18F46Q71","18F4680","18F46K80","18F4682","18F46Q83","18F46Q84","18F4685",
+"18F47J13","18F47K42","18F47Q43","18F47J53","18F47Q83","18F47Q84",
+"18F54Q71","18F55K42","18F55Q43","18F55Q71","18F56K42","18F56Q43","18F56Q71","18F56Q83","18F56Q84","18F57K42","18F57Q43","18F57Q83","18F57Q84",
+"18F63J11","18F63J90","18F64J11","18F64J90",
+"18F65J10","18F65J11","18F65J15","18F65J50","18F65J90","18F65K80",
+"18F66J10","18F66J11","18F66J15","18F66J16","18F66J50","18F66J55","18F66J60","18F66J65","18F66J90","18F66J93",
+"18F67J10","18F67J11","18F67J50","18F67J60","18F66K80","18F67J90","18F67J93",
+"18F83J11","18F83J90","18F84J11","18F84J90","18F85J10","18F85J11","18F85J15","18F85J50","18F85J90",
+"18F8520","18F86J10","18F86J11","18F86J15","18F86J16","18F86J50","18F86J55","18F86J60","18F86J65",
+"18F86J72","18F86J90","18F86J93",
+"18F8722","18F87J10","18F87J11","18F87J50","18F87J60","18F87J72","18F87J90","18F87J93",
+"18F96J60","18F96J65","18F97J60",
+"24F04KA200","24F04KA201",
+"24F08KA101","24F08KA102",
+"24F16KA101","24F16KA102",
+"24FJ16GA002","24FJ16GA004",
+"24FJ32GA002","24FJ32GA004","24FJ32GA102","24FJ32GA104",
+"24FJ32GB002","24FJ32GB004",
+"24FJ48GA002","24FJ48GA004",
+"24FJ64GA002","24FJ64GA004","24FJ64GA006","24FJ64GA008","24FJ64GA010",
+"24FJ64GA102","24FJ64GA104","24FJ64GA306","24FJ64GA308","24FJ64GA310",
+"24FJ64GB002","24FJ64GB004","24FJ64GB106","24FJ64GB108","24FJ64GB110",
+"24FJ64GC006","24FJ64GC008","24FJ64GC010",
+"24FJ96GA006","24FJ96GA008","24FJ96GA010",
+"24FJ128GA006","24FJ128GA008","24FJ128GA010","24FJ128GA106","24FJ128GA108","24FJ128GA110",
+"24FJ128GA306","24FJ128GA308","24FJ128GA310",
+"24FJ128GB106","24FJ128GB108","24FJ128GB110","24FJ128GB206","24FJ128GB210",
+"24FJ128GC006","24FJ128GC008","24FJ128GC010",
+"24FJ128DA106","24FJ128DA110","24FJ128DA206","24FJ128DA210",
+"24FJ192GA106","24FJ192GA108","24FJ192GA110",
+"24FJ192GB106","24FJ192GB108","24FJ192GB110",
+"24FJ256GA106","24FJ256GA108","24FJ256GA110",
+"24FJ256GB106","24FJ256GB108","24FJ256GB110",
+"24FJ256GB206","24FJ256GB210",
+"24FJ256DA106","24FJ256DA110","24FJ256DA206","24FJ256DA210",
+"24EP32GP202","24EP32GP203","24EP32GP204",
+"24EP32MC202","24EP32MC203","24EP32MC204",
+"24EP64GP202","24EP64GP203","24EP64GP204","24EP64GP206",
+"24EP64MC202","24EP64MC203","24EP64MC204","24EP64MC206",
+"24EP128GP202","24EP128GP204","24EP128GP206",
+"24EP128MC202","24EP128MC204","24EP128MC206",
+"24EP256GP202","24EP256GP204","24EP256GP206",
+"24EP256MC202","24EP256MC204","24EP256MC206",
+"24EP512GP202","24EP512GP204","24EP512GP206",
+"24EP512MC202","24EP512MC204","24EP512MC206",
+"24HJ12GP201","24HJ12GP202",
+"24HJ16GP304",
+"24HJ32GP202","24HJ32GP204","24HJ32GP302","24HJ32GP304",
+"24HJ64GP202","24HJ64GP204","24HJ64GP206","24HJ64GP210","24HJ64GP502",
+"24HJ64GP504","24HJ64GP506","24HJ64GP510",
+"24HJ128GP202","24HJ128GP204","24HJ128GP206","24HJ128GP210",
+"24HJ128GP306","24HJ128GP310","24HJ128GP502","24HJ128GP504","24HJ128GP506","24HJ128GP510",
+"24HJ256GP206","24HJ256GP210","24HJ256GP610",
+"30F1010","30F2010","30F2011","30F2012","30F2020","30F2023",
+"30F3010","30F3011","30F3012","30F3013","30F3014",
+"30F4011","30F4012","30F4013",
+"30F5011","30F5013","30F5015","30F5016",
+"30F6010","30F6011","30F6012","30F6013","30F6014","30F6015",
+//"32MX270F256",
+"33FJ06GS101","33FJ06GS102","33FJ06GS202",
+"33FJ12GP201","33FJ12GP202","33FJ12MC201","33FJ12MC202",
+"33FJ16GP304","33FJ16GS402","33FJ16GS404","33FJ16GS502","33FJ16GS504","33FJ16MC304",
+"33FJ32GP202","33FJ32GP204","33FJ32GP302","33FJ32GP304",
+"33FJ32GS406","33FJ32GS606","33FJ32GS608","33FJ32GS610",
+"33FJ32MC202","33FJ32MC204","33FJ32MC302","33FJ32MC304",
+"33FJ64GP202","33FJ64GP204","33FJ64GP206","33FJ64GP306","33FJ64GP310",
+"33FJ64GP706","33FJ64GP708","33FJ64GP710","33FJ64GP802","33FJ64GP804",
+"33FJ64GS406","33FJ64GS606","33FJ64GS608","33FJ64GS610",
+"33FJ64MC202","33FJ64MC204","33FJ64MC506","33FJ64MC508","33FJ64MC510",
+"33FJ64MC706","33FJ64MC710","33FJ64MC802","33FJ64MC804",
+"33FJ128GP202","33FJ128GP204","33FJ128GP206","33FJ128GP306","33FJ128GP310","33FJ128GP706",
+"33FJ128GP708","33FJ128GP710","33FJ128GP802","33FJ128GP804",
+"33FJ128MC202","33FJ128MC204","33FJ128MC506","33FJ128MC510","33FJ128MC706","33FJ128MC708",
+"33FJ128MC710","33FJ128MC802","33FJ128MC804",
+"33FJ256GP506","33FJ256GP510","33FJ256GP710",
+"33FJ256MC510","33FJ256MC710",
+"33EP32GP502","33EP32GP503","33EP32GP504",
+"33EP32MC202","33EP32MC203","33EP32MC204","33EP32MC502","33EP32MC503","33EP32MC504",
+"33EP64GP502","33EP64GP503","33EP64GP504","33EP64GP506",
+"33EP64MC202","33EP64MC203","33EP64MC204","33EP64MC206","33EP64MC502","33EP64MC503","33EP64MC504","33EP64MC506",
+"33EP128GP502","33EP128GP504","33EP128GP506",
+"33EP128MC202","33EP128MC204","33EP128MC206","33EP128MC502","33EP128MC504","33EP128MC506",
+"33EP256GP502","33EP256GP504","33EP256GP506",
+"33EP256MC202","33EP256MC204","33EP256MC206","33EP256MC502","33EP256MC504","33EP256MC506",
+"33EP512GP502","33EP512GP504","33EP512GP506",
+"33EP512MC202","33EP512MC204","33EP512MC206","33EP512MC502","33EP512MC504","33EP512MC506",
+"AT90S1200","AT90S2313",
+"AT90S8515","AT90S8535","ATmega48","ATmega8","ATmega88","ATmega8515",
+"ATmega8535","ATmega16","ATmega164","ATmega168","ATmega32","ATmega324",
+"ATmega328","ATmega64","ATmega644","ATmega1284",
+"ATtiny11","ATtiny12","ATtiny13",
+"ATtiny2313","ATtiny24","ATtiny25","ATtiny26","ATtiny261","ATtiny4313","ATtiny44","ATtiny45",
+"ATtiny461","ATtiny48","ATtiny84","ATtiny85","ATtiny88","ATtiny861",
+"2400","2401","2402","2404","2408","2416","2432","2464","24128","24256","24512","241024","241025",
+"25010","25020","25040","25080","25160","25320","25640","25128","25256","25512","251024",
+"95010","95020","95040","95080","95160","95320","95640","95128","95256","95512","95M01","95M02",
+"251005","252005","254005","258005","251605",
+"25X05","25X10","25X20","25X40","25X80","25X16","25X32","25X64","25X128","25Q40",
+"93S46","93x46","93x46A","93S56","93x56","93x56A","93S66","93x66", "93x66A","93x76","93x76A","93x86","93x86A",
+"DS2430","DS2431","DS2433","DS28EC20","DS1820",
+"11010","11020","11040","11080","11160"
+};
+
+int Ndevices=sizeof(devices)/sizeof(char*);
+
+struct DEVICES DEVLIST[]={
+//-------------PIC10-16---------------------------------------------------------
+ {"10F200,10F204,10F220",
+ PIC12,13.0,0,Read12F5xx,{0x100,5},0x40,Write12F5xx,{0x100,0xFF},0}, //256
+ {"10F320",
+ PIC16,9.0,1,Read16Fxxx,{0x100,0,10,0},0x80,Write12F6xx,{0x100,0,-10},0}, //256, vpp, 3.3V
+ {"12C508,12C508A",
+ PIC12,13.0,0,Read12F5xx,{0x200,4},0x40,Write12C5xx,{0x200,0},0}, //512
+ {"12F508,10F202,10F206,10F222",
+ PIC12,13.0,0,Read12F5xx,{0x200,5},0x40,Write12F5xx,{0x200,0x1FF},0}, //512
+ {"16F54",
+ PIC12,13.0,0,Read12F5xx,{0x200,4},0x40,Write12F5xx,{0x200,-1},0}, //512, no osccal
+ {"10F322",
+ PIC16,9.0,1,Read16Fxxx,{0x200,0,10,0},0x80,Write12F6xx,{0x200,0,-10},0}, //512, vpp, 3.3V
+ {"12C509,12C509A",
+ PIC12,13.0,0,Read12F5xx,{0x400,4},0x40,Write12C5xx,{0x400,0},0}, //1K
+ {"12F509,12F510,16F505,16F506",
+ PIC12,13.0,0,Read12F5xx,{0x400,5},0x40,Write12F5xx,{0x400,0x3FF},0}, //1K
+ {"12F519,16F526,16F527",
+ PIC12,13.0,0,Read12F5xx,{0x440,8},0x60,Write12F5xx,{0x440,0x3FF},0}, //1K + 64
+ {"12F529T39,12F529T48",
+ PIC12,13.0,0,Read12F5xx,{0x640,8},0x78,Write12F5xx,{0x640,0x5FF},0}, //1.5K + 64
+ {"16F57,16F59",
+ PIC12,13.0,0,Read12F5xx,{0x800,4},0x40,Write12F5xx,{0x800,-1},0}, //2K
+ {"16F570",
+ PIC12,13.0,0,Read12F5xx,{0x840,8},0x70,Write12F5xx,{0x840,0x7FF},0}, //2K + 64
+ {"16C83,16F83,16F83A",
+ PIC16,13.0,0,Read16Fxxx,{0x200,0x40,8,1},0x10,Write16F8x,{0x200,0x40,-10},0}, //512, 64, vdd
+ {"12C671,12CE673",
+ PIC16,13.0,0,Read16Fxxx,{0x400,0,0,0},0x100,0,{},0}, //1K, vpp
+ {"12F1501",
+ PIC16,8.5,1,Read16F1xxx,{0x400,0,11,0},0x100,Write16F1xxx,{0x400,0,0},0}, //1K, vpp, 3.3V
+ {"12F1571",
+ PIC16,8.5,1,Read16F1xxx,{0x400,0,12,0},0x200,Write16F1xxx,{0x400,0,0},0}, //1K, vpp, 3.3V
+ {"12F609,12F615,16F610",
+ PIC16,13.0,0,Read16Fxxx,{0x400,0,9,0},0x40,Write12F61x,{0x400,0,0},0}, //1K, vpp, cal1
+ {"12F752",
+ PIC16,13.0,0,Read16Fxxx,{0x400,0,10,0},0x80,Write12F61x,{0x400,0,0},0}, //1K, vpp, cal1
+ {"16C84,16F84,16F84A",
+ PIC16,13.0,0,Read16Fxxx,{0x400,0x40,8,1},0x10,Write16F8x,{0x400,0x40,-10},0}, //1K, 64, vdd
+ {"12F635",
+ PIC16,13.0,0,Read16Fxxx,{0x400,0x80,10,0},0x80,Write12F6xx,{0x400,0x80,-10},0}, //1K, 128, vpp, cal1 + cal2
+ {"16F631",
+ PIC16,13.0,0,Read16Fxxx,{0x400,0x80,9,0},0x80,Write12F6xx,{0x400,0x80,-10},0}, //1K, 128, vpp, cal1
+ {"12F629,12F675,16F630,16F676",
+ PIC16,13.0,0,Read16Fxxx,{0x400,0x80,8,0},0x20,Write12F62x,{0x400,0x80,-10},0}, //1K, 128, vpp
+ {"16F627",
+ PIC16,13.0,0,Read16Fxxx,{0x400,-0x80,8,0},0x10,Write16F62x,{0x400,0x80,-10},0}, //1K, 128, vpp, ee@0x2200
+ {"16F627A",
+ PIC16,13.0,0,Read16Fxxx,{0x400,0x80,8,0},0x10,Write12F6xx,{0x400,0x80,-10},0}, //1K, 128, vpp
+ {"16F818",
+ PIC16,13.0,0,Read16Fxxx,{0x400,0x80,8,2},0x10,Write16F81x,{0x400,0x80,-10},0}, //1K, 128, vdd short delay
+ {"16F72",
+ PIC16,8.5,1,Read16Fxxx,{0x800,0,8,1},0x20,Write16F7x,{0x800,0,-10},0}, //2K, vdd, 3.3V
+ {"16F720,16F722,16F722A",
+ PIC16,13.0,0,Read16Fxxx,{0x800,0,11,0},0x100,Write16F72x,{0x800,0,0},0}, //2K, vpp, config1-2 + cal1-2, 3.3V
+ {"12C672,12CE674",
+ PIC16,13.0,0,Read16Fxxx,{0x800,0,0,0},0x100,0,{},0}, //2K, vpp
+ {"16F716",
+ PIC16,13.0,0,Read16Fxxx,{0x800,0,8,2},8,Write16F71x,{0x800,1,-10},0}, //2K, vdd
+ {"16F616,12F617",
+ PIC16,13.0,0,Read16Fxxx,{0x800,0,9,0},0x40,Write12F61x,{0x800,0,0},0}, //2K, vpp, cal1
+ {"16F753",
+ PIC16,12.5,0,Read16Fxxx,{0x800,0,10,0},0x80,Write12F61x,{0x800,0,0},0}, //2K, vpp, cal1
+ {"16LF1902,16F1503,16F1507,16F1512",
+ PIC16,8.5,1,Read16F1xxx,{0x800,0,11,0},0x200,Write16F1xxx,{0x800,0,0},0}, //2K, vpp, 3.3V
+ {"12F1572",
+ PIC16,8.5,1,Read16F1xxx,{0x800,0,12,0},0x200,Write16F1xxx,{0x800,0,0},0}, //2K, vpp, 3.3V
+ {"16F1703,16F1707",
+ PIC16,8.5,1,Read16F1xxx,{0x800,0,13,0},0x200,Write16F1xxx,{0x800,0,0},0}, //2K, vpp, 3.3V
+ {"12F1612,16F1613",
+ PIC16,8.5,1,Read16F1xxx,{0x800,0,13,4},0x200,Write16F1xxx,{0x800,0,4},0}, //2K, vpp, 3.3V
+ {"16F15213,16F15223,16F15243,16F15313,16F15323",
+ PIC16,8.5,1,Read16F18xxx,{0x800,0,0,0},0,Write16F18xxx,{0x800,0,0},0}, //2K, vpp, 3.3V, 8b commands
+ {"16F870,16F871,16F872",
+ PIC16,13.0,0,Read16Fxxx,{0x800,0x40,8,1},0x100,Write16F87x,{0x800,0x40,-10},0}, //2K, 64, vdd
+ {"16F628",
+ PIC16,13.0,0,Read16Fxxx,{0x800,-0x80,8,0},0x10,Write16F62x,{0x800,0x80,-10},0}, //2K, 128, vpp, ee@0x2200
+ {"16F628A",
+ PIC16,13.0,0,Read16Fxxx,{0x800,0x80,8,0},0x10,Write12F6xx,{0x800,0x80,-10},0}, //2K, 128, vpp
+ {"16F882",
+ PIC16,13.0,0,Read16Fxxx,{0x800,0x80,10,0},0x80,Write16F88x,{0x800,0x80,-10},0}, //2K, 128, vpp, config2 + cal1
+ {"16F819",
+ PIC16,13.0,0,Read16Fxxx,{0x800,0x100,8,2},0x10,Write16F81x,{0x800,0x100,-10},0}, //2K, 256, vdd short delay
+ {"12F683,16F684",
+ PIC16,13.0,0,Read16Fxxx,{0x800,0x100,9,0},0x40,Write12F6xx,{0x800,0x100,-10},0}, //2K, 256, vpp, cal1
+ {"16F636,16F639,16F785",
+ PIC16,13.0,0,Read16Fxxx,{0x800,0x100,10,0},0x40,Write12F6xx,{0x800,0x100,-10},0}, //2K, 256, vpp, cal1 + cal2
+ {"16F677,16F687",
+ PIC16,13.0,0,Read16Fxxx,{0x800,0x100,9,0},0x80,Write12F6xx,{0x800,0x100,-10},0}, //2K, 256, vpp, cal1
+ {"12F1822,16F1823,16F1826",
+ PIC16,8.5,1,Read16F1xxx,{0x800,0x100,11,0},0x200,Write16F1xxx,{0x800,0x100,0},0}, //2K, 256, vpp, 3.3V
+ {"16F1782",
+ PIC16,8.5,1,Read16F1xxx,{0x800,0x100,19,0},0x200,Write16F1xxx,{0x800,0x100,0},0}, //2K, 256, vpp, 3.3V
+ {"16F18313,16F18323",
+ PIC16,8.5,1,Read16F1xxx,{0x800,0x100,11,0x1C},0x20,Write16F1xxx,{0x800,0x100,0x1C},0}, //2K, 256, vpp, 3.3V, new cmd
+ {"16F18013,16F18023",
+ PIC16,8.5,1,Read16F18xxx,{0x800,1,0,0},0,Write16F18xxx,{0x800,0x100,0},0}, //2K, 256, vpp, 3.3V, 8b commands
+ {"16F73,16F74",
+ PIC16,13.0,0,Read16Fxxx,{0x1000,0,8,1},0x20,Write16F7x,{0x1000,0,-10},0}, //4K, vdd
+ {"16F737,16F747",
+ PIC16,13.0,0,Read16Fxxx,{0x1000,0,9,2},9,Write16F7x,{0x1000,1,-10},0}, //4K, vdd short/no delay
+ {"16F721,16F723,16F723A,16F724",
+ PIC16,13.0,0,Read16Fxxx,{0x1000,0,11,0},0x100,Write16F72x,{0x1000,0,0},0}, //4K, vpp, config1-2 + cal1-2, 3.3V
+ {"16LF1903,16LF1904,16F1508,16F1513,16LF1554",
+ PIC16,8.5,1,Read16F1xxx,{0x1000,0,11,0},0x200,Write16F1xxx,{0x1000,0,0},0}, //4K, vpp, 3.3V
+ {"16F1574,16F1578",
+ PIC16,8.5,1,Read16F1xxx,{0x1000,0,12,0},0x200,Write16F1xxx,{0x1000,0,0},0}, //4K, vpp, 3.3V
+ {"16F1704,16F1708",
+ PIC16,8.5,1,Read16F1xxx,{0x1000,0,13,0},0x200,Write16F1xxx,{0x1000,0,0},0}, //4K, vpp, 3.3V
+ {"16F1614,16F1618",
+ PIC16,8.5,1,Read16F1xxx,{0x1000,0,13,4},0x200,Write16F1xxx,{0x1000,0,4},0}, //4K, vpp, 3.3V
+ {"16F1713",
+ PIC16,8.5,1,Read16F1xxx,{0x1000,0,17,0},0x200,Write16F1xxx,{0x1000,0,0},0}, //4K, vpp, 3.3V
+ {"16F1783,16F1784",
+ PIC16,8.5,1,Read16F1xxx,{0x1000,0,19,0},0x200,Write16F1xxx,{0x1000,0,0},0}, //4K, vpp, 3.3V
+ {"16F1764,16F1768",
+ PIC16,8.5,1,Read16F1xxx,{0x1000,0,20,0},0x200,Write16F1xxx,{0x1000,0,0},0}, //4K, vpp, 3.3V
+ {"16F1773",
+ PIC16,8.5,1,Read16F1xxx,{0x1000,0,24,0},0x200,Write16F1xxx,{0x1000,0,0},0}, //4K, vpp, 3.3V
+ {"16F15214,16F15224,16F15244,16F15254,16F15274,16F15324,16F15344,16F15354",
+ PIC16,8.5,1,Read16F18xxx,{0x1000,0,0,0},0,Write16F18xxx,{0x1000,0,0},0}, //4K, vpp, 3.3V, 8b commands
+ {"16F873A,16F874A",
+ PIC16,13.0,0,Read16Fxxx,{0x1000,0x80,8,1},0x100,Write16F87xA,{0x1000,0x80,1},0}, //4K, 128, vdd
+ {"16F873,16F874",
+ PIC16,13.0,0,Read16Fxxx,{0x1000,-0x80,8,1},0x100,Write16F87x,{0x1000,-0x80,-10},0}, //4K, 128, vdd, ee@0x2200
+ {"16F685,16F689,16F690",
+ PIC16,13.0,0,Read16Fxxx,{0x1000,0x100,9,0},0x80,Write12F6xx,{0x1000,0x100,-10},0}, //4K, 256, vpp, cal1
+ {"16F688",
+ PIC16,13.0,0,Read16Fxxx,{0x1000,0x100,9,0},0x40,Write12F6xx,{0x1000,0x100,-10},0}, //4K, 256, vpp, cal1
+ {"16F883,16F884",
+ PIC16,13.0,0,Read16Fxxx,{0x1000,0x100,10,0},0x80,Write16F88x,{0x1000,0x100,-10},0}, //4K, 256, vpp, config2 + cal1
+ {"16F648A",
+ PIC16,13.0,0,Read16Fxxx,{0x1000,0x100,8,0},0x10,Write12F6xx,{0x1000,0x100,-10},0}, //4K, 256, vpp
+ {"16F87,16F88",
+ PIC16,13.0,0,Read16Fxxx,{0x1000,0x100,9,2},0x10,Write16F81x,{0x1000,0x100,-10},0}, //4K, 256, vdd short delay
+ {"16F913,16F914",
+ PIC16,13.0,0,Read16Fxxx,{0x1000,0x100,10,0},0x40,Write12F6xx,{0x1000,0x100,-10},0}, //4K, 256, vpp, cal1 + cal2
+ {"16F1933,16F1934,16F1824,16F1827,16F1828,12F1840",
+ PIC16,8.5,1,Read16F1xxx,{0x1000,0x100,11,0},0x200,Write16F1xxx,{0x1000,0x100,0},0}, //4K, 256, vpp, 3.3V
+ {"16F18324,16F18344",
+ PIC16,8.5,1,Read16F1xxx,{0x1000,0x100,11,0x1C},0x20,Write16F1xxx,{0x1000,0x100,0x1C},0}, //4K, 256, vpp, 3.3V, new cmd
+ {"16F17114,16F17124,16F17144,16F17154,16F17174,16F18014,16F18024,16F18044,16F18054,16F18074,16F18114,16F18124,16F18144,\
+ 16F18154,16F18174,16F18424,16F18444",
+ PIC16,8.5,1,Read16F18xxx,{0x1000,1,0,0},0,Write16F18xxx,{0x1000,0x100,0},0}, //4K, 256, vpp, 3.3V, 8b commands
+ {"16F18854",
+ PIC16,8.5,1,Read16F18xxx,{0x1000,0x100,0,0x10},0,Write16F18xxx,{0x1000,0x100,0x10},0}, //4K, 256, vpp, 3.3V, 8b commands no DIA
+ {"16F76,16F77",
+ PIC16,13.0,0,Read16Fxxx,{0x2000,0,8,1},0x20,Write16F7x,{0x2000,0,-10},0}, //8K, vdd
+ {"16F767,16F777",
+ PIC16,13.0,0,Read16Fxxx,{0x2000,0,9,2},0x40,Write16F7x,{0x2000,1,-10},0}, //8K, vdd short delay
+ {"16F726,16F727,16F707",
+ PIC16,8.5,1,Read16Fxxx,{0x2000,0,11,0},0x100,Write16F72x,{0x2000,0,0},0}, //8K, vpp, config1-2 + cal1-2, 3.3V
+ {"16LF1906,16LF1907,16F1509,16F1454,16F1455,16F1459,16F1516,16F1517,16F1526,16LF1559",
+ PIC16,8.5,1,Read16F1xxx,{0x2000,0,11,0},0x200,Write16F1xxx,{0x2000,0,0},0}, //8K, vpp, 3.3V
+ {"16F1575,16F1579",
+ PIC16,8.5,1,Read16F1xxx,{0x2000,0,12,0},0x200,Write16F1xxx,{0x2000,0,0},0}, //8K, vpp, 3.3V
+ {"16F1705,16F1709",
+ PIC16,8.5,1,Read16F1xxx,{0x2000,0,13,0},0x200,Write16F1xxx,{0x2000,0,0},0}, //8K, vpp, 3.3V
+ {"16F1615,16F1619",
+ PIC16,8.5,1,Read16F1xxx,{0x2000,0,13,4},0x200,Write16F1xxx,{0x2000,0,4},0}, //8K, vpp, 3.3V
+ {"16F1716,16F1717",
+ PIC16,8.5,1,Read16F1xxx,{0x2000,0,17,0},0x200,Write16F1xxx,{0x2000,0,0},0}, //8K, vpp, 3.3V
+ {"16F1765,16F1769",
+ PIC16,8.5,1,Read16F1xxx,{0x2000,0,20,0},0x200,Write16F1xxx,{0x2000,0,0},0}, //8K, vpp, 3.3V
+ {"16F1776,16F1777",
+ PIC16,8.5,1,Read16F1xxx,{0x2000,0,24,0},0x200,Write16F1xxx,{0x2000,0,0},0}, //8K, vpp, 3.3V
+ {"16F15225,16F15245,16F15255,16F15275,16F15325,16F15345,16F15355,16F15375,16F15385",
+ PIC16,8.5,1,Read16F18xxx,{0x2000,0,0,0},0,Write16F18xxx,{0x2000,0,0},0}, //8K, vpp, 3.3V, 8b commands
+ {"16F876A,16F877A",
+ PIC16,13.0,0,Read16Fxxx,{0x2000,0x100,8,1},0x100,Write16F87xA,{0x2000,0x100,1},0}, //8K, 256, vdd
+ {"16F876,16F877",
+ PIC16,13.0,0,Read16Fxxx,{0x2000,-0x100,8,1},0x100,Write16F87x,{0x2000,-0x100,-10},0}, //8K, 256, vdd, ee@0x2200
+ {"16F886,16F887",
+ PIC16,11.0,0,Read16Fxxx,{0x2000,0x100,10,0},0x80,Write16F88x,{0x2000,0x100,-10},0}, //8K, 256, vpp, config2 + cal1
+ {"16F916,16F917,16F946",
+ PIC16,13.0,0,Read16Fxxx,{0x2000,0x100,10,0},0x40,Write12F6xx,{0x2000,0x100,-10},0}, //8K, 256, vpp, cal1 + cal2
+ {"16F1936,16F1937,16F1946,16F1825,16F1829,16F1847",
+ PIC16,8.5,1,Read16F1xxx,{0x2000,0x100,11,0},0x200,Write16F1xxx,{0x2000,0x100,0},0}, //8K, 256, vpp, 3.3V
+ {"16F1786,16F1787",
+ PIC16,8.5,1,Read16F1xxx,{0x2000,0x100,19,0},0x200,Write16F1xxx,{0x2000,0x100,0},0}, //8K, 256, vpp, 3.3V
+ {"16F18325,16F18345",
+ PIC16,8.5,1,Read16F1xxx,{0x2000,0x100,11,0x1C},0x20,Write16F1xxx,{0x2000,0x100,0x1C},0}, //8K, 256, vpp, 3.3V, new cmd
+ {"16F17115,16F17125,16F17145,16F17155,16F17175,16F18015,16F18025,16F18045,16F18055,16F18075,16F18115,16F18125,16F18145,16F18155,16F18175,\
+ 16F18425,16F18445,16F18455,16F19155,16F19175,16F19185,16F19195",
+ PIC16,8.5,1,Read16F18xxx,{0x2000,1,0,0},0,Write16F18xxx,{0x2000,0x100,0},0}, //8K, 256, vpp, 3.3V, 8b commands
+ {"16F18855,16F18875",
+ PIC16,8.5,1,Read16F18xxx,{0x2000,0x100,0,0x10},0,Write16F18xxx,{0x2000,0x100,0x10},0}, //8K, 256, vpp, 3.3V, 8b commands no DIA
+ {"16F1518,16F1519,16F1527",
+ PIC16,8.5,1,Read16F1xxx,{0x4000,0,11,0},0x200,Write16F1xxx,{0x4000,0,0},0}, //16K, vpp, 3.3V
+ {"16F1718,16F1719",
+ PIC16,8.5,1,Read16F1xxx,{0x4000,0,17,0},0x200,Write16F1xxx,{0x4000,0,0},0}, //16K, vpp, 3.3V
+ {"16F1778,16F1779",
+ PIC16,8.5,1,Read16F1xxx,{0x4000,0,24,0},0x200,Write16F1xxx,{0x4000,0,0},0}, //16K, vpp, 3.3V
+ {"16F15256,16F15276,16F15356,16F15376,16F15386",
+ PIC16,8.5,1,Read16F18xxx,{0x4000,0,0,0},0,Write16F18xxx,{0x4000,0,0},0}, //16K, vpp, 3.3V, 8b commands
+ {"16F1938,16F1939,16F1947",
+ PIC16,8.5,1,Read16F1xxx,{0x4000,0x100,11,0},0x200,Write16F1xxx,{0x4000,0x100,0},0}, //16K, 256, vpp, 3.3V
+ {"16F1788,16F1789",
+ PIC16,8.5,1,Read16F1xxx,{0x4000,0x100,19,0},0x200,Write16F1xxx,{0x4000,0x100,0},0}, //16K, 256, vpp, 3.3V
+ {"16F18326,16F18346",
+ PIC16,8.5,1,Read16F1xxx,{0x4000,0x100,11,0x1C},0x20,Write16F1xxx,{0x4000,0x100,0x1C},0}, //16K, 256, vpp, 3.3V, new cmd
+ {"16F17126,16F17146,16F17156,16F17176,16F18026,16F18046,16F18056,16F18076,16F18126,16F18146,16F18156,16F18176,\
+ 16F18426,16F18446,16F18456,16F19156,16F19176,16F19186,16F19196",
+ PIC16,8.5,1,Read16F18xxx,{0x4000,1,0,0},0,Write16F18xxx,{0x4000,0x100,0},0}, //16K, 256, vpp, 3.3V, 8b commands
+ {"16F18856,16F18876",
+ PIC16,8.5,1,Read16F18xxx,{0x4000,0x100,0,0x10},0,Write16F18xxx,{0x4000,0x100,0x10},0}, //16K, 256, vpp, 3.3V, 8b commands no DIA
+ {"16F19197",
+ PIC16,8.5,1,Read16F18xxx,{0x8000,1,0,0},0,Write16F18xxx,{0x8000,0x100,0},0}, //32K, 256, vpp, 3.3V, 8b commands
+ {"16F18857,16F18877",
+ PIC16,8.5,1,Read16F18xxx,{0x8000,0x100,0,0x10},0,Write16F18xxx,{0x8000,0x100,0x10},0}, //32K, 256, vpp, 3.3V, 8b commands no DIA
+//-------------PIC18---------------------------------------------------------
+// Read18Fx options:
+// bit [3:0]
+// 0 = vdd before vpp (12V)
+// 1 = vdd before vpp (9V)
+// 2 = low voltage entry with 32 bit key
+// bit [7:4]
+// 0 = normal control registers address
+// 1 = new control registers address (18FxxK80)
+//
+// Write18Fx options:
+// bit [3:0]
+// 0 = vdd before vpp (12V)
+// 1 = vdd before vpp (9V)
+// 2 = low voltage entry with 32 bit key
+// bit [7:4]
+// 0 = normal eeprom write algoritm
+// 1 = with unlock sequence 55 AA
+// bit [11:8]
+// 0 = 15ms erase delay, 1ms code write time, 5ms EE write, 5ms config write
+// 1 = 550ms erase delay, 1.2ms code write time, no config or EEPROM
+// 2 = 550ms erase delay, 3.4ms code write time, no config or EEPROM
+// 3 = separate block erase with 5ms delay, 1ms code write, 5ms EE write, 5ms config write
+// + new control registers address (18FxxK80)
+ {"18F1230",
+ PIC18,12,0,Read18Fx,{0x1000,0x80,0},0,Write18Fx,{0x1000,0x80,8,0x0F0F,0x8787,0},0}, //4K, 128, 8
+ {"18F2221,18F4221",
+ PIC18,12,0,Read18Fx,{0x1000,0x100,0},0,Write18Fx,{0x1000,0x100,8,0x3F3F,0x8F8F,0},0}, //4K, 256, 8
+ {"18F1220,18F2220,18F4220",
+ PIC18,12,0,Read18Fx,{0x1000,0x100,0},0,Write18Fx,{0x1000,0x100,8,0x10000,0x80,0x10},0}, //4K, 256, 8, EE with unlock
+ {"18F63J11,18F63J90,18F83J11,18F83J90",
+ PIC18,-1,1,Read18Fx,{0x2000,0,2},0,Write18Fx,{0x2000,0,64,0x0101,0x8080,0x202},0}, //8K, 0, 64, LV
+ {"18F1330",
+ PIC18,12,0,Read18Fx,{0x2000,0x80,0},0,Write18Fx,{0x2000,0x80,8,0x0F0F,0x8787,0},0}, //8K, 128, 8
+ {"18F2321,18F4321",
+ PIC18,12,0,Read18Fx,{0x2000,0x100,0},0,Write18Fx,{0x2000,0x100,8,0x3F3F,0x8F8F,0},0}, //8K, 256, 8
+ {"18F1320,18F2320,18F4320,18F2331,18F4331",
+ PIC18,12,0,Read18Fx,{0x2000,0x100,0},0,Write18Fx,{0x2000,0x100,8,0x10000,0x80,0x10},0}, //8K, 256, 8, EE with unlock
+ {"18F13K50,18F13K22",
+ PIC18,8.5,1,Read18Fx,{0x2000,0x100,1},0,Write18Fx,{0x2000,0x100,8,0x0F0F,0x8F8F,1},0}, //8K, 256, 8, 9V
+ {"18F23K20,18F43K20",
+ PIC18,8.5,1,Read18Fx,{0x2000,0x100,1},0,Write18Fx,{0x2000,0x100,16,0x0F0F,0x8F8F,1},0}, //8K, 256, 16, 9V
+ {"18F23K22,18F43K22",
+ PIC18,8.5,1,Read18Fx,{0x2000,0x100,1},0,Write18Fx,{0x2000,0x100,64,0x0F0F,0x8F8F,1},0}, //8K, 256, 64, 9V
+ {"18F2439,18F4439",
+ PIC18,12,0,Read18Fx,{0x3000,0x100,0},0,Write18Fx,{0x3000,0x100,8,0x10000,0x80,0x10},0}, //12K, 256, 8, EE with unlock
+ {"18F2410,18F4410",
+ PIC18,12,0,Read18Fx,{0x4000,0,0},0,Write18Fx,{0x4000,0,32,0x3F3F,0x8F8F,0},0}, //16K, 0, 32
+ {"18F24J10,18F44J10,18F64J11,18F64J90,18F84J11,18F84J90",
+ PIC18,-1,1,Read18Fx,{0x4000,0,2},0,Write18Fx,{0x4000,0,64,0x0101,0x8080,0x202},0}, //16K, 0, 64, LV
+ {"18F24J11,18F24J50,18F44J11,18F44J50",
+ PIC18,-1,1,Read18Fx,{0x4000,0,2},0,Write18Fx,{0x4000,0,64,0x0101,0x8080,0x102},0}, //16K, 0, 64, LV
+ {"18F2420,18F2423,18F4420,18F4423,18F2480,18F4480",
+ PIC18,12,0,Read18Fx,{0x4000,0x100,0},0,Write18Fx,{0x4000,0x100,32,0x3F3F,0x8F8F,0},0}, //16K, 256, 32
+ {"18F2431,18F4431,18F242,18F248,18F442,18F448",
+ PIC18,12,0,Read18Fx,{0x4000,0x100,0},0,Write18Fx,{0x4000,0x100,8,0x10000,0x80,0x10},0}, //16K, 256, 8, EE with unlock
+ {"18F2450,18F4450",
+ PIC18,12,0,Read18Fx,{0x4000,0,0},0,Write18Fx,{0x4000,0,16,0x3F3F,0x8F8F,0},0}, //16K, 0, 16
+ {"18F14K50,18F14K22",
+ PIC18,8.5,1,Read18Fx,{0x4000,0x100,1},0,Write18Fx,{0x4000,0x100,16,0x0F0F,0x8F8F,1},0}, //16K, 256, 16, 9V
+ {"18F24K20,18F44K20",
+ PIC18,8.5,1,Read18Fx,{0x4000,0x100,1},0,Write18Fx,{0x4000,0x100,32,0x0F0F,0x8F8F,1},0}, //16K, 256, 32, 9V
+ {"18F24K22,18F44K22,18F24K50",
+ PIC18,8.5,1,Read18Fx,{0x4000,0x100,1},0,Write18Fx,{0x4000,0x100,64,0x0F0F,0x8F8F,1},0}, //16K, 256, 64, 9V
+ {"18F04Q40,18F14Q40,18F04Q41,18F14Q41,18F24Q71,18F44Q71,18F54Q71",
+ PIC18,8.5,1,Read18FKx,{0x4000,1,0x10},0,Write18FKx,{0x4000,0x200,0x10,0,0,0},0}, //16K, 256, --, LV
+ {"18F2455,18F2458,18F4455,18F4458",
+ PIC18,12,0,Read18Fx,{0x6000,0x100,0},0,Write18Fx,{0x6000,0x100,32,0x3F3F,0x8F8F,0},0}, //24K, 256, 32
+ {"18F2539,18F4539",
+ PIC18,12,0,Read18Fx,{0x6000,0x100,0},0,Write18Fx,{0x6000,0x100,8,0x10000,0x80,0x10},0}, //24K, 256, 8, EE with unlock
+ {"18F2510,18F4510",
+ PIC18,12,0,Read18Fx,{0x8000,0,0},0,Write18Fx,{0x8000,0,32,0x3F3F,0x8F8F,0},0}, //32K, 0, 32
+ {"18F25J10,18F45J10,18F65J10,18F65J11,18F65J50,18F65J90,18F85J10,18F85J11,18F85J50,18F85J90",
+ PIC18,-1,1,Read18Fx,{0x8000,0,2},0,Write18Fx,{0x8000,0,64,0x0101,0x8080,0x202},0}, //32K, 0, 64, LV
+ {"18F25J11,18F25J50,18F45J11,18F45J50",
+ PIC18,-1,1,Read18Fx,{0x8000,0,2},0,Write18Fx,{0x8000,0,64,0x0101,0x8080,0x102},0}, //32K, 0, 64, LV
+ {"18F252,18F258,18F452,18F458",
+ PIC18,12,0,Read18Fx,{0x8000,0x100,0},0,Write18Fx,{0x8000,0x100,8,0x10000,0x80,0x10},0}, //32K, 256, 8, EE with unlock
+ {"18F2550,18F2553,18F4550,18F4553,18F2520,18F2523,18F4520,18F4523,18F2580,18F4580",
+ PIC18,12,0,Read18Fx,{0x8000,0x100,0},0,Write18Fx,{0x8000,0x100,32,0x3F3F,0x8F8F,0},0}, //32K, 256, 32
+ {"18F25K20,18F45K20",
+ PIC18,8.5,1,Read18Fx,{0x8000,0x100,1},0,Write18Fx,{0x8000,0x100,32,0x0F0F,0x8F8F,1},0}, //32K, 256, 32, 9V
+ {"18F25K22,18F45K22,18F25K50,18F45K50",
+ PIC18,8.5,1,Read18Fx,{0x8000,0x100,1},0,Write18Fx,{0x8000,0x100,64,0x0F0F,0x8F8F,1},0}, //32K, 256, 64, 9V
+ {"18F25K42,18F45K42,18F55K42",
+ PIC18,8.5,1,Read18FKx,{0x8000,1,0},0,Write18FKx,{0x8000,0x100,0,0,0,0},0}, //32K, 256, --, LV
+ {"18F05Q40,18F15Q40,18F05Q41,18F15Q41,18F25Q71,18F45Q71,18F55Q71",
+ PIC18,8.5,1,Read18FKx,{0x8000,1,0x10},0,Write18FKx,{0x8000,0x200,0x10,0,0,0},0}, //32K, 256, --, LV
+ {"18F25K80,18F45K80,18F65K80",
+ PIC18,8.5,1,Read18Fx,{0x8000,0x400,0x13},0,Write18Fx,{0x8000,0x400,64,0,0,0x303},0}, //32K, 1K, 64, 9V, xxK80
+ {"18F8520",
+ PIC18,12,0,Read18Fx,{0x8000,0x400,0},0,Write18Fx,{0x8000,0x400,8,0x10000,0x0080,0x10},0},//32K, 1K, 8, EE with unlock
+ {"18F25Q43,18F45Q43,18F55Q43",
+ PIC18,8.5,1,Read18FKx,{0x8000,1,0x10},0,Write18FKx,{0x8000,0x400,0x10,0,0,0},0}, //32K, 1k, --, LV
+ {"18F25K83",
+ PIC18,8.5,1,Read18FKx,{0x8000,1,0},0,Write18FKx,{0x8000,0x400,0,0,0,0},0}, //32K, 1k, --, LV
+ {"18F2515,18F4515",
+ PIC18,12,0,Read18Fx,{0xC000,0,0},0,Write18Fx,{0xC000,0,64,0x3F3F,0x8F8F,0},0}, //48K, 0, 64
+ {"18F65J15,18F85J15",
+ PIC18,-1,1,Read18Fx,{0xC000,0,2},0,Write18Fx,{0xC000,0,64,0x0101,0x8080,0x202},0}, //48K, 0, 64, LV
+ {"18F2525,18F2585,18F4525,18F4585",
+ PIC18,12,0,Read18Fx,{0xC000,0x400,0},0,Write18Fx,{0xC000,0x400,64,0x3F3F,0x8F8F,0},0}, //48K, 1K, 64
+ {"18F2610,18F4610",
+ PIC18,12,0,Read18Fx,{0x10000,0,0},0,Write18Fx,{0x10000,0,64,0x3F3F,0x8F8F,0},0}, //64K, 0, 64
+ {"18F26J11,18F26J13,18F26J50,18F26J53,18F46J11,18F46J13,18F46J50,18F46J53",
+ PIC18,-1,1,Read18Fx,{0x10000,0,2},0,Write18Fx,{0x10000,0,64,0x0101,0x8080,0x102},0}, //64K, 0, 64, LV
+ {"18F66J60,18F86J60,18F96J60,18F66J10,18F66J11,18F66J50,18F66J90,18F66J93,18F86J10,18F86J11,18F86J50,18F86J72,18F86J90,18F86J93",
+ PIC18,-1,1,Read18Fx,{0x10000,0,2},0,Write18Fx,{0x10000,0,64,0x0101,0x8080,0x202},0}, //64K, 0, 64, LV
+ {"18F2620,18F2680,18F4620,18F4680",
+ PIC18,12,0,Read18Fx,{0x10000,0x400,0},0,Write18Fx,{0x10000,0x400,64,0x3F3F,0x8F8F,0},0},//64K, 1K, 64
+ {"18F26K20,18F46K20,18F26K22,18F46K22,18F26K50,18F46K50",
+ PIC18,12,0,Read18Fx,{0x10000,0x100,1},0,Write18Fx,{0x10000,0x100,64,0x0F0F,0x8F8F,1},0},//64K, 256, 64, 9V
+ {"18F06Q40,18F16Q40,18F06Q41,18F16Q41,18F26Q71,18F46Q71,18F56Q71",
+ PIC18,8.5,1,Read18FKx,{0x10000,1,0x10},0,Write18FKx,{0x10000,0x200,0x10,0,0,0},0}, //64K, 256, --, LV
+ {"18F26K80,18F46K80,18F66K80",
+ PIC18,8.5,1,Read18Fx,{0x10000,0x400,0x13},0,Write18Fx,{0x10000,0x400,64,0,0,0x303},0}, //64K, 1K, 64, 9V, xxK80
+ {"18F26Q43,18F46Q43,18F56Q43",
+ PIC18,8.5,1,Read18FKx,{0x10000,1,0x10},0,Write18FKx,{0x10000,0x400,0x10,0,0,0},0}, //64K, 1k, --, LV
+ {"18F26K42,18F46K42,18F56K42,18F26K83",
+ PIC18,8.5,1,Read18FKx,{0x10000,1,0},0,Write18FKx,{0x10000,0x400,0,0,0,0},0}, //64K, 1k, --, LV
+ {"18F26Q83,18F26Q84,18F46Q83,18F46Q84,18F56Q83,18F56Q84",
+ PIC18,8.5,1,Read18FKx,{0x10000,1,0x20},0,Write18FKx,{0x10000,0x400,0x20,0,0,0},0}, //64K, 1k, --, LV
+ {"18F2682,18F4682",
+ PIC18,12,0,Read18Fx,{0x14000,0x400,0},0,Write18Fx,{0x14000,0x400,64,0x3F3F,0x8F8F,0},0},//80K, 1K, 64
+ {"18F66J65,18F86J65,18F96J65,18F66J15,18F66J16,18F66J55,18F86J15,18F86J16,18F86J55",
+ PIC18,-1,1,Read18Fx,{0x18000,0,2},0,Write18Fx,{0x18000,0,64,0x0101,0x8080,0x202},0}, //96K, 0, 64, LV
+ {"18F2685,18F4685",
+ PIC18,12,0,Read18Fx,{0x18000,0x400,0},0,Write18Fx,{0x18000,0x400,64,0x3F3F,0x8F8F,0},0},//96K, 1K, 64
+ {"18F27J13,18F27J53,18F47J13,18F47J53,18F67J10,18F87J10",
+ PIC18,-1,1,Read18Fx,{0x20000,0,2},0,Write18Fx,{0x20000,0,64,0x0101,0x8080,0x102},0}, //128K, 0, 64, LV
+ {"18F67J60,18F87J60,18F97J60,18F67J11,18F67J50,18F67J90,18F67J93,18F87J11,18F87J50,18F87J72,18F87J90,18F87J93",
+ PIC18,-1,1,Read18Fx,{0x20000,0,2},0,Write18Fx,{0x20000,0,64,0x0101,0x8080,0x202},0}, //128K, 0, 64, LV
+ {"18F8722",
+ PIC18,12,0,Read18Fx,{0x20000,0x400,0},0,Write18Fx,{0x20000,0x400,64,0xFFFF,0x8787,0},0},//128K, 1K, 64
+ {"18F27Q43,18F47Q43,18F57Q43",
+ PIC18,8.5,1,Read18FKx,{0x20000,1,0x10},0,Write18FKx,{0x20000,0x400,0x10,0,0,0},0}, //128K, 1k, --, LV
+ {"18F27K42,18F47K42,18F57K42",
+ PIC18,8.5,1,Read18FKx,{0x20000,1,0},0,Write18FKx,{0x20000,0x400,0,0,0,0},0}, //128K, 1k, --, LV
+ {"18F27Q83,18F27Q84,18F47Q83,18F47Q84,18F57Q83,18F57Q84",
+ PIC18,8.5,1,Read18FKx,{0x20000,1,0x20},0,Write18FKx,{0x20000,0x400,0x20,0,0,0},0}, //128K, 1k, --, LV
+//-------------PIC24---------------------------------------------------------
+// options:
+// bit [3:0]
+// 0 = low voltage ICSP entry
+// 1 = High voltage ICSP entry (6V)
+// 2 = High voltage ICSP entry (12V) + PIC30F sequence (additional NOPs)
+// 3 = low voltage ICSP entry (5V power supply)
+// bit [7:4]
+// 0 = config area in the last 2 program words
+// 1 = config area in the last 3 program words
+// 2 = config area in the last 4 program words
+// 3 = 0xF80000 to 0xF80010 except 02 (24F)
+// 4 = 0xF80000 to 0xF80016 (24H-33F)
+// 5 = 0xF80000 to 0xF8000C (x16 bit, 30F)
+// 6 = 0xF80000 to 0xF8000E (30FSMPS)
+// bit [11:8]
+// 0 = code erase word is 0x4064, row write is 0x4004
+// 1 = code erase word is 0x404F, row write is 0x4001
+// 2 = code erase word is 0x407F, row write is 0x4001, 55AA unlock and external timing (2 ms)
+// 3 = code erase word is 0x407F, row write is 0x4001, 55AA unlock and external timing (200 ms)
+// bit [15:12]
+// 0 = eeprom erase word is 0x4050, write word is 0x4004
+// 1 = eeprom erased with bulk erase, write word is 0x4004
+// 2 = eeprom erased with special sequence, write word is 0x4004
+// bit [19:16]
+// 0 = config write is 0x4000
+// 1 = config write is 0x4003
+// 2 = config write is 0x4004
+// 3 = config write is 0x4008
+ {"24F04KA200,24F04KA201",
+ PIC24,6,1,Read24Fx,{0xB00,0,0x31,0x05BE},0x800,Write24Fx,{0xB00,0,0x20031,0x05BE,32},2.0}, //1.375KW, HV
+ {"24F08KA101,24F08KA102",
+ PIC24,6,1,Read24Fx,{0x1600,0x200,0x31,0x05BE},0x800,Write24Fx,{0x1600,0x200,0x20031,0x05BE,32},2.0}, //2.75KW, HV, 512
+ {"24F16KA101,24F16KA102",
+ PIC24,6,1,Read24Fx,{0x2C00,0x200,0x31,0x05BE},0x800,Write24Fx,{0x2C00,0x200,0x20031,0x05BE,32},2.0}, //5.5KW, HV, 512
+ {"24FJ16GA002,24FJ16GA004",
+ PIC24,-1,1,Read24Fx,{0x2C00,0,0,0x05BE},0x800,Write24Fx,{0x2C00,0,0x10100,0x05BE,64},2.0}, //5.5KW
+ {"24FJ32GA002,24FJ32GA004",
+ PIC24,-1,1,Read24Fx,{0x5800,0,0,0x05BE},0x800,Write24Fx,{0x5800,0,0x10100,0x05BE,64},2.0}, //11KW
+ {"24FJ32GA102,24FJ32GA104,24FJ32GB002,24FJ32GB004",
+ PIC24,-1,1,Read24Fx,{0x5800,0,0x20,0x07F0},0x800,Write24Fx,{0x5800,0,0x10120,0x07F0,64},2.0}, //11KW 4 Config Word
+ {"24FJ48GA002,24FJ48GA004",
+ PIC24,-1,1,Read24Fx,{0x8400,0,0,0x05BE},0x800,Write24Fx,{0x8400,0,0x10100,0x05BE,64},2.0}, //16.5KW
+ {"24FJ64GA002,24FJ64GA004,24FJ64GA006,24FJ64GA008,24FJ64GA010",
+ PIC24,-1,1,Read24Fx,{0xAC00,0,0,0x05BE},0x800,Write24Fx,{0xAC00,0,0x10100,0x05BE,64},2.0}, //22KW
+ {"24FJ64GA102,24FJ64GA104,24FJ64GB002,24FJ64GB004",
+ PIC24,-1,1,Read24Fx,{0xAC00,0,0x20,0x07F0},0x800,Write24Fx,{0xAC00,0,0x10120,0x07F0,64},2.0}, //22KW 4 Config Word
+ {"24FJ64GA306,24FJ64GA308,24FJ64GA310,24FJ64GC006,24FJ64GC008,24FJ64GC010",
+ PIC24,-1,1,Read24Fx,{0xAC00,0,0x120,0x07F0},0x800,Write24Fx,{0xAC00,0,0x110120,0x07F0,64},2.0}, //22KW 4 Config Word new TABLPAG
+ {"24FJ64GB106,24FJ64GB108,24FJ64GB110",
+ PIC24,-1,1,Read24Fx,{0xAC00,0,0x10,0x07F0},0x800,Write24Fx,{0xAC00,0,0x10110,0x07F0,64},2.0}, //22KW 3 Config Word
+ {"24FJ96GA006,24FJ96GA008,24FJ96GA010",
+ PIC24,-1,1,Read24Fx,{0x10000,0,0,0x05BE},0x800,Write24Fx,{0x10000,0,0x10100,0x05BE,64},2.0}, //32KW
+ {"24FJ128GA006,24FJ128GA008,24FJ128GA010",
+ PIC24,-1,1,Read24Fx,{0x15800,0,0,0x05BE},0x800,Write24Fx,{0x15800,0,0x10100,0x05BE,64},2.0}, //44KW
+ {"24FJ128GA106,24FJ128GA108,24FJ128GA110,24FJ128GB106,24FJ128GB108,24FJ128GB110",
+ PIC24,-1,1,Read24Fx,{0x15800,0,0x10,0x07F0},0x800,Write24Fx,{0x15800,0,0x10110,0x07F0,64},2.0}, //44KW 3 Config Word
+ {"24FJ128GA306,24FJ128GA308,24FJ128GA310,24FJ128GB206,24FJ128GB210,24FJ128GC006,24FJ128GC008,\
+24FJ128GC010,24FJ128DA106,24FJ128DA110,24FJ128DA206,24FJ128DA210",
+ PIC24,-1,1,Read24Fx,{0x15800,0,0x120,0x07F0},0x800,Write24Fx,{0x15800,0,0x110120,0x07F0,64},2.0}, //44KW 4 Config Word new TABLPAG
+ {"24FJ192GA106,24FJ192GA108,24FJ192GA110,24FJ192GB106,24FJ192GB108,24FJ192GB110",
+ PIC24,-1,1,Read24Fx,{0x20C00,0,0x10,0x07F0},0x800,Write24Fx,{0x20C00,0,0x10110,0x07F0,64},2.0}, //68KW 3 Config Word
+ {"24FJ256GA106,24FJ256GA108,24FJ256GA110,24FJ256GB106,24FJ256GB108,24FJ256GB110",
+ PIC24,-1,1,Read24Fx,{0x2AC00,0,0x10,0x07F0},0x800,Write24Fx,{0x2AC00,0,0x10110,0x07F0,64},2.0}, //88KW 3 Config Word
+ {"24FJ256DA106,24FJ256DA110,24FJ256DA206,24FJ256DA210,24FJ256GB206,24FJ256GB210",
+ PIC24,-1,1,Read24Fx,{0x2AC00,0,0x120,0x07F0},0x800,Write24Fx,{0x2AC00,0,0x110120,0x07F0,64},2.0}, //88KW 4 Config Word new TABLPAG
+ {"33FJ06GS101,33FJ06GS102,33FJ06GS202",
+ PIC24,-1,1,Read24Fx,{0x1000,0,0x40,0x07F0},0x800,Write24Fx,{0x1000,0,0x00140,0x07F0,64},2.0}, //2KW
+ {"24HJ12GP201,24HJ12GP202,33FJ12GP201,33FJ12GP202,33FJ12MC201,33FJ12MC202",
+ PIC24,-1,1,Read24Fx,{0x2000,0,0x40,0x07F0},0x800,Write24Fx,{0x2000,0,0x00140,0x07F0,64},2.0}, //4KW
+ {"24HJ16GP304,33FJ16GP304,33FJ16GS402,33FJ16GS404,33FJ16GS502,33FJ16GS504,33FJ16MC304",
+ PIC24,-1,1,Read24Fx,{0x2C00,0,0x40,0x07F0},0x800,Write24Fx,{0x2C00,0,0x00140,0x07F0,64},2.0}, //5.5KW
+ {"24HJ32GP202,24HJ32GP204,24HJ32GP302,24HJ32GP304,33FJ32GP202,33FJ32GP204,33FJ32GP302,\
+33FJ32GP304,33FJ32GS406,33FJ32GS606,33FJ32GS608,33FJ32GS610,33FJ32MC202,33FJ32MC204,33FJ32MC302,33FJ32MC304",
+ PIC24,-1,1,Read24Fx,{0x5800,0,0x40,0x07F0},0x1000,Write24Fx,{0x5800,0,0x00140,0x07F0,64},2.0}, //11KW
+ {"24HJ64GP202,24HJ64GP204,24HJ64GP206,24HJ64GP210,24HJ64GP502,24HJ64GP504,24HJ64GP506,24HJ64GP510,\
+33FJ64GP202,33FJ64GP204,33FJ64GP206,33FJ64GP306,33FJ64GP310,33FJ64GP706,33FJ64GP708,33FJ64GP710,33FJ64GP802,\
+33FJ64GP804,33FJ64GS406,33FJ64GS606,33FJ64GS608,33FJ64GS610,33FJ64MC202,33FJ64MC204,33FJ64MC506,33FJ64MC508,33FJ64MC510,\
+33FJ64MC706,33FJ64MC710,33FJ64MC802,33FJ64MC804",
+ PIC24,-1,1,Read24Fx,{0xAC00,0,0x40,0x07F0},0x1000,Write24Fx,{0xAC00,0,0x00140,0x07F0,64},2.0}, //22KW
+ {"24HJ128GP202,24HJ128GP204,24HJ128GP206,24HJ128GP210,24HJ128GP306,24HJ128GP310,24HJ128GP502,\
+24HJ128GP504,24HJ128GP506,24HJ128GP510,\
+33FJ128GP202,33FJ128GP204,33FJ128GP206,33FJ128GP306,33FJ128GP310,33FJ128GP706,33FJ128GP708,33FJ128GP710,\
+33FJ128GP802,33FJ128GP804,33FJ128MC202,33FJ128MC204,33FJ128MC506,33FJ128MC510,33FJ128MC706,33FJ128MC708,\
+33FJ128MC710,33FJ128MC802,33FJ128MC804",
+ PIC24,-1,1,Read24Fx,{0x15800,0,0x40,0x07F0},0x1000,Write24Fx,{0x15800,0,0x00140,0x07F0,64},2.0}, //44KW
+ {"24HJ256GP206,24HJ256GP210,24HJ256GP610,\
+33FJ256GP506,33FJ256GP510,33FJ256GP710,33FJ256MC510,33FJ256MC710",
+ PIC24,-1,1,Read24Fx,{0x2AC00,0,0x40,0x07F0},0x1000,Write24Fx,{0x2AC00,0,0x00140,0x07F0,64},2.0}, //88KW
+ {"24EP32GP202,24EP32GP203,24EP32GP204,33EP32GP502,33EP32GP503,33EP32GP504,\
+24EP32MC202,24EP32MC203,24EP32MC204,33EP32MC202,33EP32MC203,33EP32MC204,33EP32MC502,33EP32MC503,33EP32MC504",
+ PIC24,-1,1,Read24Ex,{0x5800,0,0,0x0FF0},0x1000,Write24Ex,{0x5800,0,0,0,0,0},2.0}, //11KW 10 Config Word
+ {"24EP64GP202,24EP64GP203,24EP64GP204,24EP64GP206,33EP64GP502,33EP64GP503,33EP64GP504,33EP64GP506,\
+24EP64MC202,24EP64MC203,24EP64MC204,24EP64MC206,33EP64MC202,33EP64MC203,33EP64MC204,33EP64MC206,\
+33EP64MC502,33EP64MC503,33EP64MC504,33EP64MC506",
+ PIC24,-1,1,Read24Ex,{0xB000,0,0,0x0FF0},0x1000,Write24Ex,{0xB000,0,0,0,0,0},2.0}, //22.5KW 10 Config Word
+ {"24EP128GP202,24EP128GP204,24EP128GP206,33EP128GP502,33EP128GP504,33EP128GP506,\
+24EP128MC202,24EP128MC204,24EP128MC206,33EP128MC202,33EP128MC204,33EP128MC206,\
+33EP128MC502,33EP128MC504,33EP128MC506",
+ PIC24,-1,1,Read24Ex,{0x15800,0,0,0x0FF0},0x1000,Write24Ex,{0x15800,0,0,0,0,0},2.0}, //44KW 10 Config Word
+ {"24EP256GP202,24EP256GP204,24EP256GP206,33EP256GP502,33EP256GP504,33EP256GP506,\
+24EP256MC202,24EP256MC204,24EP256MC206,33EP256MC202,33EP256MC204,33EP256MC206,\
+33EP256MC502,33EP256MC504,33EP256MC506",
+ PIC24,-1,1,Read24Ex,{0x2B000,0,0,0x0FF0},0x1000,Write24Ex,{0x2B000,0,0,0,0,0},2.0}, //88KW 10 Config Word
+ {"24EP512GP202,24EP512GP204,24EP512GP206,33EP512GP502,33EP512GP504,33EP512GP506,\
+24EP512MC202,24EP512MC204,24EP512MC206,33EP512MC202,33EP512MC204,33EP512MC206,\
+33EP512MC502,33EP512MC504,33EP512MC506",
+ PIC24,-1,1,Read24Ex,{0x56000,0,0,0x0FF0},0x1000,Write24Ex,{0x56000,0,0,0,0,0},2.0}, //175KW 10 Config Word
+ {"30F1010",
+ PIC24,-1,0,Read24Fx,{0x1000,0,0x63,0x05BE},0x600,Write24Fx,{0x1000,0,0x30263,0x05BE,32},2.0}, //1KW, LV5V
+ {"30F2020,30F2023",
+ PIC24,-1,0,Read24Fx,{0x2000,0,0x63,0x05BE},0x600,Write24Fx,{0x2000,0,0x30263,0x05BE,32},2.0}, //2KW, LV5V
+ {"30F2010",
+ PIC24,12,0,Read24Fx,{0x2000,0x400,0x52,0x05BE},0x600,Write24Fx,{0x2000,0x400,0x31252,0x05BE,32},2.0}, //4KW, 1K, HV12
+ {"30F2011,30F2012",
+ PIC24,12,0,Read24Fx,{0x2000,0,0x52,0x05BE},0x600,Write24Fx,{0x2000,0,0x31252,0x05BE,32},2.0}, //4KW, HV12
+ {"30F3010,30F3011,30F3012,30F3013,30F3014",
+ PIC24,12,0,Read24Fx,{0x4000,0x400,0x52,0x05BE},0x600,Write24Fx,{0x4000,0x400,0x31252,0x05BE,32},2.0}, //8KW, 1K, HV12
+ {"30F4011,30F4012,30F4013",
+ PIC24,12,0,Read24Fx,{0x8000,0x400,0x52,0x05BE},0x600,Write24Fx,{0x8000,0x400,0x31252,0x05BE,32},2.0}, //16KW, 1K, HV12
+ {"30F5011,30F5013,30F5015,30F5016",
+ PIC24,12,0,Read24Fx,{0xB000,0x400,0x52,0x05BE},0x600,Write24Fx,{0xB000,0x400,0x31252,0x05BE,32},2.0}, //22KW, 1K, HV12
+ {"30F6011,30F6013",
+ PIC24,12,0,Read24Fx,{0x16000,0x800,0x52,0x05BE},0x600,Write24Fx,{0x16000,0x800,0x31252,0x05BE,32},2.0}, //44KW, 2K, HV12
+ {"30F6010,30F6012,30F6014,30F6015",
+ PIC24,12,0,Read24Fx,{0x18000,0x1000,0x52,0x05BE},0x600,Write24Fx,{0x18000,0x1000,0x31252,0x05BE,32},2.0}, //49KW, 4K, HV12
+//-------------PIC32---------------------------------------------------------
+// options:
+// {"32MX270F256",
+// PIC32,-1,1,Read32x,{0x40000,0},0x800,0,{0,0,0,0,0},0.0}, //256K
+//-------------ATMEL---------------------------------------------------------
+ {"AT90S1200",
+ AVR,-1,0,ReadAT,{0x400,0x40,0},0,WriteAT,{0x400,0x40,0,0},0}, //1K, 64
+ {"ATtiny11",
+ AVR,12,0,ReadAT_HV,{0x400,0,LOCK+FUSE+CAL},0,WriteAT_HV,{0x400,0,0,0},0}, //1K, HV
+ {"ATtiny12",
+ AVR,12,0,ReadAT_HV,{0x400,0x40,LOCK+FUSE+CAL},0,WriteAT_HV,{0x400,0x40,0,0},0}, //1K, 64, HV
+ {"ATtiny13",
+ AVR,12,0,ReadAT_HV,{0x400,0x40,LOCK+FUSE+FUSE_H+CAL},0,WriteAT_HV,{0x400,0x40,16,0},0}, //1K, 64, HV
+ {"AT90S2313",
+ AVR,-1,0,ReadAT,{0x800,0x80,0},0,WriteAT,{0x800,0x80,0,0},0}, //2K, 128
+ {"ATtiny2313",
+ AVR,-1,0,ReadAT,{0x800,0x80,LOCK+FUSE+FUSE_H+FUSE_X+CAL},0,WriteATmega,{0x800,0x80,16,0},0},//2K, 128
+ {"ATtiny24,ATtiny25",
+ AVR,12,0,ReadAT_HV,{0x800,0x80,LOCK+FUSE+FUSE_H+FUSE_X+CAL},0,WriteAT_HV,{0x800,0x80,16,0},0}, //2K, 128, HV
+ {"ATtiny26",
+ AVR,-1,0,ReadAT,{0x800,0x80,LOCK+FUSE+FUSE_H+CAL},0,WriteATmega,{0x800,0x80,16,0},0}, //2K, 128
+ {"ATtiny261",
+ AVR,-1,0,ReadAT,{0x800,0x80,LOCK+FUSE+FUSE_H+FUSE_X+CAL},0,WriteATmega,{0x800,0x80,16,0},0}, //2K, 128
+ {"ATtiny44,ATtiny45",
+ AVR,12,0,ReadAT_HV,{0x1000,0x100,LOCK+FUSE+FUSE_H+FUSE_X+CAL},0,WriteAT_HV,{0x1000,0x100,32,0},0}, //4K, 256, HV
+ {"ATtiny461,ATtiny4313,ATmega48",
+ AVR,-1,0,ReadAT,{0x1000,0x100,LOCK+FUSE+FUSE_H+FUSE_X+CAL},0,WriteATmega,{0x1000,0x100,32,0},0}, //4K, 256
+ {"ATtiny48",
+ AVR,-1,0,ReadAT,{0x1000,0x40,LOCK+FUSE+FUSE_H+FUSE_X+CAL},0,WriteATmega,{0x1000,0x40,32,0},0}, //4K, 64
+ {"ATtiny88",
+ AVR,-1,0,ReadAT,{0x2000,0x40,LOCK+FUSE+FUSE_H+FUSE_X+CAL},0,WriteATmega,{0x2000,0x40,32,0},0}, //8K, 64
+ {"AT90S8515,AT90S8535",
+ AVR,-1,0,ReadAT,{0x2000,0x100,0},0,WriteAT,{0x2000,0x100,0,0},0}, //8K, 256
+ {"ATmega8,ATmega8515,ATmega8535",
+ AVR,-1,0,ReadAT,{0x2000,0x200,LOCK+FUSE+FUSE_H+CAL},0,WriteATmega,{0x2000,0x200,32,0},0}, //8K, 512
+ {"ATmega88,ATtiny861",
+ AVR,-1,0,ReadAT,{0x2000,0x200,LOCK+FUSE+FUSE_H+FUSE_X+CAL},0,WriteATmega,{0x2000,0x200,32,0},0}, //8K, 512
+ {"ATtiny84,ATtiny85",
+ AVR,12,0,ReadAT_HV,{0x2000,0x200,LOCK+FUSE+FUSE_H+FUSE_X+CAL},0,WriteAT_HV,{0x2000,0x200,32,0},0}, //8K, 512, HV
+ {"ATmega16",
+ AVR,-1,0,ReadAT,{0x4000,0x200,LOCK+FUSE+FUSE_H+CAL},0,WriteATmega,{0x4000,0x200,64,0},0}, //16K, 512
+ {"ATmega164,ATmega168",
+ AVR,-1,0,ReadAT,{0x4000,0x200,LOCK+FUSE+FUSE_H+FUSE_X+CAL},0,WriteATmega,{0x4000,0x200,64,0},0}, //16K, 512
+ {"ATmega32",
+ AVR,-1,0,ReadAT,{0x8000,0x400,LOCK+FUSE+FUSE_H+CAL},0,WriteATmega,{0x8000,0x400,64,0},0}, //32K, 1K
+ {"ATmega324,ATmega328",
+ AVR,-1,0,ReadAT,{0x8000,0x400,LOCK+FUSE+FUSE_H+FUSE_X+CAL},0,WriteATmega,{0x8000,0x400,64,0},0}, //32K, 1K
+ {"ATmega64,ATmega644",
+ AVR,-1,0,ReadAT,{0x10000,0x800,LOCK+FUSE+FUSE_H+FUSE_X+CAL},0,WriteATmega,{0x10000,0x800,128,0},0}, //64K, 2K
+ {"ATmega1284",
+ AVR,-1,0,ReadAT,{0x20000,0x1000,LOCK+FUSE+FUSE_H+FUSE_X+CAL},0,WriteATmega,{0x20000,0x1000,128,0},0},//128K, 4K
+//-------------I2C---------------------------------------------------------
+ {"2400",
+ I2CEE,-1,0,ReadI2C,{0x10,0},0,WriteI2C,{0x10,0,1},0}, //16, 1B addr.
+ {"2401",
+ I2CEE,-1,0,ReadI2C,{0x80,0},0,WriteI2C,{0x80,0,8},0}, //128, 1B addr.
+ {"2402",
+ I2CEE,-1,0,ReadI2C,{0x100,0},0,WriteI2C,{0x100,0,8},0}, //256, 1B addr.
+ {"2404",
+ I2CEE,-1,0,ReadI2C,{0x200,0},0,WriteI2C,{0x200,0,16},0}, //512, 1B addr.
+ {"2408",
+ I2CEE,-1,0,ReadI2C,{0x400,0},0,WriteI2C,{0x400,0,16},0}, //1K, 1B addr.
+ {"2416",
+ I2CEE,-1,0,ReadI2C,{0x800,0},0,WriteI2C,{0x800,0,16},0}, //2K, 1B addr.
+ {"2432",
+ I2CEE,-1,0,ReadI2C,{0x1000,1},0,WriteI2C,{0x1000,1,32},0}, //4K, 2B addr.
+ {"2464",
+ I2CEE,-1,0,ReadI2C,{0x2000,1},0,WriteI2C,{0x2000,1,32},0}, //8K, 2B addr.
+ {"24128",
+ I2CEE,-1,0,ReadI2C,{0x4000,1},0,WriteI2C,{0x4000,1,64},0}, //16K, 2B addr.
+ {"24256",
+ I2CEE,-1,0,ReadI2C,{0x8000,1},0,WriteI2C,{0x8000,1,64},0}, //32K, 2B addr.
+ {"24512",
+ I2CEE,-1,0,ReadI2C,{0x10000,1},0,WriteI2C,{0x10000,1,128},0}, //64K, 2B addr.
+ {"241024",
+ I2CEE,-1,0,ReadI2C,{0x20000,0x201},0,WriteI2C,{0x20000,0x201,256},0}, //128K, 2B addr.
+ {"241025",
+ I2CEE,-1,0,ReadI2C,{0x20000,0x841},0,WriteI2C,{0x20000,0x841,128},0}, //128K, 2B addr.
+//-------------Microwire EEPROM---------------------------------------------------------
+ {"93S46",
+ UWEE,-1,0,Read93x,{0x80,6,0},0,Write93Sx,{0x80,6,8},0}, //128, 6b addr, 4W page
+ {"93x46",
+ UWEE,-1,0,Read93x,{0x80,6,0},0,Write93Cx,{0x80,6,0},0}, //128, 6b addr
+ {"93x46A",
+ UWEE,-1,0,Read93x,{0x80,7,1},0,Write93Cx,{0x80,7,1},0}, //128, 6b addr x8
+ {"93S56",
+ UWEE,-1,0,Read93x,{0x100,8,0},0,Write93Sx,{0x100,8,8},0}, //256, 8b addr, 4W page
+ {"93x56",
+ UWEE,-1,0,Read93x,{0x100,8,0},0,Write93Cx,{0x100,8,0},0}, //256, 8b addr
+ {"93x56A",
+ UWEE,-1,0,Read93x,{0x100,9,1},0,Write93Cx,{0x100,9,1},0}, //256, 8b addr x8
+ {"93S66",
+ UWEE,-1,0,Read93x,{0x200,8,0},0,Write93Sx,{0x200,8,8},0}, //512, 8b addr, 4W page
+ {"93x66",
+ UWEE,-1,0,Read93x,{0x200,8,0},0,Write93Cx,{0x200,8,0},0}, //512, 8b addr
+ {"93x66A",
+ UWEE,-1,0,Read93x,{0x200,9,1},0,Write93Cx,{0x200,9,1},0}, //512, 8b addr x8
+ {"93x76",
+ UWEE,-1,0,Read93x,{0x400,10,0},0,Write93Cx,{0x400,10,0},0}, //1k, 10b addr
+ {"93x76A",
+ UWEE,-1,0,Read93x,{0x400,11,1},0,Write93Cx,{0x400,11,1},0}, //1k, 10b addr x8
+ {"93x86",
+ UWEE,-1,0,Read93x,{0x800,10,0},0,Write93Cx,{0x800,10,0},0}, //2k, 10b addr
+ {"93x86A",
+ UWEE,-1,0,Read93x,{0x800,11,1},0,Write93Cx,{0x800,11,1},0}, //2k, 10b addr x8
+//-------------SPI---------------------------------------------------------
+ {"25010,95010",
+ SPIEE,-1,0,Read25xx,{0x80},0,Write25xx,{0x80,16},0}, //128
+ {"25020,95020",
+ SPIEE,-1,0,Read25xx,{0x100},0,Write25xx,{0x100,16},0}, //256
+ {"25040,95040",
+ SPIEE,-1,0,Read25xx,{0x200},0,Write25xx,{0x200,16},0}, //512
+ {"25080,95080",
+ SPIEE,-1,0,Read25xx,{0x400},0,Write25xx,{0x400,16},0}, //1K
+ {"25160,95160",
+ SPIEE,-1,0,Read25xx,{0x800},0,Write25xx,{0x800,16},0}, //2K
+ {"25320,95320",
+ SPIEE,-1,0,Read25xx,{0x1000},0,Write25xx,{0x1000,32},0}, //4K
+ {"25640,95640",
+ SPIEE,-1,0,Read25xx,{0x2000},0,Write25xx,{0x2000,32},0}, //8K
+ {"25128,95128",
+ SPIEE,-1,0,Read25xx,{0x4000},0,Write25xx,{0x4000,64},0}, //16K
+ {"25256,95256",
+ SPIEE,-1,0,Read25xx,{0x8000},0,Write25xx,{0x8000,64},0}, //32K
+ {"25512,95512",
+ SPIEE,-1,0,Read25xx,{0x10000},0,Write25xx,{0x10000,128},0}, //64K
+ {"251024,95M01",
+ SPIEE,-1,0,Read25xx,{0x20000},0,Write25xx,{0x20000,256},0}, //128K
+ {"95M02",
+ SPIEE,-1,0,Read25xx,{0x40000},0,Write25xx,{0x40000,256},0}, //256K
+ {"25X05",
+ SPIEE,-1,0,Read25xx,{0x10000},0,Write25xx,{0x10000,0x1000+256},0}, //64K flash 3.3V
+ {"251005,25X10",
+ SPIEE,-1,0,Read25xx,{0x20000},0,Write25xx,{0x20000,0x1000+256},0}, //128K flash 3.3V
+ {"252005,25X20",
+ SPIEE,-1,0,Read25xx,{0x40000},0,Write25xx,{0x40000,0x1000+256},0}, //256K flash 3.3V
+ {"254005,25X40",
+ SPIEE,-1,0,Read25xx,{0x80000},0,Write25xx,{0x80000,0x1000+256},0}, //512K flash 3.3V
+ {"25Q40",
+ SPIEE,-1,0,Read25xx,{0x80000},0,Write25xx,{0x80000,0x3000+256},0}, //512K flash 3.3V STATUS2
+ {"258005,25X80",
+ SPIEE,-1,0,Read25xx,{0x100000},0,Write25xx,{0x100000,0x1000+256},0},//1M flash 3.3V
+ {"251605,25X16",
+ SPIEE,-1,0,Read25xx,{0x200000},0,Write25xx,{0x200000,0x1000+256},0},//2M flash 3.3V
+ {"25X32",
+ SPIEE,-1,0,Read25xx,{0x400000},0,Write25xx,{0x400000,0x1000+256},0},//4M flash 3.3V
+ {"25X64",
+ SPIEE,-1,0,Read25xx,{0x800000},0,Write25xx,{0x800000,0x1000+256},0},//8M flash 3.3V
+ {"25X128",
+ SPIEE,-1,0,Read25xx,{0x1000000},0,Write25xx,{0x1000000,0x1000+256},0},//16M flash 3.3V
+//-------------One wire devices---------------------------------------------------------
+ {"DS2430",
+ OWEE,-1,0,ReadOneWireMem,{0x20,1},0,WriteOneWireMem,{0x20,1},0}, //32
+ {"DS2431",
+ OWEE,-1,0,ReadOneWireMem,{0x80,2},0,WriteOneWireMem,{0x80,0},0}, //128
+ {"DS2433",
+ OWEE,-1,0,ReadOneWireMem,{0x200,0},0,WriteOneWireMem,{0x200,1},0}, //512
+ {"DS28EC20",
+ OWEE,-1,0,ReadOneWireMem,{0xA00,2},0,WriteOneWireMem,{0xA00,1},0}, //2560
+ {"DS1820",
+ OWEE,-1,0,ReadDS1820,{-10},0,0,{0},0}, //digital thermometer
+//-------------UNIO devices---------------------------------------------------------
+ {"11010",
+ UNIOEE,-1,0,Read11xx,{0x80},0,Write11xx,{0x80,16},0}, //128
+ {"11020",
+ UNIOEE,-1,0,Read11xx,{0x100},0,Write11xx,{0x100,16},0}, //256
+ {"11040",
+ UNIOEE,-1,0,Read11xx,{0x200},0,Write11xx,{0x200,16},0}, //512
+ {"11080",
+ UNIOEE,-1,0,Read11xx,{0x400},0,Write11xx,{0x400,16},0}, //1k
+ {"11160",
+ UNIOEE,-1,0,Read11xx,{0x800},0,Write11xx,{0x800,16},0} //2k
+};
+
+int NDEVLIST = (sizeof(DEVLIST)/sizeof(struct DEVICES));
+
+//Add all devices to the appropriate structure
+#ifndef _GTKGUI
+void AddDevices(char *list){ //make sure list is long enough
+ int i;
+ static char last[8]="";
+ for(i=0;i<sizeof(devices)/sizeof(char*);i++){
+ if(last[0]) strcat(list,", ");
+ if(strncmp(devices[i],last,2)){
+ strcat(list,"\n");
+ last[0]=devices[i][0];
+ last[1]=devices[i][1];
+ last[2]=0;
+ }
+ strcat(list,devices[i]);
+ }
+}
+#endif
+
+//Make a list of all supported devices (insert \n between types)
+char* ListDevices(){
+ int i,len=0,l;
+ static char last[8]="";
+ char* list=0;
+ for(i=0;i<Ndevices;i++){
+ l=strlen(devices[i]);
+ if(!last[0]){
+ list=realloc(list,len+l+1);
+ strcpy(list+len,devices[i]);
+ len+=l;
+ }
+ else{
+ list=realloc(list,len+l+3);
+ if(strncmp(devices[i],last,2)) strcpy(list+len,",\n");
+ else strcpy(list+len,", ");
+ strcpy(list+len+2,devices[i]);
+ len+=l+2;
+ }
+ last[0]=devices[i][0];
+ last[1]=devices[i][1];
+ last[2]=0;
+ }
+ return list;
+}
+
+#ifdef DEBUG
+//Check that all devices in the list have a read/write function
+void CheckDevices(){
+ int i;
+ for(i=0;i<Ndevices;i++){
+ if(GetDevType(devices[i])<0){
+ printf("Can't find %s\n",devices[i]);fflush(stdout);
+ }
+ }
+ printf("OK %d devices\n",Ndevices);fflush(stdout);
+}
+#endif
+
+
+void Read(char* dev,int ee,int r)
+{
+ int i,j;
+ int params[5];
+ char *str=0,*tok;
+#ifdef DEBUG
+ CheckDevices();
+#endif
+ //parse all device names until "dev" is found,
+ //then execute the read function with the right number of parameters
+ for(i=0;i<sizeof(DEVLIST)/sizeof(DEVLIST[0]);i++){
+ if(str) free(str);
+ str=malloc(strlen(DEVLIST[i].device)+1);
+ strcpy(str,DEVLIST[i].device);
+ for(tok=strtok(str,",");tok;tok=strtok(NULL,",")){ //compare every device name
+ if(!strcmp(dev,tok)){ //proceed if found
+ for(j=0;j<4;j++) params[j]=DEVLIST[i].ReadParam[j];
+ if(DEVLIST[i].V33>0){ //3.3V required
+ if(!CheckV33Regulator()){
+ PrintMessage(strings[S_noV33reg]); //Can't find 3.3V expansion board
+ return;
+ }
+ }
+ if(hvreg!=DEVLIST[i].HV) hvreg=StartHVReg(DEVLIST[i].HV)>0?DEVLIST[i].HV:0;
+ if(DEVLIST[i].ReadPtr==0){
+ PrintMessage(strings[S_nodev_r]); //"Device not supported for reading\r\n");
+ return;
+ }
+ switch(DEVLIST[i].family){ //call read function with the right number of arguments (better ways to do it???)
+ case PIC12:
+ if(r) params[1]=DEVLIST[i].ResArea; //modify reserved area parameter
+ (*DEVLIST[i].ReadPtr)(params[0],params[1]);
+ break;
+ case PIC16:
+ if(r) params[2]=DEVLIST[i].ResArea; //modify reserved area parameter
+ if(!ee) params[1]=0; //clear eeprom parameter
+ (*DEVLIST[i].ReadPtr)(params[0],params[1],params[2],params[3]);
+ break;
+ case PIC18:
+ if(!ee) params[1]=0; //clear eeprom parameter
+ (*DEVLIST[i].ReadPtr)(params[0],params[1],params[2]);
+ break;
+ case PIC24:
+ if(!ee) params[1]=0; //clear eeprom parameter
+ (*DEVLIST[i].ReadPtr)(params[0],params[1],params[2],params[3],r?DEVLIST[i].ResArea:0);
+ break;
+ case PIC32:
+// if(!ee) params[1]=0; //clear eeprom parameter
+ (*DEVLIST[i].ReadPtr)(params[0],params[1]);
+ break;
+ case AVR:
+ if(!ee) params[1]=0; //clear eeprom parameter
+ (*DEVLIST[i].ReadPtr)(params[0],params[1],params[2]);
+ break;
+ case I2CEE:
+ (*DEVLIST[i].ReadPtr)(params[0],params[1]);
+ break;
+ case UWEE:
+ (*DEVLIST[i].ReadPtr)(params[0],params[1],params[2]);
+ break;
+ case SPIEE:
+ (*DEVLIST[i].ReadPtr)(params[0]);
+ break;
+ case OWEE:
+ if(params[0]==-10) (*DEVLIST[i].ReadPtr)();
+ else (*DEVLIST[i].ReadPtr)(params[0],params[1]);
+ break;
+ case UNIOEE:
+ (*DEVLIST[i].ReadPtr)(params[0]);
+ break;
+ default:
+ PrintMessage(strings[S_nodev_r]); //"Device not supported for reading\r\n");
+ }
+ return;
+ }
+ }
+ }
+ PrintMessage(strings[S_nodev_r]); //"Device not supported for reading\r\n");
+}
+
+
+void Write(char* dev,int ee)
+{
+ int i,j;
+ int params[6];
+ char *str=0,*tok;
+ //parse all device names until "dev" is found,
+ //then execute the write function with the right number of parameters
+ for(i=0;i<sizeof(DEVLIST)/sizeof(DEVLIST[0]);i++){
+ if(str) free(str);
+ str=malloc(strlen(DEVLIST[i].device)+1);
+ strcpy(str,DEVLIST[i].device);
+ for(tok=strtok(str,",");tok;tok=strtok(NULL,",")){ //compare every device name
+ if(!strcmp(dev,tok)){ //proceed if found
+ for(j=0;j<6;j++) params[j]=DEVLIST[i].WriteParam[j];
+ if(DEVLIST[i].V33>0){ //3.3V required
+ if(!CheckV33Regulator()){
+ PrintMessage(strings[S_noV33reg]); //Can't find 3.3V expansion board
+ return;
+ }
+ }
+ if(hvreg!=DEVLIST[i].HV) hvreg=StartHVReg(DEVLIST[i].HV)>0?DEVLIST[i].HV:0;
+ if(DEVLIST[i].WritePtr==0){
+ PrintMessage(strings[S_nodev_w]); //"Device not supported for writing\r\n");
+ return;
+ }
+ switch(DEVLIST[i].family){ //call write function with the right number of arguments (better ways to do it???)
+ case PIC12:
+ (*DEVLIST[i].WritePtr)(params[0],params[1]);
+ break;
+ case PIC16:
+ if(!ee) params[1]=0; //clear eeprom parameter
+ if(params[2]==-10) (*DEVLIST[i].WritePtr)(params[0],params[1]);
+ else (*DEVLIST[i].WritePtr)(params[0],params[1],params[2]);
+ break;
+ case PIC18:
+ if(!ee) params[1]=0; //clear eeprom parameter
+ (*DEVLIST[i].WritePtr)(params[0],params[1],params[2],params[3],params[4],params[5]);
+ break;
+ case PIC24:
+ if(!ee) params[1]=0; //clear eeprom parameter
+ (*DEVLIST[i].WritePtr)(params[0],params[1],params[2],params[3],params[4],DEVLIST[i].WriteParamD);
+ break;
+ case AVR:
+ if(!ee) params[1]=0; //clear eeprom parameter
+ (*DEVLIST[i].WritePtr)(params[0],params[1],params[2],params[3]);
+ break;
+ case I2CEE:
+ (*DEVLIST[i].WritePtr)(params[0],params[1],params[2]);
+ break;
+ case UWEE:
+ (*DEVLIST[i].WritePtr)(params[0],params[1],params[2]);
+ break;
+ case SPIEE:
+ (*DEVLIST[i].WritePtr)(params[0],params[1]);
+ break;
+ case OWEE:
+ (*DEVLIST[i].WritePtr)(params[0],params[1]);
+ break;
+ case UNIOEE:
+ (*DEVLIST[i].WritePtr)(params[0],params[1]);
+ break;
+ default:
+ PrintMessage(strings[S_nodev_w]); //"Device not supported for writing\r\n");
+ }
+ return;
+ }
+ }
+ }
+ PrintMessage(strings[S_nodev_w]); //"Device not supported for writing\r\n");
+}
+
+///Search the device type
+int GetDevType(const char* dev)
+{
+ int i,type=-1;
+ char *str=0,*tok;
+ //parse all device names until "dev" is found
+ for(i=0;i<sizeof(DEVLIST)/sizeof(DEVLIST[0]);i++){
+ if(str) free(str);
+ str=malloc(strlen(DEVLIST[i].device)+1);
+ strcpy(str,DEVLIST[i].device);
+ for(tok=strtok(str,",");tok;tok=strtok(NULL,",")){ //compare every device name
+ if(!strcmp(dev,tok)){ //proceed if found
+ type=DEVLIST[i].family;
+ tok=0;
+ i=sizeof(DEVLIST)/sizeof(DEVLIST[0]);
+ }
+ }
+ }
+ free(str);
+ return type;
+}
+
+/// Determine the group of a specific device
+enum group_t nameToGroup(const char *devName) {
+ if(!strncmp(devName,"10F",3)||!strncmp(devName,"12F",3)||!strncmp(devName,"12C",3))
+ return G_PIC_10_12;
+ if(!strncmp(devName,"16F",3)||!strncmp(devName,"16LF",4)||!strncmp(devName,"16C",3))
+ return G_PIC_16;
+ if(!strncmp(devName,"18F",3))
+ return G_PIC_18;
+ if(!strncmp(devName,"24F",3)||!strncmp(devName,"24H",3)||!strncmp(devName,"24E",3))
+ return G_PIC_24;
+ if(!strncmp(devName,"30F",3)||!strncmp(devName,"33F",3)||!strncmp(devName,"33E",3))
+ return G_PIC_30_33;
+ if(!strncmp(devName,"AT",2))
+ return G_ATMEL;
+ if(!strncmp(devName,"24",2)||!strncmp(devName,"25",2)||!strncmp(devName,"93",2)|| \
+ !strncmp(devName,"95",2)||!strncmp(devName,"11",2)||!strncmp(devName,"DS",2))
+ return G_EEPROM;
+ PrintMessage1("can't determine group of device '%s'\n",devName);
+ return -1;
+}
+
+/// Copies the device info from the passed devlist entry into the passed DevInfo
+/// Does NOT populate fields 'device' and 'group' as these are device-specific
+void populateDevInfo(struct DevInfo *info, const struct DEVICES *devlistEntry) {
+ char str2[256],str3[64],strF[32];
+ info->family=devlistEntry->family;
+ info->HV=devlistEntry->HV;
+ info->V33=devlistEntry->V33;
+ info->size=devlistEntry->ReadParam[0];
+ info->sizeEE=devlistEntry->ReadParam[1];
+ str2[0]=0;
+ double x=info->size/1024.0;
+ if(x-(int)x) sprintf(strF,"%.1f",x);
+ else sprintf(strF,"%d",(int)x);
+ switch(info->family){
+ case -1:
+ sprintf(str2,"?? ");
+ break;
+ case PIC12:
+ sprintf(str2,"PIC12, ");
+ if(info->size<1024) sprintf(str3,"%dW FLASH",info->size);
+ else sprintf(str3,"%sKW FLASH",strF);
+ strcat(str2,str3);
+ break;
+ case PIC16:
+ sprintf(str2,"PIC16, ");
+ if(info->size<1024) sprintf(str3,"%dW FLASH",info->size);
+ else sprintf(str3,"%sKW FLASH",strF);
+ strcat(str2,str3);
+ if(info->sizeEE){
+ int ee=info->sizeEE;
+ if(ee<0) ee=-ee;
+ sprintf(str3," + %dB EEPROM",ee);
+ strcat(str2,str3);
+ }
+ break;
+ case PIC18:
+ sprintf(str2,"PIC18, ");
+ if(info->size<1024) sprintf(str3,"%dB FLASH ",info->size);
+ else sprintf(str3,"%sKB FLASH ",strF);
+ strcat(str2,str3);
+ if(info->sizeEE){
+ sprintf(str3,"+ %dB EEPROM ",info->sizeEE);
+ strcat(str2,str3);
+ }
+ break;
+ case PIC24:
+ sprintf(str2,"PIC24, ");
+ if(info->size<1024) sprintf(str3,"%dW FLASH",info->size);
+ else sprintf(str3,"%sKW FLASH",strF);
+ strcat(str2,str3);
+ if(info->sizeEE){
+ sprintf(str3," + %dB EEPROM",info->sizeEE);
+ strcat(str2,str3);
+ }
+ break;
+ case PIC32:
+ sprintf(str2,"PIC32, ");
+ if(info->size<1024) sprintf(str3,"%dW FLASH",info->size);
+ else sprintf(str3,"%sKW FLASH",strF);
+ strcat(str2,str3);
+ if(info->sizeEE){
+ sprintf(str3," + %dB EEPROM",info->sizeEE);
+ strcat(str2,str3);
+ }
+ break;
+ case AVR:
+ sprintf(str2,"AVR, ");
+ if(info->size<1024) sprintf(str3,"%dB FLASH",info->size);
+ else sprintf(str3,"%sKB FLASH",strF);
+ strcat(str2,str3);
+ if(info->sizeEE){
+ sprintf(str3," + %dB EEPROM",info->sizeEE);
+ strcat(str2,str3);
+ }
+ break;
+ case I2CEE:
+ if(info->size<1024) sprintf(str2,"%s, %dB",strings[I_I2CMEM],info->size); //I2C Memory
+ else sprintf(str2,"%s, %sKB",strings[I_I2CMEM],strF); //I2C Memory
+ break;
+ case SPIEE:
+ if(info->size<1024) sprintf(str2,"%s, %dB",strings[I_SPIMEM],info->size); //SPI Memory
+ else sprintf(str2,"%s, %sKB",strings[I_SPIMEM],strF); //SPI Memory
+ break;
+ case UWEE:
+ if(info->size<1024) sprintf(str2,"%s, %dB",strings[I_UWMEM],info->size); //Microwire Memory
+ else sprintf(str2,"%s,%sKB",strings[I_UWMEM],strF);
+ break;
+ case OWEE:
+ if(info->size<0) sprintf(str2,strings[I_OWDEV]); //OneWire device
+ else if(info->size<1024) sprintf(str2,"%s, %dB",strings[I_OWMEM],info->size); //OneWire Memory
+ else sprintf(str2,"%s, %sKB",strings[I_OWMEM],strF);
+ break;
+ case UNIOEE:
+ if(info->size<1024) sprintf(str2,"%s, %dB",strings[I_UNIOMEM],info->size); //UNI/O Memory
+ else sprintf(str2,"%s, %sKB",strings[I_UNIOMEM],strF);
+ break;
+ }
+ if(info->HV>0){
+ sprintf(str3,", %.1fV",info->HV);
+ strcat(str2,str3);
+ }
+ if(info->V33){
+ strcat(str2,", ");
+ strcat(str2,strings[I_3V3REQUIRED]); // 3.3V adapter
+ }
+ info->features=malloc(strlen(str2)+1);
+ strcpy(info->features,str2);
+}
+
+
+///Search and return device info
+struct DevInfo GetDevInfo(const char* dev)
+{
+ int i;
+ char *str=0,*tok;
+ struct DevInfo info;
+ info.device=0;
+ info.family=-1;
+ info.HV=-1;
+ info.V33=-1;
+ info.size=-1;
+ info.sizeEE=-1;
+ info.features=0;
+ //parse all device names until "dev" is found
+ for(i=0;i<NDEVLIST;i++){
+ str=malloc(strlen(DEVLIST[i].device)+1);
+ strcpy(str,DEVLIST[i].device);
+ for(tok=strtok(str,",");tok;tok=strtok(NULL,",")){ //compare every device name
+ if(!strcmp(dev,tok)){ //proceed if found
+ info.device=malloc(strlen(tok)+1);
+ strcpy(info.device,tok);
+ info.group=nameToGroup(info.device);
+ populateDevInfo(&info, &(DEVLIST[i]));
+ free(str);
+ return info;
+ }
+ }
+ free(str);
+ }
+ return info;
+}
diff --git a/deviceRW.h b/deviceRW.h
new file mode 100644
index 0000000..9efdd7b
--- /dev/null
+++ b/deviceRW.h
@@ -0,0 +1,52 @@
+extern char* devices[];
+extern int Ndevices;
+enum family_t {PIC12=0,PIC16,PIC18,PIC24,PIC32,AVR,I2CEE,SPIEE,UWEE,OWEE,UNIOEE,NUM_FAMILIES};
+enum group_t {G_PIC_10_12=0,G_PIC_16,G_PIC_18,G_PIC_24,G_PIC_30_33,G_ATMEL,G_EEPROM,NUM_GROUPS};
+
+
+// This struct stores information about how to program a set of devices
+struct DEVICES {
+ char *device; //comma-separated list of device names which share the same method of programming
+ enum family_t family; //architecture type
+ double HV; //High voltage value (-1= turn off HV)
+ int V33; //3.3V regulator required (0=not required)
+ void (*ReadPtr)(); //Read function pointer
+ int ReadParam[4]; //Read function parameters; -10 = NU
+ int ResArea; //reserved area size
+ void (*WritePtr)(); //Write function pointer
+ int WriteParam[6]; //Write function parameters; -10 = NU
+ double WriteParamD; //Write function parameter, double
+};
+
+// This struct stores information about a specific device
+struct DevInfo{
+ char *device; //device name
+ enum group_t group; //device group (used for selection in GUI only) - see nameToGroup()
+ enum family_t family; //architecture type
+// int type; //type
+ double HV; //High voltage value (-1= turn off HV)
+ int V33; //3.3V regulator required (0=not required)
+ int size; //memory size
+ int sizeEE; //EE memory size
+ char *features; //device features string
+};
+
+extern int NDEVLIST;
+extern struct DEVICES DEVLIST[];
+
+/// Determine the group of a specific device
+enum group_t nameToGroup(const char *devName);
+
+/// Copies the device info from the passed devlist entry into the passed DevInfo
+/// Does NOT populate fields 'device' and 'group' as these are device-specific
+void populateDevInfo(struct DevInfo *info, const struct DEVICES *devlistEntry);
+
+///Search and return device info. Uses strtok (so don't call inside a strtok loop)
+struct DevInfo GetDevInfo(const char* dev);
+
+void AddDevices();
+char* ListDevices();
+int GetDevType(const char* device);
+struct DevInfo GetDevInfo(const char* dev);
+void Write(char* dev,int ee);
+void Read(char* dev,int ee,int r);
diff --git a/fileIO.c b/fileIO.c
new file mode 100644
index 0000000..30da4b0
--- /dev/null
+++ b/fileIO.c
@@ -0,0 +1,835 @@
+/*
+ * fileIO.c - file read and write
+ * Copyright (C) 2010-2021 Alberto Maccioni
+ *
+ * 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/>
+ */
+
+//configure for GUI or command-line
+#include "common.h"
+#include "progP12.h"
+#include "progP16.h"
+#include "progP18.h"
+#include "progP24.h"
+#include "progAVR.h"
+
+unsigned int htoi(const char *hex, int length)
+{
+ int i;
+ unsigned int v = 0;
+ for (i = 0; i < length; i++) {
+ v <<= 4;
+ if (hex[i] >= '0' && hex[i] <= '9') v += hex[i] - '0';
+ else if (hex[i] >= 'a' && hex[i] <= 'f') v += hex[i] - 'a' + 10;
+ else if (hex[i] >= 'A' && hex[i] <= 'F') v += hex[i] - 'A' + 10;
+ else PrintMessage1(strings[S_Inohex],hex); //"Error: '%.4s' doesn't look very hexadecimal, right?\n"
+ }
+ return v;
+}
+
+void Save(char* dev,char* savefile)
+{
+ FILE* f=fopen(savefile,"w");
+ if(!f) return;
+ char str[512],str1[512]="";
+ int i,sum=0,count=0,ext=0,s,base;
+//**************** 10-16F *******************************************
+ if(!strncmp(dev,"10",2)||!strncmp(dev,"12",2)||!strncmp(dev,"16",2)){
+ int x=0x3fff,addr;
+ //if(!strncmp(dev,"16",2)||!strncmp(dev,"12F6",4)) x=0x3fff;
+ fprintf(f,":020000040000FA\n"); //extended address=0
+ for(i=0;i<sizeW;i++) memCODE_W[i]&=x;
+ for(i=0;i<sizeW&&memCODE_W[i]>=x;i++); //remove leading 0xFFF
+ for(;i<sizeW;i++){
+ sum+=(memCODE_W[i]>>8)+(memCODE_W[i]&0xff);
+ sprintf(str,"%02X%02X",memCODE_W[i]&0xff,memCODE_W[i]>>8);
+ strcat(str1,str);
+ count++;
+ if(count==8||i==sizeW-1){
+ base=i-count+1;
+ for(s=i;s>=base&&memCODE_W[s]>=x;s--){ //remove trailing 0xFFF
+ sum-=(memCODE_W[s]>>8)+(memCODE_W[s]&0xff);
+ str1[strlen(str1)-4]=0;
+ }
+ count-=i-s;
+ addr=(s-count+1)*2;
+ sum+=count*2+(addr&0xff)+(addr>>8);
+ if(base>>15>ext){
+ ext=base>>15;
+ fprintf(f,":02000004%04X%02X\n",ext,(-6-ext)&0xff);
+ }
+ if(count) fprintf(f,":%02X%04X00%s%02X\n",count*2,addr&0xFFFF,str1,(-sum)&0xff);
+ str1[0]=0;
+ count=sum=0;
+ }
+ }
+ if(sizeEE){ //this is only for 16F1xxx
+ if(ext!=0x01) fprintf(f,":020000040001F9\n");
+ for(i=0,count=sum=0;i<sizeEE;i++){
+ sum+=memEE[i];
+ sprintf(str,"%02X00",memEE[i]&0xff);
+ strcat(str1,str);
+ count++;
+ if(count==8||i==sizeEE-1){
+ for(s=i;s>i-count&&memEE[s]>=0xff;s--){ //remove trailing 0xFF
+ sum-=memEE[s]&0xff;
+ str1[strlen(str1)-4]=0;
+ }
+ count-=i-s;
+ addr=(s-count+1)*2+0xE000;
+ sum+=count*2+(addr&0xff)+(addr>>8);
+ if(count){
+ fprintf(f,":%02X%04X00%s%02X\n",count*2,addr,str1,(-sum)&0xff);
+ }
+ str1[0]=0;
+ count=sum=0;
+ }
+ }
+ }
+ fprintf(f,":00000001FF\n");
+ }
+//**************** 18F *******************************************
+ else if(!strncmp(dev,"18F",3)){
+ fprintf(f,":020000040000FA\n"); //extended address=0
+ for(i=0;i<size&&memCODE[i]==0xff;i++); //remove leading 0xFF
+ for(;i<size;i++){
+ sum+=memCODE[i];
+ sprintf(str,"%02X",memCODE[i]);
+ strcat(str1,str);
+ count++;
+ if(count==16||i==size-1){
+ base=i-count+1;
+ for(s=i;s>=base&&memCODE[s]==0xff;s--){ //remove trailing 0xFF
+ sum-=memCODE[s];
+ str1[strlen(str1)-2]=0;
+ }
+ count-=i-s;
+ sum+=count+(base&0xff)+((base>>8)&0xff);
+ if(base>>16>ext){
+ ext=base>>16;
+ fprintf(f,":02000004%04X%02X\n",ext,(-6-ext)&0xff);
+ }
+ if(count){
+ fprintf(f,":%02X%04X00%s%02X\n",count,base&0xFFFF,str1,(-sum)&0xff);
+ }
+ str1[0]=0;
+ count=sum=0;
+ }
+ }
+ for(i=0,count=sum=0;i<8;i++){
+ sum+=memID[i];
+ sprintf(str,"%02X",memID[i]&0xff);
+ strcat(str1,str);
+ count++;
+ if(count==8){
+ fprintf(f,":020000040020DA\n");
+ base=i-count+1;
+ for(s=i;s>i-count&&memID[s]>=0xff;s--){ //remove trailing 0xFF
+ sum-=memID[s]&0xff;
+ str1[strlen(str1)-2]=0;
+ }
+ count-=i-s;
+ sum+=count+(base&0xff)+((base>>8)&0xff);
+ if(count){
+ fprintf(f,":%02X%04X00%s%02X\n",count,base&0xFFFF,str1,(-sum)&0xff);
+ }
+ str1[0]=0;
+ count=sum=0;
+ }
+ }
+ for(i=0,count=sum=0;i<14;i++){
+ sum+=memCONFIG[i];
+ sprintf(str,"%02X",memCONFIG[i]&0xff);
+ strcat(str1,str);
+ count++;
+ if(count==14){
+ fprintf(f,":020000040030CA\n");
+ base=i-count+1;
+ for(s=i;s>i-count&&memCONFIG[s]>=0xff;s--){ //remove trailing 0xFF
+ sum-=memCONFIG[s]&0xff;
+ str1[strlen(str1)-2]=0;
+ }
+ count-=i-s;
+ sum+=count+(base&0xff)+((base>>8)&0xff);
+ if(count){
+ fprintf(f,":%02X%04X00%s%02X\n",count,base&0xFFFF,str1,(-sum)&0xff);
+ }
+ str1[0]=0;
+ count=sum=0;
+ }
+ }
+ if(sizeEE){
+ fprintf(f,":0200000400F00A\n");
+ for(i=0,count=sum=0;i<sizeEE;i++){
+ sum+=memEE[i];
+ sprintf(str,"%02X",memEE[i]&0xff);
+ strcat(str1,str);
+ count++;
+ if(count==16||i==sizeEE-1){
+ base=i-count+1;
+ for(s=i;s>i-count&&memEE[s]>=0xff;s--){ //remove trailing 0xFF
+ sum-=memEE[s]&0xff;
+ str1[strlen(str1)-2]=0;
+ }
+ count-=i-s;
+ sum+=count+(base&0xff)+((base>>8)&0xff);
+ if(count){
+ fprintf(f,":%02X%04X00%s%02X\n",count,base&0xFFFF,str1,(-sum)&0xff);
+ }
+ str1[0]=0;
+ count=sum=0;
+ }
+ }
+ }
+ fprintf(f,":00000001FF\n");
+ }
+//**************** 24F *******************************************
+ else if((!strncmp(dev,"24F",3)||!strncmp(dev,"24H",3)||!strncmp(dev,"24E",3)||!strncmp(dev,"30F",3)||!strncmp(dev,"33F",3)||!strncmp(dev,"33E",3))){
+ int valid;
+ fprintf(f,":020000040000FA\n"); //extended address=0
+ int sum=0,count=0,s,word;
+ word=memCODE[0]+(memCODE[1]<<8)+(memCODE[2]<<16)+(memCODE[3]<<24);
+ for(i=0;i<size&&word==0xffffffff;i+=4) //remove leading 0xFFFFFFFF
+ word=memCODE[i]+(memCODE[i+1]<<8)+(memCODE[i+2]<<16)+(memCODE[i+3]<<24);
+ for(;i<size;i++){
+ sum+=memCODE[i];
+ sprintf(str,"%02X",memCODE[i]);
+ strcat(str1,str);
+ count++;
+ if(count==16||i==size-1){
+ base=i-count+1;
+ for(s=base,valid=0;s<=i&&!valid;s+=4){ //remove empty lines
+ if(memCODE[s]<0xFF||memCODE[s+1]<0xFF||+memCODE[s+2]<0xFF) valid=1;
+ }
+ sum+=count+(base&0xff)+((base>>8)&0xff);
+ if(base>>16>ext){
+ ext=base>>16;
+ fprintf(f,":02000004%04X%02X\n",ext,(-6-ext)&0xff);
+ }
+ if(count&&valid){
+ fprintf(f,":%02X%04X00%s%02X\n",count,base&0xFFFF,str1,(-sum)&0xff);
+ }
+ str1[0]=0;
+ count=sum=0;
+ }
+ }
+ if(sizeCONFIG){
+ fprintf(f,":0200000401F009\n");
+ for(i=0,count=sum=0;i<sizeCONFIG&&i<48;i++){
+ sum+=memCONFIG[i];
+ sprintf(str,"%02X",memCONFIG[i]);
+ strcat(str1,str);
+ count++;
+ if(count==4||i==sizeCONFIG-1){
+ base=i-count+1;
+ sum+=count+(base&0xff)+((base>>8)&0xff);
+ if(count){
+ fprintf(f,":%02X%04X00%s%02X\n",count,base&0xFFFF,str1,(-sum)&0xff);
+ }
+ str1[0]=0;
+ count=sum=0;
+ }
+ }
+ }
+ if(sizeEE){
+ fprintf(f,":0200000400FFFB\n");
+ str1[0]=0;
+ for(i=0,count=sum=0;i<sizeEE;i+=2){ //append 0000 every 2 bytes
+ sum+=memEE[i]+memEE[i+1];
+ sprintf(str,"%02X%02X0000",memEE[i]&0xff,memEE[i+1]&0xff);
+ strcat(str1,str);
+ count+=4;
+ if(count==16||i==sizeEE-2){
+ base=2*i-count+4;
+ for(s=base/2,valid=0;s<=i&&!valid;s+=2){ //remove empty lines
+ if(memEE[s]<0xFF||memEE[s+1]<0xFF) valid=1;
+ }
+ sum+=0xE0+count+(base&0xff)+(base>>8);
+ if(count&&valid){
+ fprintf(f,":%02X%04X00%s%02X\n",count,base+0xE000,str1,(-sum)&0xff);
+ }
+ str1[0]=0;
+ count=sum=0;
+ }
+ }
+ }
+ fprintf(f,":00000001FF\n");
+ }
+//**************** ATxxxx *******************************************
+ else if(!strncmp(dev,"AT",2)){
+ fprintf(f,":020000040000FA\n"); //extended address=0
+ for(i=0;i<size&&memCODE[i]==0xff;i++); //remove leading 0xFF
+ for(;i<size;i++){
+ sum+=memCODE[i];
+ sprintf(str,"%02X",memCODE[i]);
+ strcat(str1,str);
+ count++;
+ if(count==16||i==size-1){
+ base=i-count+1;
+ for(s=i;s>=base&&memCODE[s]==0xff;s--){ //remove trailing 0xFF
+ sum-=memCODE[s];
+ str1[strlen(str1)-2]=0;
+ }
+ count-=i-s;
+ sum+=count+(base&0xff)+((base>>8)&0xff);
+ if(base>>16>ext){
+ ext=base>>16;
+ fprintf(f,":02000004%04X%02X\n",ext,(-6-ext)&0xff);
+ }
+ if(count){
+ fprintf(f,":%02X%04X00%s%02X\n",count,base&0xFFFF,str1,(-sum)&0xff);
+ }
+ str1[0]=0;
+ count=sum=0;
+ }
+ }
+ fprintf(f,":00000001FF\n");
+ }
+//**************** 24xxx / 93xxx / 25xxx / 95xxx / DSxxxx *******************************************
+ else if(!strncmp(dev,"24",2)||!strncmp(dev,"93",2)||!strncmp(dev,"25",2)||!strncmp(dev,"95",2)||\
+ !strncmp(dev,"DS",2)||!strncmp(dev,"11",2)){
+ if(strstr(savefile,".bin")||strstr(savefile,".BIN")){
+ #ifdef _WIN32
+ //brain-damaged op. systems need this to avoid messing with some bytes
+ f=freopen(savefile,"wb",f);
+ if(!f) return;
+ #endif
+ fwrite(memEE,1,sizeEE,f);
+ }
+ else{ //HEX
+ int valid;
+ fprintf(f,":020000040000FA\n"); //extended address=0
+ for(i=0;i<sizeEE;i++){
+ sum+=memEE[i];
+ sprintf(str,"%02X",memEE[i]);
+ strcat(str1,str);
+ count++;
+ if(count==16||i==sizeEE-1){
+ for(s=valid=0;str1[s]&&!valid;s++) if(str1[s]!='F') valid=1;
+ if(valid){
+ base=i-count+1;
+ sum+=count+(base&0xff)+((base>>8)&0xff);
+ if(base>>16>ext){
+ ext=base>>16;
+ fprintf(f,":02000004%04X%02X\n",ext,(-6-ext)&0xff);
+ }
+ if(count){
+ fprintf(f,":%02X%04X00%s%02X\n",count,base&0xFFFF,str1,(-sum)&0xff);
+ }
+ }
+ str1[0]=0;
+ count=sum=0;
+ }
+ }
+ fprintf(f,":00000001FF\n");
+ }
+ }
+ if(f) fclose(f);
+}
+
+void SaveEE(char* dev,char* savefile){
+ FILE* f=fopen(savefile,"w");
+ if(!f) return;
+//**************** ATMEL *******************************************
+ if(!strncmp(dev,"AT",2)){
+ char str[512],str1[512]="";
+ int i,base;
+ fprintf(f,":020000040000FA\n"); //extended address=0
+ int sum=0,count=0,s;
+ for(i=0,count=sum=0;i<sizeEE;i++){
+ sum+=memEE[i];
+ sprintf(str,"%02X",memEE[i]&0xff);
+ strcat(str1,str);
+ count++;
+ if(count==16||i==sizeEE-1){
+ base=i-count+1;
+ for(s=i;s>i-count&&memEE[s]>=0xff;s--){ //remove trailing 0xFF
+ sum-=memEE[s]&0xff;
+ str1[strlen(str1)-2]=0;
+ }
+ count-=i-s;
+ sum+=count+(base&0xff)+((base>>8)&0xff);
+ if(count){
+ fprintf(f,":%02X%04X00%s%02X\n",count,base&0xFFFF,str1,(-sum)&0xff);
+ }
+ str1[0]=0;
+ count=sum=0;
+ }
+ }
+ fprintf(f,":00000001FF\n");
+ }
+ if(f) fclose(f);
+}
+
+int Load(char*dev,char*loadfile){
+ int i,input_address=0,ext_addr=0,sum,valid;
+ char line[256];
+ FILE* f=fopen(loadfile,"r");
+ if(!f) return -1;
+ PrintMessage1("%s :\r\n",loadfile);
+//**************** 10-16F *******************************************
+ if(!strncmp(dev,"10",2)||!strncmp(dev,"12",2)||!strncmp(dev,"16",2)){
+ unsigned char buffer[0x20000],bufferEE[0x1000];
+ int sizeM=0;
+ memset(buffer,0xFF,sizeof(buffer));
+ memset(bufferEE,0xFF,sizeof(bufferEE));
+ sizeEE=0;
+ for(;fgets(line,256,f);){
+ if(strlen(line)>9&&line[0]==':'){
+ int hex_count = htoi(line+1, 2);
+ if((int)strlen(line)-11<hex_count*2) {
+ PrintMessage1(strings[S_IhexShort],line); //"Intel hex8 line too short:\r\n%s\r\n"
+ }
+ else{
+ input_address=(ext_addr<<16)+htoi(line+3,4);
+ sum=0;
+ for (i=1;i<=hex_count*2+9;i+=2) sum += htoi(line+i,2);
+ if ((sum & 0xff)!=0) {
+ PrintMessage1(strings[S_IhexChecksum],line); //"Intel hex8 checksum error in line:\r\n%s\r\n"
+ }
+ else{
+ switch(htoi(line+7,2)){
+ case 0: //Data record
+ if(input_address<0x1E000){ //Code
+ sizeM=input_address+hex_count;
+ if(sizeM>sizeW) sizeW=sizeM;
+ for (i=0;i<hex_count;i++){
+ buffer[input_address+i]=htoi(line+9+i*2,2);
+ }
+ }
+ else if(input_address>=0x1E000&&input_address<0x1F000){ //EEPROM
+ sizeM=(input_address-0x1E000+hex_count)/2;
+ if(sizeM>sizeEE) sizeEE=sizeM;
+ for (i=0;i<hex_count;i+=2){
+ bufferEE[(input_address-0x1E000)/2+i/2]=htoi(line+9+i*2,2);
+ }
+ }
+ break;
+ case 4: //extended linear address record
+ if(strlen(line)>14) ext_addr=htoi(line+9,4);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ }
+ sizeW/=2;
+ if(memCODE_W) free(memCODE_W);
+ memCODE_W=(WORD*)malloc(sizeof(WORD)*sizeW);
+ for(i=0;i<sizeW;i++){ //Swap bytes
+ memCODE_W[i]=(buffer[i*2+1]<<8)+buffer[i*2];
+ }
+ if(memEE) free(memEE);
+ if(sizeEE){
+ memEE=(unsigned char*)malloc(sizeEE);
+ memcpy(memEE,bufferEE,sizeEE);
+ }
+ else memEE=0;
+ PrintMessage(strings[S_CodeMem]); //"\r\nCode memory:\r\n"
+ int imax=sizeW>0x8000?0x8500:0x2100;
+ DisplayCODE16F(imax);
+ if(sizeW>=0x2100&&sizeW<0x3000){ //EEPROM@0x2100
+ PrintMessage(strings[S_EEMem]); //"\r\nEEPROM memory:\r\n"
+ DisplayEE16F(0x700);
+ }
+ else if(sizeEE) DisplayEE();
+ PrintMessage("\r\n");
+ }
+//**************** 18F *******************************************
+ else if(!strncmp(dev,"18F",3)){
+ unsigned char buffer[0x30000],bufferEE[0x1000];
+ int sizeM;
+ memset(buffer,0xFF,sizeof(buffer));
+ memset(bufferEE,0xFF,sizeof(bufferEE));
+ memset(memID,0xFF,sizeof(memID));
+ memset(memCONFIG,0xFF,sizeof(memCONFIG));
+ for(;fgets(line,256,f);){
+ if(strlen(line)>9&&line[0]==':'){
+ int hex_count = htoi(line+1, 2);
+ if((int)strlen(line) - 11 < hex_count * 2) {
+ PrintMessage1(strings[S_IhexShort],line); //"Intel hex8 line too short:\r\n%s\r\n"
+ }
+ else{
+ input_address=htoi(line+3,4);
+ sum=0;
+ for (i=1;i<=hex_count*2+9;i+=2)
+ sum += htoi(line+i,2);
+ if ((sum & 0xff)!=0) {
+ PrintMessage1(strings[S_IhexChecksum],line); //"Intel hex8 checksum error in line:\r\n%s\r\n"
+ }
+ else{
+ switch(htoi(line+7,2)){
+ case 0: //Data record
+ if(ext_addr<0x20){ //Code <0x200000
+ sizeM=(ext_addr<<16)+input_address+hex_count;
+ if(sizeM>size) size=sizeM;
+ for (i=0;i<hex_count;i++){
+ buffer[(ext_addr<<16)+input_address+i]=htoi(line+9+i*2,2);
+ }
+ }
+ else if(ext_addr==0x20&&input_address<64){ //ID: 0x200000
+ for (i=0;i<hex_count;i++){
+ memID[input_address+i]=htoi(line+9+i*2,2);
+ }
+ }
+ else if(ext_addr==0x30&&input_address<14){ //CONFIG: 0x300000
+ for (i=0;i<hex_count;i++){
+ memCONFIG[input_address+i]=htoi(line+9+i*2,2);
+ }
+ }
+ else if((ext_addr==0xF0||ext_addr==0x31||ext_addr==0x38)&&input_address<0x1000){
+ //EEPROM: 0xF00000, 0x310000, 0x380000
+ for (i=0;i<hex_count;i++){
+ bufferEE[input_address+i]=htoi(line+9+i*2,2);
+ }
+ sizeM=input_address+hex_count;
+ if(sizeM>sizeEE) sizeEE=sizeM;
+
+ }
+ break;
+ case 4: //extended linear address record
+ if(strlen(line)>14) ext_addr=htoi(line+9,4);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ }
+ if(memCODE) free(memCODE);
+ memCODE=(unsigned char*)malloc(size);
+ memcpy(memCODE,buffer,size);
+ if(memEE) free(memEE);
+ memEE=(unsigned char*)malloc(sizeEE);
+ memcpy(memEE,bufferEE,sizeEE);
+ PrintMessage(strings[S_IDMem]); //"ID memory:\r\n"
+ for(i=0;i<8;i+=2) PrintMessage4("ID%d: 0x%02X ID%d: 0x%02X\r\n",i,memID[i],i+1,memID[i+1]);
+ PrintMessage(strings[S_ConfigMem]); //"CONFIG memory:\r\n"
+ 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"
+ }
+ PrintMessage(strings[S_CodeMem]); //"\r\nCODE memory:\r\n"
+ DisplayCODE18F(size);
+ if(sizeEE) DisplayEE();
+ PrintMessage("\r\n");
+ }
+//**************** 24F *******************************************
+ else if(!strncmp(dev,"24F",3)||!strncmp(dev,"24H",3)||!strncmp(dev,"24E",3)||!strncmp(dev,"30F",3)||!strncmp(dev,"33F",3)||!strncmp(dev,"33E",3)){
+ unsigned char *buffer,bufferEE[0x2000];
+ int d;
+ buffer=(unsigned char*)malloc(0x100000);
+ memset(buffer,0xFF,0x100000);
+ memset(bufferEE,0xFF,sizeof(bufferEE));
+ memset(memCONFIG,0xFF,sizeof(memCONFIG));
+ memset(memUSERID,0xFF,sizeof(memUSERID));
+ sizeUSERID=0;
+ for(;fgets(line,256,f);){
+ if(strlen(line)>9&&line[0]==':'){
+ int hex_count = htoi(line+1, 2);
+ if((int)strlen(line) - 11 < hex_count * 2) {
+ PrintMessage1(strings[S_IhexShort],line); //"Intel hex8 line too short:\r\n%s\r\n"
+ }
+ else{
+ input_address=htoi(line+3,4);
+ sum=0;
+ for (i=1;i<=hex_count*2+9;i+=2)
+ sum += htoi(line+i,2);
+ if ((sum & 0xff)!=0) {
+ PrintMessage1(strings[S_IhexChecksum],line); //"Intel hex8 checksum error in line:\r\n%s\r\n"
+ }
+ else{
+ switch(htoi(line+7,2)){
+ case 0: //Data record
+ if(ext_addr<0x20){ //Code
+ int end1=(ext_addr<<16)+input_address+hex_count;
+ if(size<end1) size=end1;
+ for (i=0;i<hex_count;i++){
+ buffer[(ext_addr<<16)+input_address+i]=htoi(line+9+i*2,2);
+ }
+ }
+ else if(ext_addr==0x1F0&&input_address<48){ //CONFIG
+ sizeCONFIG=input_address+hex_count;
+ for (i=0;i<hex_count;i++){
+ memCONFIG[input_address+i]=htoi(line+9+i*2,2);
+ }
+ }
+ else if(ext_addr==0xFF&&input_address>=0xE000){ //EEPROM
+ for (i=0;i<hex_count;i++){
+ bufferEE[input_address-0xE000+i]=htoi(line+9+i*2,2);
+ }
+ sizeEE=input_address-0xE000+hex_count;
+ }
+ else if(ext_addr==0x100&&input_address<8){ //USER ID
+ sizeUSERID=input_address+hex_count;
+ for (i=0;i<hex_count&&(i+input_address)<8;i++){
+ memUSERID[input_address+i]=htoi(line+9+i*2,2);
+ }
+ }
+ break;
+ case 4: //extended linear address record
+ if(strlen(line)>14) ext_addr=htoi(line+9,4);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ }
+ if(memCODE) free(memCODE);
+ memCODE=(unsigned char*)malloc(size);
+ memcpy(memCODE,buffer,size);
+ free(buffer);
+ sizeEE=sizeEE?0x1000:0;
+ if(memEE) free(memEE);
+ memEE=(unsigned char*)malloc(sizeEE);
+ for(i=0;i<sizeEE;i+=2){ //skip voids in the hex file organization
+ memEE[i]=bufferEE[i*2]; //0 1 4 5 8 9 12 13 ...
+ memEE[i+1]=bufferEE[i*2+1];
+ }
+ for(i=valid=0;i<48;i++) if(memCONFIG[i]<0xFF) valid=1;
+ if(valid){
+ PrintMessage(strings[S_ConfigMem]); //"\r\nCONFIG memory:\r\n"
+ for(i=0;i<48;i+=4){
+ d=(memCONFIG[i+1]<<8)+memCONFIG[i];
+ if(i<36||d<0xFFFF)PrintMessage2("0xF800%02X: 0x%04X\r\n",i/2,d);
+ }
+ }
+ if(size) PrintMessage(strings[S_CodeMem]); //"\r\nCODE memory:\r\n"
+ DisplayCODE24F(size);
+ if(sizeEE){ //show eeprom with address offset by 0x7FF000
+ PrintMessage(strings[S_EEMem]); //"\r\nEEPROM memory:\r\n"
+ DisplayEE24F();
+ }
+ PrintMessage("\r\n");
+ }
+//**************** ATxxxx *******************************************
+ else if(!strncmp(dev,"AT",2)){
+ unsigned char buffer[0x30000];
+ memset(buffer,0xFF,sizeof(buffer));
+ for(;fgets(line,256,f);){
+ if(strlen(line)>9&&line[0]==':'){
+ int hex_count = htoi(line+1, 2);
+ if((int)strlen(line) - 11 < hex_count * 2) {
+ PrintMessage1(strings[S_IhexShort],line); //"Intel hex8 line too short:\r\n%s\r\n"
+ }
+ else{
+ input_address=htoi(line+3,4);
+ sum=0;
+ for (i=1;i<=hex_count*2+9;i+=2)
+ sum += htoi(line+i,2);
+ if ((sum & 0xff)!=0) {
+ PrintMessage1(strings[S_IhexChecksum],line); //"Intel hex8 checksum error in line:\r\n%s\r\n"
+ }
+ else{
+ switch(htoi(line+7,2)){
+ case 0: //Data record
+ if(ext_addr<0x20){ //Code
+ size=input_address+hex_count;
+ for (i=0;i<hex_count;i++){
+ buffer[(ext_addr<<16)+input_address+i]=htoi(line+9+i*2,2);
+ }
+ }
+ break;
+ case 4: //extended linear address record
+ if(strlen(line)>14) ext_addr=htoi(line+9,4);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ }
+ if(memCODE) free(memCODE);
+ memCODE=(unsigned char*)malloc(size);
+ memcpy(memCODE,buffer,size);
+ if(size) PrintMessage(strings[S_CodeMem]); //"\r\nmemoria CODICE:\r\n"
+ DisplayCODEAVR(size);
+ PrintMessage("\r\n");
+ }
+//**************** 24xxx / 93xxx / 25xxx / 95xxx / DSxxxx /11xxx *******************************
+ else if(!strncmp(dev,"24",2)||!strncmp(dev,"93",2)||!strncmp(dev,"25",2)||!strncmp(dev,"95",2)||\
+ !strncmp(dev,"DS",2)||!strncmp(dev,"11",2)){
+ if(strstr(loadfile,".bin")||strstr(loadfile,".BIN")){
+ #ifdef _WIN32
+ //brain-damaged op. systems need this to avoid messing with some bytes
+ f=freopen(loadfile,"rb",f);
+ if(!f) return -1;
+ #endif
+ fseek(f, 0L, SEEK_END);
+ sizeEE=ftell(f);
+ fseek(f, 0L, SEEK_SET);
+ if(sizeEE>0x1000000) sizeEE=0x1000000; //max 16MB
+ if(memEE) free(memEE);
+ memEE=(unsigned char*)malloc(sizeEE);
+ sizeEE=fread(memEE,1,sizeEE,f);
+ }
+ else{ //Hex file
+ int bufSize=0x40000; //256K
+ unsigned char *bufferEE=(unsigned char*)malloc(bufSize);
+ memset(bufferEE,0xFF,bufSize);
+ for(;fgets(line,256,f);){
+ if(strlen(line)>9&&line[0]==':'){
+ int hex_count = htoi(line+1, 2);
+ if((int)strlen(line) - 11 < hex_count * 2) {
+ PrintMessage1(strings[S_IhexShort],line); //"Intel hex8 line too short:\r\n%s\r\n"
+ }
+ else{
+ input_address=htoi(line+3,4);
+ sum=0;
+ int end1;
+ for (i=1;i<=hex_count*2+9;i+=2) sum+=htoi(line+i,2);
+ if ((sum & 0xff)!=0) {
+ PrintMessage1(strings[S_IhexChecksum],line); //"Intel hex8 checksum error in line:\r\n%s\r\n"
+ }
+ else{
+ switch(htoi(line+7,2)){
+ case 0: //Data record
+ end1=(ext_addr<<16)+input_address+hex_count;
+ if(end1>=0x1000000) break; //max 16MB
+ if(sizeEE<end1){ //grow array
+ sizeEE=end1;
+ }
+ if(bufSize<=end1){ //grow buffer
+ int newsize=(end1&0xFFFC0000)+0x40000;
+ bufferEE=(unsigned char*)realloc(bufferEE,newsize);
+ memset(bufferEE+bufSize,0xFF,newsize-bufSize);
+ bufSize=newsize;
+ }
+ for (i=0;i<hex_count;i++){
+ bufferEE[(ext_addr<<16)+input_address+i]=htoi(line+9+i*2,2);
+ }
+ break;
+ case 4: //extended linear address record
+ if(strlen(line)>14) ext_addr=htoi(line+9,4);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ }
+ if(memEE) free(memEE);
+ memEE=(unsigned char*)malloc(sizeEE);
+ memcpy(memEE,bufferEE,sizeEE);
+ free(bufferEE);
+ }
+ DisplayEE(); //visualize
+ int sum=0;
+ for(i=0;i<sizeEE;i++) sum+=memEE[i];
+ PrintMessage1("Checksum: 0x%X\r\n",sum&0xFFFF);
+ PrintMessage("\r\n");
+ }
+ fclose(f);
+ return 0;
+}
+
+void LoadEE(char*dev,char*loadfile){
+ FILE* f=fopen(loadfile,"r");
+ if(!f) return;
+ int i;
+//**************** ATMEL *******************************************
+ if(!strncmp(dev,"AT",2)){
+ char line[256];
+ int input_address=0,ext_addr=0;
+ unsigned char bufferEE[0x1000];
+ PrintMessage1("%s :\r\n\r\n",loadfile);
+ memset(bufferEE,0xFF,sizeof(bufferEE));
+ for(;fgets(line,256,f);){
+ if(strlen(line)>9&&line[0]==':'){
+ int hex_count = htoi(line+1, 2);
+ if((int)strlen(line) - 11 < hex_count * 2) {
+ PrintMessage1(strings[S_IhexShort],line); //"Intel hex8 line too short:\r\n%s\r\n"
+ }
+ else{
+ input_address=htoi(line+3,4);
+ int sum = 0;
+ for (i=1;i<=hex_count*2+9;i+=2) sum+=htoi(line+i,2);
+ if ((sum & 0xff)!=0) {
+ PrintMessage1(strings[S_IhexChecksum],line); //"Intel hex8 checksum error in line:\r\n%s\r\n"
+ }
+ else{
+ switch(htoi(line+7,2)){
+ case 0: //Data record
+ if(ext_addr==0&&input_address<0x1000){ //EEPROM
+ for (i=0;i<hex_count;i++){
+ bufferEE[input_address+i]=htoi(line+9+i*2,2);
+ }
+ sizeEE=input_address+hex_count;
+ }
+ break;
+ case 4: //extended linear address record
+ if(strlen(line)>14) ext_addr=htoi(line+9,4);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ }
+ if(memEE) free(memEE);
+ memEE=(unsigned char*)malloc(sizeEE);
+ memcpy(memEE,bufferEE,sizeEE);
+ if(sizeEE) DisplayEE(); //visualize
+ PrintMessage("\r\n");
+ fclose(f);
+ }
+}
+
+void OpenLogFile()
+{
+ logfile=fopen(LogFileName,"w");
+ if(!logfile) return;
+ fprintf(logfile,_APPNAME " version %s (%s)\n",VERSION,SYSNAME);
+ fprintf(logfile,"Firmware version %d.%d.%d\n",FWVersion>>16,(FWVersion>>8)&0xFF,FWVersion&0xFF);
+ struct tm * timeinfo;
+ time_t rawtime;
+ time( &rawtime ); /* Get time as long integer. */
+ timeinfo = localtime( &rawtime ); /* Convert to local time. */
+ fprintf(logfile,"%s\n", asctime (timeinfo) );
+}
+
+void CloseLogFile()
+{
+ if(logfile)fclose(logfile);
+ logfile=0;
+}
+
+void WriteLogIO()
+{
+ int i;
+ //fprintf(logfile,"bufferU=[%02X\n",bufferU[0]);
+ fprintf(logfile,"bufferU=[");
+ for(i=0;i<DIMBUF;i++){
+ if(i%32==0) fprintf(logfile,"\n");
+ fprintf(logfile,"%02X ",bufferU[i]);
+ }
+ fprintf(logfile,"]\n");
+ //fprintf(logfile,"bufferI=[%02X\n",bufferI[0]);
+ fprintf(logfile,"bufferI=[");
+ for(i=0;i<DIMBUF;i++){
+ if(i%32==0) fprintf(logfile,"\n");
+ fprintf(logfile,"%02X ",bufferI[i]);
+ }
+ fprintf(logfile,"]\n");
+}
diff --git a/fileIO.h b/fileIO.h
new file mode 100644
index 0000000..339d5a9
--- /dev/null
+++ b/fileIO.h
@@ -0,0 +1,8 @@
+unsigned int htoi(const char *hex, int length);
+void Save(char* dev,char* savefile);
+int Load(char*dev,char*loadfile);
+void SaveEE(char* dev,char* savefile);
+int LoadEE(char*dev,char*loadfile);
+void OpenLogFile(void);
+void WriteLogIO();
+void CloseLogFile();
diff --git a/gpl-2.0.txt b/gpl-2.0.txt
new file mode 100644
index 0000000..d511905
--- /dev/null
+++ b/gpl-2.0.txt
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/hid-example.c b/hid-example.c
new file mode 100644
index 0000000..37a0ffc
--- /dev/null
+++ b/hid-example.c
@@ -0,0 +1,182 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Hidraw Userspace Example
+ *
+ * Copyright (c) 2010 Alan Ott <alan@signal11.us>
+ * Copyright (c) 2010 Signal 11 Software
+ *
+ * The code may be used by anyone for any purpose,
+ * and can serve as a starting point for developing
+ * applications using hidraw.
+ */
+
+/* Linux */
+#include <linux/types.h>
+#include <linux/input.h>
+#include <linux/hidraw.h>
+
+/*
+ * Ugly hack to work around failing compilation on systems that don't
+ * yet populate new version of hidraw.h to userspace.
+ */
+#ifndef HIDIOCSFEATURE
+#warning Please have your distro update the userspace kernel headers
+#define HIDIOCSFEATURE(len) _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x06, len)
+#define HIDIOCGFEATURE(len) _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x07, len)
+#endif
+
+/* Unix */
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+/* C */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+
+const char *bus_str(int bus);
+
+int main(int argc, char **argv)
+{
+ int fd;
+ int i, res, desc_size = 0;
+ char buf[256];
+ struct hidraw_report_descriptor rpt_desc;
+ struct hidraw_devinfo info;
+ char *device = "/dev/hidraw0";
+
+ if (argc > 1)
+ device = argv[1];
+
+ /* Open the Device with non-blocking reads. In real life,
+ don't use a hard coded path; use libudev instead. */
+ fd = open(device, O_RDWR|O_NONBLOCK);
+
+ if (fd < 0) {
+ perror("Unable to open device");
+ return 1;
+ }
+
+ memset(&rpt_desc, 0x0, sizeof(rpt_desc));
+ memset(&info, 0x0, sizeof(info));
+ memset(buf, 0x0, sizeof(buf));
+
+ /* Get Report Descriptor Size */
+ res = ioctl(fd, HIDIOCGRDESCSIZE, &desc_size);
+ if (res < 0)
+ perror("HIDIOCGRDESCSIZE");
+ else
+ printf("Report Descriptor Size: %d\n", desc_size);
+
+ /* Get Report Descriptor */
+ rpt_desc.size = desc_size;
+ res = ioctl(fd, HIDIOCGRDESC, &rpt_desc);
+ if (res < 0) {
+ perror("HIDIOCGRDESC");
+ } else {
+ printf("Report Descriptor:\n");
+ for (i = 0; i < rpt_desc.size; i++)
+ printf("%hhx ", rpt_desc.value[i]);
+ puts("\n");
+ }
+
+ /* Get Raw Name */
+ res = ioctl(fd, HIDIOCGRAWNAME(256), buf);
+ if (res < 0)
+ perror("HIDIOCGRAWNAME");
+ else
+ printf("Raw Name: %s\n", buf);
+
+ /* Get Physical Location */
+ res = ioctl(fd, HIDIOCGRAWPHYS(256), buf);
+ if (res < 0)
+ perror("HIDIOCGRAWPHYS");
+ else
+ printf("Raw Phys: %s\n", buf);
+
+ /* Get Raw Info */
+ res = ioctl(fd, HIDIOCGRAWINFO, &info);
+ if (res < 0) {
+ perror("HIDIOCGRAWINFO");
+ } else {
+ printf("Raw Info:\n");
+ printf("\tbustype: %d (%s)\n",
+ info.bustype, bus_str(info.bustype));
+ printf("\tvendor: 0x%04hx\n", info.vendor);
+ printf("\tproduct: 0x%04hx\n", info.product);
+ }
+
+ /* Set Feature */
+ buf[0] = 0x9; /* Report Number */
+ buf[1] = 0xff;
+ buf[2] = 0xff;
+ buf[3] = 0xff;
+ res = ioctl(fd, HIDIOCSFEATURE(4), buf);
+ if (res < 0)
+ perror("HIDIOCSFEATURE");
+ else
+ printf("ioctl HIDIOCSFEATURE returned: %d\n", res);
+
+ /* Get Feature */
+ buf[0] = 0x9; /* Report Number */
+ res = ioctl(fd, HIDIOCGFEATURE(256), buf);
+ if (res < 0) {
+ perror("HIDIOCGFEATURE");
+ } else {
+ printf("ioctl HIDIOCGFEATURE returned: %d\n", res);
+ printf("Report data (not containing the report number):\n\t");
+ for (i = 0; i < res; i++)
+ printf("%hhx ", buf[i]);
+ puts("\n");
+ }
+
+ /* Send a Report to the Device */
+ buf[0] = 0x1; /* Report Number */
+ buf[1] = 0x77;
+ res = write(fd, buf, 2);
+ if (res < 0) {
+ printf("Error: %d\n", errno);
+ perror("write");
+ } else {
+ printf("write() wrote %d bytes\n", res);
+ }
+
+ /* Get a report from the device */
+ res = read(fd, buf, 16);
+ if (res < 0) {
+ perror("read");
+ } else {
+ printf("read() read %d bytes:\n\t", res);
+ for (i = 0; i < res; i++)
+ printf("%hhx ", buf[i]);
+ puts("\n");
+ }
+ close(fd);
+ return 0;
+}
+
+const char *
+bus_str(int bus)
+{
+ switch (bus) {
+ case BUS_USB:
+ return "USB";
+ break;
+ case BUS_HIL:
+ return "HIL";
+ break;
+ case BUS_BLUETOOTH:
+ return "Bluetooth";
+ break;
+ case BUS_VIRTUAL:
+ return "Virtual";
+ break;
+ default:
+ return "Other";
+ break;
+ }
+}
diff --git a/hid_test.c b/hid_test.c
new file mode 100644
index 0000000..ccc519d
--- /dev/null
+++ b/hid_test.c
@@ -0,0 +1,575 @@
+/*
+ * 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-1307 USA
+ */
+
+
+#if !defined _WIN32 && !defined __CYGWIN__
+ #include <sys/ioctl.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <asm/types.h>
+ #include <fcntl.h>
+ #include <linux/hiddev.h>
+ #include <linux/input.h>
+ #include <sys/timeb.h>
+#else
+ #include <windows.h>
+ #include <setupapi.h>
+ #include <hidusage.h>
+ #include <hidpi.h>
+ #include <math.h>
+ #include <sys/timeb.h>
+ #include <wchar.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <time.h>
+#include <ctype.h>
+#include <getopt.h>
+#include <string.h>
+
+int FindDevice();
+
+#if !defined _WIN32 && !defined __CYGWIN__
+DWORD GetTickCount();
+struct hiddev_report_info rep_info_i,rep_info_u;
+struct hiddev_usage_ref_multi ref_multi_i,ref_multi_u;
+struct hiddev_devinfo device_info;
+
+#else
+ #define write() Result = WriteFile(WriteHandle,bufferU,n,&BytesWritten,NULL);
+ #define read() Result = ReadFile(ReadHandle,bufferI,n,&NumberOfBytesRead,(LPOVERLAPPED) &HIDOverlapped);\
+ Result = WaitForSingleObject(hEventObject,50);\
+ ResetEvent(hEventObject);\
+ if(Result!=WAIT_OBJECT_0){\
+ printf("communication timeout\r\n");\
+ }
+
+unsigned char bufferU[128],bufferI[128];
+DWORD NumberOfBytesRead,BytesWritten;
+ULONG Result;
+HANDLE WriteHandle,ReadHandle;
+OVERLAPPED HIDOverlapped;
+HANDLE hEventObject;
+
+#endif
+
+int vid=0x1209,pid=0x5432,info=0;
+
+int main (int argc, char **argv) {
+#define L_IT 0
+#define L_EN 1
+ int d=0,v=0,q=0,r=1,lang=L_EN,c,i,j,block=0,R=0;
+ char path[512]="";
+ char buf[256];
+ for(i=0;i<256;i++) buf[i]=0;
+ #if defined _WIN32
+ int n=65;
+ int langID=GetUserDefaultLangID();
+ if((langID&0xFF)==0x10) lang=L_IT;
+ #else
+ int n=64;
+ if(getenv("LANG")&&strstr(getenv("LANG"),"it")!=0) lang=L_IT;
+ #endif
+ opterr = 0;
+ int option_index = 0;
+ struct option long_options[] =
+ {
+ {"b", no_argument, &block, 1},
+ {"block", no_argument, &block, 1},
+ {"verbose", no_argument, &v, 1},
+ {"v", no_argument, &v, 1},
+ {"quiet", no_argument, &q, 1},
+ {"q", no_argument, &q, 1},
+ {"info", no_argument, &info, 1},
+ {"i", no_argument, &info, 1},
+ {"help", no_argument, 0, 'h'},
+ {"path", required_argument, 0, 'p'},
+ {"read", required_argument, 0, 'R'},
+ {"repeat", required_argument, 0, 'r'},
+ {"delay", required_argument, 0, 'd'},
+ {0, 0, 0, 0}
+ };
+ while ((c = getopt_long_only (argc, argv, "n:d:p:hr:R:",long_options,&option_index)) != -1)
+ switch (c)
+ {
+ case 'h': //guida
+ if(!lang) printf("hid_test [opzioni] [dati]\n"
+ "opzioni: \n"
+ "-b, block\tusa lettura bloccante\n"
+ "-d, delay\tritardo lettura (ms) [0]\n"
+ "-h, help\tguida\n"
+ "-i, info\tinformazioni sul dispositivo [no]\n"
+ "-n\t\tdimensione report [64]\n"
+ "-p, path\tpercorso dispositivo [/dev/usb/hiddev0] \n"
+ "-q, quiet\tmostra solo risposta [no]\n"
+ "-R, read\tripeti lettura N volte [0]\n\n"
+ "-r, repeat\tripeti scrittura-lettura N volte [1]\n\n"
+ "-v, verbose\tmostra funzioni [no]\n"
+ "es. hid_test -i 1 2 3 4\n");
+ else printf("hid_test [otions] [data]\n"
+ "options: \n"
+ "-b, block\tuse blocking read\n"
+ "-d, delay\tread delay (ms) [0]\n"
+ "-h, help\thelp\n"
+ "-i, info\tdevice info [no]\n"
+ "-n\t\treport size [64]\n"
+ "-p, path\tdevice path [/dev/usb/hiddev0]\n"
+ "-q, quiet\tprint response only [no]\n"
+ "-R, repeat\trepeat read N times [0]\n\n"
+ "-r, repeat\trepeat N times [1]\n\n"
+ "-v, verbose\tshow functions [no]\n"
+ "e.g. hid_test -i 1 2 3 4\n");
+ exit(1);
+ break;
+ case 'n': //dim report
+ n = atoi(optarg);
+ break;
+ case 'd': //ritardo lettura
+ d = atoi(optarg);
+ break;
+ case 'p': //percorso hiddev
+ strncpy(path,optarg,sizeof(path));
+ break;
+ case 'r': //ripeti IO
+ r = atoi(optarg);
+ break;
+ case 'R': //ripeti lettura
+ R = atoi(optarg);
+ break;
+ case '?':
+ if (optopt == 'c')
+ fprintf (stderr, "Option -%c requires an argument.\n", optopt);
+ else if (isprint (optopt))
+ fprintf (stderr, "Unknown option `-%c'.\n", optopt);
+ else
+ fprintf (stderr, "Unknown option character 0x%02x\n", optopt);
+ return 1;
+ default:
+ //abort ();
+ break;
+ }
+
+ for (j=0,i = optind; i < argc&&i<128; i++,j++) sscanf(argv[i], "%x", &buf[j]);
+ for (;j<n;j++) buf[j]=0;
+
+ int fd = -1;
+
+ if(FindDevice()<0) exit(1);
+
+ if(!q){
+ printf("-> ");
+ for(i=0;i<j;i++) printf("%02X ",(unsigned char)buf[i]);
+ printf("\n");
+ }
+ if(v) printf("%slocking read\n",block?"B":"Non b");
+
+#if !defined _WIN32 && !defined __CYGWIN__
+ struct hiddev_event ev[80];
+ rep_info.report_type=HID_REPORT_TYPE_OUTPUT;
+ rep_info.report_id=HID_REPORT_ID_FIRST;
+ rep_info.num_fields=1;
+ ref_multi.uref.report_type=HID_REPORT_TYPE_OUTPUT;
+ ref_multi.uref.report_id=HID_REPORT_ID_FIRST;
+ ref_multi.uref.field_index=0;
+ ref_multi.uref.usage_index=0;
+ ref_multi.num_values=n;
+ for(i=0;i<n;i++) ref_multi.values[i]=buf[i];
+ int res;
+ res=ioctl(fd, HIDIOCSUSAGES, &ref_multi);
+ if(v) printf("HIDIOCSUSAGES:%d\n",res);
+ res=ioctl(fd,HIDIOCSREPORT, &rep_info);
+ if(v) printf("HIDIOCSREPORT:%d\n",res);
+ if(!block) for(j=0;j<r;j++){
+ usleep(d*1000);
+ rep_info.report_type=HID_REPORT_TYPE_INPUT;
+ res=ioctl(fd,HIDIOCGREPORT, &rep_info);
+ if(v) printf("HIDIOCGREPORT:%d\n",res);
+ ref_multi.uref.report_type=HID_REPORT_TYPE_INPUT;
+ res=ioctl(fd, HIDIOCGUSAGES, &ref_multi);
+ if(v) printf("HIDIOCGUSAGES:%d\n",res);
+ if(!q) printf("<- ");
+ for(i=0;i<n;i++) printf("%02X ",ref_multi.values[i]);
+ printf("\n");
+ }
+ else for(j=0;j<r;j++){
+ usleep(d*1000);
+ res=read(fd, ev,sizeof(struct hiddev_event) *n);
+ if(!q) printf("<- ");
+ for(i=0;i<n;i++) printf("%02X ",ev[i].value);
+ printf("\n");
+ }
+ else for(j=0;j<R;j++){
+ usleep(d*1000);
+ res=read(fd, ev,sizeof(struct hiddev_event) *n);
+ if(!q) printf("<- ");
+ for(i=0;i<n;i++) printf("%02X ",ev[i].value);
+ printf("\n");
+ }
+ close(fd);
+#else
+ __int64 start,stop,freq;
+ QueryPerformanceFrequency((LARGE_INTEGER *)&freq);
+ bufferU[0]=0;
+ for(i=0;i<n;i++) bufferU[i+1]=buf[i];
+ for(j=0;j<r;j++){
+ QueryPerformanceCounter((LARGE_INTEGER *)&start);
+ write();
+ Sleep(d);
+ read();
+ QueryPerformanceCounter((LARGE_INTEGER *)&stop);
+ if(!q) printf("<- ");
+ for(i=1;i<n;i++) printf("%02X ",bufferI[i]);
+ printf("\nT=%.2fms\n",(stop-start)*1000.0/freq);
+ }
+ for(j=0;j<R;j++){
+ QueryPerformanceCounter((LARGE_INTEGER *)&start);
+ read();
+ QueryPerformanceCounter((LARGE_INTEGER *)&stop);
+ if(!q) printf("<- ");
+ for(i=1;i<n;i++) printf("%02X ",bufferI[i]);
+ printf("\nT=%.2fms\n",(stop-start)*1000.0/freq);
+ }
+
+#endif
+ return 0;
+}
+
+
+DWORD GetTickCount(){
+ struct timeb now;
+ ftime(&now);
+ return now.time*1000+now.millitm;
+}
+
+
+int FindDevice(){
+#if !defined _WIN32 && !defined __CYGWIN__
+ struct hiddev_devinfo device_info;
+ int i;
+ if(path[0]==0){ //search all devices
+ 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){
+ printf(strings[S_noprog]);
+ return -1;
+ }
+ }
+ else{ //user supplied path
+ if ((fd = open(path, O_RDONLY )) < 0) {
+ printf(strings[S_DevPermission],path);
+ exit(1);
+ }
+ ioctl(fd, HIDIOCGDEVINFO, &device_info);
+ if(device_info.vendor!=vid||device_info.product!=pid){
+ printf(strings[S_noprog]);
+ return -1;
+ }
+ }
+ printf(strings[S_progDev],path);
+
+ 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;
+
+ if(info){
+ ioctl(fd, HIDIOCGDEVINFO, &device_info);
+ printf("vendor 0x%04hx product 0x%04hx version 0x%04hx ",
+ device_info.vendor, device_info.product, device_info.version);
+ printf("has %i application%s ", device_info.num_applications,
+ (device_info.num_applications==1?"":"s"));
+ printf("and is on bus: %d devnum: %d ifnum: %d\n",
+ device_info.busnum, device_info.devnum, device_info.ifnum);
+ char name[256]= "Unknown";
+ if(ioctl(fd, HIDIOCGNAME(sizeof(name)), name) < 0) perror("evdev ioctl");
+ printf("The device on %s says its name is %s\n", path, name);
+ }
+
+#else
+ char string[256];
+ PSP_DEVICE_INTERFACE_DETAIL_DATA detailData;
+ HANDLE DeviceHandle;
+ HANDLE hDevInfo;
+ GUID HidGuid;
+ int MyDeviceDetected;
+ 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;
+ //char UsageDescription[256];
+
+ 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){
+ printf("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 -1;
+
+
+ HMODULE hSAPI=0;
+ hSAPI = LoadLibrary("setupapi.dll");
+ if(!hSAPI){
+ printf("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 -1;
+
+
+ /*
+ 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 (MyDeviceDetected == FALSE){
+ printf("Can't find device\n");
+ return -1;
+ }
+
+ if(info){
+ printf("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
+ return 0;
+}
diff --git a/icd.c b/icd.c
new file mode 100644
index 0000000..3cf8e39
--- /dev/null
+++ b/icd.c
@@ -0,0 +1,1541 @@
+//General routines to communicate via ICD with a target
+#include "common.h"
+#include "coff.h"
+
+extern int saveLog;
+extern double Tcom;
+extern int running;
+extern int DeviceDetected;
+extern GtkWidget * b_log;
+extern char* cur_path;
+
+GtkWidget * statusTxt;
+GtkWidget * sourceTxt;
+GtkTextBuffer * sourceBuf;
+GtkWidget * icdVbox1;
+GtkWidget * icdMenuPC;
+GtkWidget * icdMenuSTAT;
+GtkWidget * icdMenuBank0;
+GtkWidget * icdMenuBank1;
+GtkWidget * icdMenuBank2;
+GtkWidget * icdMenuBank3;
+GtkWidget * icdMenuEE;
+GtkWidget * icdCommand;
+GtkTextBuffer * statusBuf;
+int icdTimer=0;
+int break_addr,print_addr;
+int currentSource=-1;
+int sourceHilight=0;
+char lastCmd[64]="";
+int UseCoff=0;
+struct src_i source_info[LMAX];
+struct srcfile *s_files;
+struct symbol *sym;
+int nsym=0;
+char* Slabel[LMAX],*Sulabel[ULMAX];
+struct symbol *watch;
+int nwatch=0;
+unsigned short coff_data[DATA_MAX];
+int ver=0,reset=1,freeze=0,icdConnected=0,running=0;
+#define Tck 30
+double Tcom=0.001*Tck*18+0.03; //communication time for a 16 bit tranfer (ms)
+
+void ShowContext();
+
+//The following commands are implemented in the debugger monitor
+//routine which is written in the last memory page on the target chip.
+#define VER 1 //;version
+#define STEP 2 //;step
+#define GO 3 //;go
+#define RREG 4 //;read register
+#define WREG 5 //;write register
+#define EEADR 0x10D
+#define EEADRH 0x10F
+#define EEDATA 0x10C
+#define EEDATH 0x10E
+#define EECON1 0x18C
+#define EECON2 0x18D
+#define w_temp 0x6B
+#define status_temp 0x6C
+#define pclath_temp 0x6D
+#define fsr_temp 0x6E
+
+struct var{ char* name; int display;} variables[0x200];
+
+//Prepare ICD interface by resetting the target with a power-up sequence.
+//MCLR is low so the target is reset even if power is not supplied by the programmer.
+//Set communication speed at 1/(2*Tck us)
+void startICD(int tck){
+ int j=0;
+ bufferU[j++]=PROG_RST;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T1T2;
+ bufferU[j++]=tck; //T1=XXu
+ bufferU[j++]=100; //T2=100u
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3; //2ms
+ bufferU[j++]=2000>>8;
+ bufferU[j++]=2000&0xff;
+ bufferU[j++]=VREG_DIS; //disable HV regulator
+ bufferU[j++]=EN_VPP_VCC; // reset target
+ bufferU[j++]=0x0;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x2; //set D as input
+ bufferU[j++]=EN_VPP_VCC; // power-up
+ bufferU[j++]=0x1;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(3);
+ if(saveLog){
+ fprintf(logfile,"startICD()\n");
+ }
+}
+
+//Check whether the target is running or is executing the debug routine.
+//This is signaled by RB7 (Data): D=1 -> debugger monitor running
+int isRunning(){
+ int z,j=0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0; //D=0
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x2; //set D as input
+ bufferU[j++]=READ_PINS;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ if(saveLog){
+ fprintf(logfile,"isRunning()\n");
+ }
+ for(z=0;z<DIMBUF-1&&bufferI[z]!=READ_PINS;z++);
+ if(bufferI[z+1]&1) running=0;
+ else running=1;
+ return running;
+}
+
+//Set the next breakpoint address, the freeze bit,
+//and continue execution.
+//This is necessary because at every break
+//the ICD register is loaded with the last address.
+void cont(int break_addr, int freeze){
+ int j=0;
+ //set breakpoint and freeze
+ break_addr&=0x1FFF;
+ bufferU[j++]=TX16;
+ bufferU[j++]=0x2;
+ bufferU[j++]=WREG; //write register
+ bufferU[j++]=(break_addr>>8)+(freeze?0x40:0);
+ bufferU[j++]=0x1;
+ bufferU[j++]=0x8E;
+ bufferU[j++]=TX16;
+ bufferU[j++]=0x2;
+ bufferU[j++]=WREG; //write register
+ bufferU[j++]=break_addr&0xFF;
+ bufferU[j++]=0x1;
+ bufferU[j++]=0x8F;
+ bufferU[j++]=TX16;
+ bufferU[j++]=0x1;
+ bufferU[j++]=GO; //GO
+ bufferU[j++]=0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x2; //set D as input
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(1+5*Tcom);
+ if(saveLog){
+ fprintf(logfile,"continue()\n");
+ }
+ running=1;
+}
+
+//Execute a single step
+void step(){
+ int j=0;
+ bufferU[j++]=TX16;
+ bufferU[j++]=0x1;
+ bufferU[j++]=STEP; //single step
+ bufferU[j++]=0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x2; //set D as input
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(1+Tcom);
+ if(saveLog){
+ fprintf(logfile,"step()\n");
+ }
+}
+
+//Remove reset so that the target can start executing its code.
+void run(){
+ int j=0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x2;
+ bufferU[j++]=EN_VPP_VCC; //MCLR=H
+ bufferU[j++]=0x5;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ if(saveLog){
+ fprintf(logfile,"run()\n");
+ }
+ running=1;
+}
+
+//Get the debugger monitor version
+int version(){
+ int j=0,z;
+ bufferU[j++]=TX16;
+ bufferU[j++]=0x1;
+ bufferU[j++]=VER; //version
+ bufferU[j++]=0;
+ bufferU[j++]=RX16;
+ bufferU[j++]=0x1;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(1+2*Tcom);
+ if(saveLog){
+ fprintf(logfile,"version()\n");
+ }
+ for(z=0;z<DIMBUF-2&&bufferI[z]!=RX16;z++);
+ return bufferI[z+3];
+}
+
+//Halt execution by setting RB6 (Clock) low
+void Halt(){
+ int j=0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x6;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x2; //set D as input
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ if(saveLog){
+ fprintf(logfile,"halt()\n");
+ }
+ running=0;
+ //printf("halted\n");
+}
+
+//Read register at address addr
+int ReadRegister(int addr){
+ int j=0,z;
+ bufferU[j++]=TX16;
+ bufferU[j++]=0x2;
+ bufferU[j++]=RREG; //Read register
+ bufferU[j++]=0x1; //1 byte
+ bufferU[j++]=(addr>>8)&0xFF;
+ bufferU[j++]=addr&0xFF;
+ bufferU[j++]=RX16;
+ bufferU[j++]=0x1;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x2; //set D as input
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(1+3*Tcom);
+ if(saveLog){
+ fprintf(logfile,"ReadRegister(0x%X)\n",addr);
+ }
+ for(z=0;z<DIMBUF-2&&bufferI[z]!=RX16;z++);
+ return bufferI[z+3];
+}
+
+//Read n registers starting at address addr
+int ReadRegisterN(int addr,int n,int* buf){
+ int i,j=0,z,w;
+ for(i=0;i<n;i+=w){
+ w=i+(DIMBUF-9)/2<n?(DIMBUF-9)/2:n-i;
+ bufferU[j++]=TX16;
+ bufferU[j++]=0x2;
+ bufferU[j++]=RREG; //Read register
+ bufferU[j++]=w;
+ bufferU[j++]=(addr+i)>>8;
+ bufferU[j++]=(addr+i)&0xFF;
+ bufferU[j++]=RX16;
+ bufferU[j++]=w;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(1+(w+2)*Tcom);
+ if(saveLog){
+ fprintf(logfile,"ReadRegisterN(0x%X,%d)\n",addr,n);
+ }
+ for(z=0;z<DIMBUF-2&&bufferI[z]!=RX16;z++);
+ for(j=0;j<w;j++) buf[i+j]=bufferI[z+3+j*2];
+ j=0;
+ }
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x2; //set D as input
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ return i==n?0:-1;
+}
+
+//Write data at address addr
+void WriteRegister(int addr,int data){
+ int j=0;
+ bufferU[j++]=TX16;
+ bufferU[j++]=0x2;
+ bufferU[j++]=WREG; //write register
+ bufferU[j++]=data&0xFF;
+ bufferU[j++]=(addr>>8)&0xFF;
+ bufferU[j++]=addr&0xFF;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x2; //set D as input
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(1+2*Tcom);
+ if(saveLog){
+ fprintf(logfile,"WriteRegister(0x%X,0x%X)\n",addr,data);
+ }
+}
+
+//Read program memory at address addr
+int ReadProgMem(int addr){
+ int addr_temp, data_temp, eecon_temp,data;
+ addr_temp=(ReadRegister(EEADRH)<<8)+ReadRegister(EEADR);
+ data_temp=(ReadRegister(EEDATH)<<8)+ReadRegister(EEDATA);
+ eecon_temp=ReadRegister(EECON1);
+ WriteRegister(EEADRH,addr>>8);
+ WriteRegister(EEADR,addr&0xFF);
+ WriteRegister(EECON1,eecon_temp|0x80); //EEPGD=1
+ WriteRegister(EECON1,eecon_temp|0x81); //EEPGD=1 + RD=1
+ data=(ReadRegister(EEDATH)<<8)+ReadRegister(EEDATA);
+ WriteRegister(EEADRH,addr_temp<<8);
+ WriteRegister(EEADR,addr_temp&0xFF);
+ WriteRegister(EEDATH,data_temp<<8);
+ WriteRegister(EEDATA,data_temp&0xFF);
+ WriteRegister(EECON1,eecon_temp);
+ return data;
+}
+
+//Read program memory (n locations) starting at address addr
+int ReadProgMemN(int addr,int n,int* buf){
+ int addr_temp, data_temp, eecon_temp;
+ if(saveLog) fprintf(logfile,"ReadProgMemN(0x%X,%d)\n",addr,n);
+ int i,j=0,z,w,k;
+ bufferU[j++]=TX16;
+ bufferU[j++]=2;
+ bufferU[j++]=RREG; //Read register
+ bufferU[j++]=4; //4 bytes: EEDATA,EEADR,EEDATH,EEADRH
+ bufferU[j++]=(EEDATA>>8)&0xFF;
+ bufferU[j++]=EEDATA&0xFF;
+ bufferU[j++]=RX16;
+ bufferU[j++]=4;
+ bufferU[j++]=TX16;
+ bufferU[j++]=2;
+ bufferU[j++]=RREG; //Read register
+ bufferU[j++]=1; //1 byte
+ bufferU[j++]=(EECON1>>8)&0xFF;
+ bufferU[j++]=EECON1&0xFF;
+ bufferU[j++]=RX16;
+ bufferU[j++]=1;
+ bufferU[j++]=TX16;
+ bufferU[j++]=2;
+ bufferU[j++]=WREG; //write register
+ bufferU[j++]=0x80; //EEPGD=1
+ bufferU[j++]=(EECON1>>8)&0xFF;
+ bufferU[j++]=EECON1&0xFF;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(1+13*Tcom);
+ j=0;
+ for(z=0;z<DIMBUF-5&&bufferI[z]!=RX16;z++);
+ data_temp=bufferI[z+3]+(bufferI[z+7]<<8);
+ addr_temp=bufferI[z+5]+(bufferI[z+9]<<8);
+ for(z+=10;z<DIMBUF-3&&bufferI[z]!=RX16;z++);
+ eecon_temp=bufferI[z+3];
+ w=k=0;
+ for(i=0;i<n;i++){
+ bufferU[j++]=TX16;
+ bufferU[j++]=8;
+ bufferU[j++]=WREG; //write register
+ bufferU[j++]=(addr+i)&0xFF;
+ bufferU[j++]=(EEADR>>8)&0xFF;
+ bufferU[j++]=EEADR&0xFF;
+ bufferU[j++]=WREG; //write register
+ bufferU[j++]=((addr+i)>>8)&0xFF;
+ bufferU[j++]=(EEADRH>>8)&0xFF;
+ bufferU[j++]=EEADRH&0xFF;
+ bufferU[j++]=WREG; //write register
+ bufferU[j++]=0x81; //RD=1
+ bufferU[j++]=(EECON1>>8)&0xFF;
+ bufferU[j++]=EECON1&0xFF;
+ bufferU[j++]=RREG; //Read register
+ bufferU[j++]=3; //3 bytes: EEDATA,EEADR,EEDATH
+ bufferU[j++]=(EEDATA>>8)&0xFF;
+ bufferU[j++]=EEDATA&0xFF;
+ bufferU[j++]=RX16;
+ bufferU[j++]=3;
+ w++;
+ if(j>DIMBUF-21||i==n-1){
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2+13*Tcom*w);
+ j=0;
+ w=0;
+ for(z=0;z<DIMBUF-5;z++){
+ if(bufferI[z]==RX16){
+ buf[k++]=bufferI[z+3]+(bufferI[z+7]<<8);
+ z+=8; //******controllare!!**********
+ }
+ }
+ }
+ }
+ bufferU[j++]=TX16;
+ bufferU[j++]=10;
+ bufferU[j++]=WREG; //write register
+ bufferU[j++]=eecon_temp; //EEPGD=1
+ bufferU[j++]=(EECON1>>8)&0xFF;
+ bufferU[j++]=EECON1&0xFF;
+ bufferU[j++]=WREG; //write register
+ bufferU[j++]=data_temp&0xFF;
+ bufferU[j++]=(EEDATA>>8)&0xFF;
+ bufferU[j++]=EEDATA&0xFF;
+ bufferU[j++]=WREG; //write register
+ bufferU[j++]=data_temp>>8;
+ bufferU[j++]=(EEDATH>>8)&0xFF;
+ bufferU[j++]=EEDATH&0xFF;
+ bufferU[j++]=WREG; //write register
+ bufferU[j++]=addr_temp&0xFF;
+ bufferU[j++]=(EEADR>>8)&0xFF;
+ bufferU[j++]=EEADR&0xFF;
+ bufferU[j++]=WREG; //write register
+ bufferU[j++]=addr_temp>>8;
+ bufferU[j++]=(EEADRH>>8)&0xFF;
+ bufferU[j++]=EEADRH&0xFF;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x2; //set D as input
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(1+10*Tcom);
+ return i;
+}
+
+//Read data memory at address addr
+int ReadDataMem(int addr){
+ int addr_temp, data_temp, eecon_temp,data;
+ addr_temp=ReadRegister(EEADR);
+ data_temp=ReadRegister(EEDATA);
+ eecon_temp=ReadRegister(EECON1);
+ WriteRegister(EEADR,addr);
+ WriteRegister(EECON1,eecon_temp&0x7F); //EEPGD=0
+ WriteRegister(EECON1,(eecon_temp&0x7F)|0x1); //EEPGD=0 + RD=1
+ data=ReadRegister(EEDATA);
+ WriteRegister(EEADR,addr_temp);
+ WriteRegister(EEDATA,data_temp);
+ WriteRegister(EECON1,eecon_temp);
+ return data;
+}
+
+//Read n bytes from data memory starting at address addr
+int ReadDataMemN(int addr,int n,unsigned char* buf){
+ int addr_temp, data_temp, eecon_temp;
+ if(saveLog) fprintf(logfile,"ReadDataMemN(0x%X,%d)\n",addr,n);
+ int i,j=0,z,w,k;
+ bufferU[j++]=TX16;
+ bufferU[j++]=2;
+ bufferU[j++]=RREG; //Read register
+ bufferU[j++]=2; //2 bytes: EEDATA,EEADR
+ bufferU[j++]=(EEDATA>>8)&0xFF;
+ bufferU[j++]=EEDATA&0xFF;
+ bufferU[j++]=RX16;
+ bufferU[j++]=2;
+ bufferU[j++]=TX16;
+ bufferU[j++]=2;
+ bufferU[j++]=RREG; //Read register
+ bufferU[j++]=1; //1 byte
+ bufferU[j++]=(EECON1>>8)&0xFF;
+ bufferU[j++]=EECON1&0xFF;
+ bufferU[j++]=RX16;
+ bufferU[j++]=1;
+ bufferU[j++]=TX16;
+ bufferU[j++]=2;
+ bufferU[j++]=WREG; //write register
+ bufferU[j++]=0; //EEPGD=0
+ bufferU[j++]=(EECON1>>8)&0xFF;
+ bufferU[j++]=EECON1&0xFF;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(1+13*Tcom);
+ j=0;
+ for(z=0;z<DIMBUF-5&&bufferI[z]!=RX16;z++);
+ data_temp=bufferI[z+3];
+ addr_temp=bufferI[z+5];
+ for(z+=6;z<DIMBUF-3&&bufferI[z]!=RX16;z++);
+ eecon_temp=bufferI[z+3];
+ w=k=0;
+ for(i=0;i<n;i++){
+ bufferU[j++]=TX16;
+ bufferU[j++]=6;
+ bufferU[j++]=WREG; //write register
+ bufferU[j++]=(addr+i)&0xFF;
+ bufferU[j++]=(EEADR>>8)&0xFF;
+ bufferU[j++]=EEADR&0xFF;
+ bufferU[j++]=WREG; //write register
+ bufferU[j++]=0x1; //RD=1
+ bufferU[j++]=(EECON1>>8)&0xFF;
+ bufferU[j++]=EECON1&0xFF;
+ bufferU[j++]=RREG; //Read register
+ bufferU[j++]=1; // EEDATA
+ bufferU[j++]=(EEDATA>>8)&0xFF;
+ bufferU[j++]=EEDATA&0xFF;
+ bufferU[j++]=RX16;
+ bufferU[j++]=1;
+ w++;
+ if(j>DIMBUF-17||i==n-1){
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2+10*Tcom*w);
+ j=0;
+ w=0;
+ for(z=0;z<DIMBUF-5;z++){
+ if(bufferI[z]==RX16){
+ buf[k++]=bufferI[z+3];
+ z+=4;
+ }
+ }
+ }
+ }
+ bufferU[j++]=TX16;
+ bufferU[j++]=6;
+ bufferU[j++]=WREG; //write register
+ bufferU[j++]=eecon_temp; //EEPGD=1
+ bufferU[j++]=(EECON1>>8)&0xFF;
+ bufferU[j++]=EECON1&0xFF;
+ bufferU[j++]=WREG; //write register
+ bufferU[j++]=data_temp&0xFF;
+ bufferU[j++]=(EEDATA>>8)&0xFF;
+ bufferU[j++]=EEDATA&0xFF;
+ bufferU[j++]=WREG; //write register
+ bufferU[j++]=addr_temp&0xFF;
+ bufferU[j++]=(EEADR>>8)&0xFF;
+ bufferU[j++]=EEADR&0xFF;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x2; //set D as input
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(1+10*Tcom);
+ return i;
+}
+
+// get register name from list
+char* getVar(int addr,char *var){
+ addr&=0x1FF;
+ if(variables[addr].name) strcpy(var,variables[addr].name);
+ else sprintf(var,"0x%03X",addr);
+ return var;
+}
+
+//Disassemble a command and return string
+//addrH is the higher (bank) address for memory (RP1-RP0)
+char* decodeCmd(int cmd,char *str, int addrH){
+ char ins[32],reg[32];
+ if((cmd&0x3F9F)==0) sprintf(str,"nop");
+ else if(cmd==0x0001) sprintf(str,"reset");
+ else if(cmd==0x0008) sprintf(str,"return");
+ else if(cmd==0x0009) sprintf(str,"retfie");
+ else if(cmd==0x000A) sprintf(str,"callw");
+ else if(cmd==0x000B) sprintf(str,"brw");
+ else if(cmd==0x0062) sprintf(str,"option");
+ else if(cmd==0x0063) sprintf(str,"sleep");
+ else if(cmd==0x0064) sprintf(str,"clrwdt");
+ else if(cmd==0x0065) sprintf(str,"trisa");
+ else if(cmd==0x0066) sprintf(str,"trisb");
+ else if(cmd==0x0067) sprintf(str,"trisc");
+ else if((cmd>>12)==0){ //byte oriented instructions
+ if((cmd>>8)==0&&cmd&0x80) sprintf(str,"movwf %s",getVar(addrH+(cmd&0x7F),reg));
+ else if((cmd>>8)==1){
+ if(cmd&0x80) sprintf(str,"clrf %s",getVar(addrH+(cmd&0x7F),reg));
+ else sprintf(str,"clrf w");
+ }
+ else{
+ switch(cmd>>8){
+ case 2:
+ sprintf(ins,"subwf");
+ break;
+ case 3:
+ sprintf(ins,"decf");
+ break;
+ case 4:
+ sprintf(ins,"iorwf");
+ break;
+ case 5:
+ sprintf(ins,"andwf");
+ break;
+ case 6:
+ sprintf(ins,"xorwf");
+ break;
+ case 7:
+ sprintf(ins,"addwf");
+ break;
+ case 8:
+ sprintf(ins,"movf");
+ break;
+ case 9:
+ sprintf(ins,"comf");
+ break;
+ case 10:
+ sprintf(ins,"incf");
+ break;
+ case 11:
+ sprintf(ins,"decfsz");
+ break;
+ case 12:
+ sprintf(ins,"rrf");
+ break;
+ case 13:
+ sprintf(ins,"rlf");
+ break;
+ case 14:
+ sprintf(ins,"swapf");
+ break;
+ case 15:
+ sprintf(ins,"incfsz");
+ break;
+ default:
+ sprintf(ins,"???");
+ break;
+ }
+ sprintf(str,"%s %s,%c",ins,getVar(addrH+(cmd&0x7F),reg),cmd&0x80?'f':'w');
+ }
+ }
+ else if((cmd>>12)==1){ //bit oriented instructions
+ switch(cmd>>10){
+ case 4:
+ sprintf(ins,"bcf");
+ break;
+ case 5:
+ sprintf(ins,"bsf");
+ break;
+ case 6:
+ sprintf(ins,"btfsc");
+ break;
+ case 7:
+ sprintf(ins,"btfss");
+ break;
+ default:
+ sprintf(ins,"??"); //(not possible)
+ }
+ sprintf(str,"%s %s,%d",ins,getVar(addrH+(cmd&0x7F),reg),(cmd&0x380)>>7);
+ }
+ else if((cmd>>12)==2) sprintf(str,"%s 0x%X",cmd&0x800?"goto":"call",cmd&0x7FF);
+ else if((cmd>>10)==0xC) sprintf(str,"movlw 0x%X",cmd&0xFF);
+ else if((cmd>>10)==0xD) sprintf(str,"retlw 0x%X",cmd&0xFF);
+ else if((cmd>>9)==0x1E) sprintf(str,"sublw 0x%X",cmd&0xFF);
+ else if((cmd>>9)==0x1F) sprintf(str,"addlw 0x%X",cmd&0xFF);
+ else if((cmd>>8)==0x38) sprintf(str,"iorlw 0x%X",cmd&0xFF);
+ else if((cmd>>8)==0x39) sprintf(str,"andlw 0x%X",cmd&0xFF);
+ else if((cmd>>8)==0x3A) sprintf(str,"xorlw 0x%X",cmd&0xFF);
+ else sprintf(str,"unknown command");
+ return str;
+}
+
+//Functions tied to GUI:
+///
+///Print a message on the ICD data field
+void PrintMessageICD(const char *msg){
+ GtkTextIter iter;
+ gtk_text_buffer_set_text(statusBuf,msg,-1);
+ gtk_text_buffer_get_start_iter(statusBuf,&iter);
+ gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(statusTxt),&iter,0.0,FALSE,0,0);
+ while (gtk_events_pending ()) gtk_main_iteration();
+}
+///
+///Append a message on the ICD data field
+void AppendMessageICD(const char *msg){
+ GtkTextIter iter;
+ gtk_text_buffer_get_end_iter(statusBuf,&iter);
+ gtk_text_buffer_insert(statusBuf,&iter,msg,-1);
+ gtk_text_buffer_get_start_iter(statusBuf,&iter);
+ gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(statusTxt),&iter,0.0,FALSE,0,0);
+ while (gtk_events_pending ()) gtk_main_iteration();
+}
+///
+///Scroll source file
+void scrollToLine(int line)
+{
+ GtkTextIter iter,iter2;
+ gtk_text_buffer_get_end_iter(sourceBuf,&iter);
+ if(line>0){
+ gtk_text_iter_set_line(&iter,line-1);
+ iter2=iter;
+ gtk_text_iter_forward_char(&iter2);
+ gtk_text_iter_forward_to_line_end(&iter2);
+ }
+ else{
+ gtk_text_buffer_get_selection_bounds(sourceBuf,&iter,&iter2);
+ iter2=iter;
+ }
+ gtk_text_buffer_select_range(sourceBuf,&iter,&iter2);
+ while (gtk_events_pending ()) gtk_main_iteration();
+ gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(sourceTxt),&iter,0.0,TRUE,0,0.5);
+}
+///
+///Hilight line in source code
+void SourceHilightLine(int line)
+{
+ GtkTextIter iter,iter2;
+ GtkTextTag* tag;
+ if(line>0){
+ tag=gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(sourceBuf),"break_text");
+ if(!tag) tag=gtk_text_buffer_create_tag(sourceBuf,"break_text","background","red", NULL);
+ gtk_text_buffer_get_end_iter(sourceBuf,&iter);
+ gtk_text_iter_set_line(&iter,line-1);
+ iter2=iter;
+ gtk_text_iter_forward_char(&iter2);
+ gtk_text_iter_forward_to_line_end(&iter2);
+ gtk_text_buffer_apply_tag (sourceBuf,tag,&iter,&iter2);
+ }
+ while (gtk_events_pending ()) gtk_main_iteration();
+}
+///
+///Remove hilight line in source code
+void SourceRemoveHilightLine(int line)
+{
+ GtkTextIter iter,iter2;
+ if(line>0){
+ gtk_text_buffer_get_end_iter(sourceBuf,&iter);
+ gtk_text_iter_set_line(&iter,line-1);
+ iter2=iter;
+ gtk_text_iter_forward_char(&iter2);
+ gtk_text_iter_forward_to_line_end(&iter2);
+ gtk_text_buffer_remove_tag_by_name(sourceBuf,"break_text",&iter,&iter2);
+ }
+ while (gtk_events_pending ()) gtk_main_iteration();
+}
+///
+///load source file into source pane
+int loadSource(FILE *f){
+ if(!f) return 0;
+ fseek(f,0,SEEK_END);
+ int size=ftell(f);
+ fseek(f,0,SEEK_SET);
+ char* tmp=(char*)malloc(size+1);
+ size=fread(tmp,1,size,f);
+ tmp[size]=0;
+ char* g=g_locale_to_utf8(tmp,-1,NULL,NULL,NULL);
+ gtk_text_buffer_set_text(sourceBuf,g,-1);
+ free(tmp);
+ g_free(g);
+ return 1;
+}
+///
+///load and analyze coff file
+void loadCoff(GtkWidget *widget,GtkWidget *window)
+{
+ GtkFileChooser *dialog;
+ dialog = (GtkFileChooser*) gtk_file_chooser_dialog_new (strings[I_LOAD_COFF], //"Open Coff 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);
+ UseCoff=analyzeCOFF(filename,Slabel,Sulabel,source_info,&s_files,coff_data,&sym,&nsym);
+ g_free (filename);
+ //load source for address 0
+ if(source_info[0].src_file!=-1){
+ if(currentSource==source_info[0].src_file){
+ scrollToLine(source_info[0].src_line);
+ }
+ else if(loadSource(s_files[source_info[0].src_file].ptr)){
+ scrollToLine(source_info[0].src_line);
+ currentSource=source_info[0].src_file;
+ }
+ }
+ }
+ gtk_widget_destroy (GTK_WIDGET(dialog));
+}
+///
+/// List of variables used when decoding an assembly word
+void initVar(){
+ int i;
+ for(i=0;i<0x200;i++){//clear variable list
+ variables[i].name=0;
+ variables[i].display=0;
+ }
+ variables[0].name="INDF";
+ variables[1].name="TMR0";
+ variables[2].name="PCL";
+ variables[3].name="STATUS";
+ variables[4].name="FSR";
+ variables[5].name="PORTA";
+ variables[6].name="PORTB";
+ variables[7].name="PORTC";
+ variables[8].name="PORTD";
+ variables[9].name="PORTE";
+ variables[10].name="PCLATH";
+ variables[11].name="INTCON";
+ variables[12].name="PIR1";
+ variables[13].name="PIR2";
+ variables[14].name="TMR1L";
+ variables[15].name="TMR1H";
+ variables[16].name="T1CON";
+ variables[17].name="TMR2";
+ variables[18].name="T2CON";
+ variables[19].name="SSPBUF";
+ variables[20].name="SSPCON";
+ variables[21].name="CCPR1L";
+ variables[22].name="CCPR1H";
+ variables[23].name="CCP1CON";
+ variables[24].name="RCSTA";
+ variables[25].name="TXREG";
+ variables[26].name="RCREG";
+ variables[27].name="CCPR2L";
+ variables[28].name="CCPR2H";
+ variables[29].name="CCP2CON";
+ variables[30].name="ADRESH";
+ variables[31].name="ADCON0";
+ variables[0x6B].name="DEBUG_VAR1";
+ variables[0x6C].name="DEBUG_VAR2";
+ variables[0x6D].name="DEBUG_VAR3";
+ variables[0x6E].name="DEBUG_VAR4";
+ variables[0x6F].name="DEBUG_VAR5";
+ variables[0x70].name="DEBUG_VAR6";
+ variables[0x71].name="DEBUG_VAR7";
+ variables[0x72].name="DEBUG_VAR8";
+ variables[0x80].name="INDF";
+ variables[0x81].name="OPTION_REG";
+ variables[0x82].name="PCL";
+ variables[0x83].name="STATUS";
+ variables[0x84].name="FSR";
+ variables[0x85].name="TRISA";
+ variables[0x86].name="TRISB";
+ variables[0x87].name="TRISC";
+ variables[0x88].name="TRISD";
+ variables[0x89].name="TRISE";
+ variables[0x8A].name="PCLATH";
+ variables[0x8B].name="INTCON";
+ variables[0x8C].name="PIE1";
+ variables[0x8D].name="PIE2";
+ variables[0x8E].name="PCON";
+ variables[0x91].name="SSPCON2";
+ variables[0x92].name="PR2";
+ variables[0x93].name="SSPADD";
+ variables[0x94].name="SSPSTAT";
+ variables[0x98].name="TXSTA";
+ variables[0x99].name="SPBRG";
+ variables[0x9E].name="ADRESL";
+ variables[0x9F].name="ADCON1";
+ variables[0x100].name="INDF";
+ variables[0x101].name="TMR0";
+ variables[0x102].name="PCL";
+ variables[0x103].name="STATUS";
+ variables[0x104].name="FSR";
+ variables[0x106].name="PORTB";
+ variables[0x10A].name="PCLATH";
+ variables[0x10B].name="INTCON";
+ variables[0x10C].name="EEDATA";
+ variables[0x10D].name="EEADR";
+ variables[0x10E].name="EEDATH";
+ variables[0x10F].name="EEADRH";
+ variables[0x180].name="INDF";
+ variables[0x181].name="OPTION_REG";
+ variables[0x182].name="PCL";
+ variables[0x183].name="STATUS";
+ variables[0x184].name="FSR";
+ variables[0x186].name="TRISB";
+ variables[0x18A].name="PCLATH";
+ variables[0x18B].name="INTCON";
+ variables[0x18C].name="EECON1";
+ variables[0x18D].name="EECON2";
+}
+///
+///Show ICD help window
+void ICDHelp(GtkWidget *widget,GtkWidget *window)
+{
+ GtkWidget* dialog = gtk_message_dialog_new (GTK_WINDOW(window),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_INFO,
+ GTK_BUTTONS_CLOSE,
+ strings[I_ICD_HELP_TXT]);
+
+ g_signal_connect_swapped (GTK_WINDOW(dialog), "response",G_CALLBACK (gtk_widget_destroy),dialog);
+ gtk_window_set_title(GTK_WINDOW(dialog),strings[I_ICD_HELP]);
+ gtk_widget_show_all (dialog);
+}
+///
+///ICD: check if program is running
+void icdCheck(GtkWidget *widget,GtkWidget *window)
+{
+#ifndef DEBUG
+ if(DeviceDetected!=1) return;
+#endif
+ if(!isRunning()){
+ g_source_remove(icdTimer);
+ ShowContext();
+ }
+}
+///
+///ICD: run program
+void icdRun(GtkWidget *widget,GtkWidget *window)
+{
+#ifndef DEBUG
+ if(DeviceDetected!=1) return;
+#endif
+ if(!icdConnected){
+ saveLog = (int) gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_log));
+ if(saveLog){
+ OpenLogFile(); //"Log.txt"
+ fprintf(logfile,"ICD start\n");
+ }
+ startICD(Tck); //start ICD mode by supplying the target and forcing a reset
+ run(); //remove reset
+ icdConnected=1;
+ icdTimer=g_timeout_add(20,(GSourceFunc)icdCheck,NULL);
+ PrintMessageICD("running");
+ }
+ else if(!running){
+ cont(break_addr,freeze); //continue execution
+ icdTimer=g_timeout_add(20,(GSourceFunc)icdCheck,NULL);
+ PrintMessageICD("running");
+ }
+}
+///
+///ICD: halt program
+void icdHalt(GtkWidget *widget,GtkWidget *window)
+{
+#ifndef DEBUG
+ if(DeviceDetected!=1) return;
+#endif
+ if(running){
+ g_source_remove(icdTimer);
+ Halt();
+ ShowContext();
+ }
+}
+///
+///ICD: step program
+void icdStep(GtkWidget *widget,GtkWidget *window)
+{
+#ifndef DEBUG
+ if(DeviceDetected!=1) return;
+#endif
+ if(running){
+ g_source_remove(icdTimer);
+ Halt();
+ }
+ step();
+#ifdef DEBUG
+ addrDebug++;
+#endif
+ ShowContext();
+}
+///
+///ICD: step program jumping over calls
+void icdStepOver(GtkWidget *widget,GtkWidget *window)
+{
+#ifndef DEBUG
+ if(DeviceDetected!=1) return;
+#endif
+ int addr,data;
+ if(running){
+ g_source_remove(icdTimer);
+ Halt();
+ }
+ addr=((ReadRegister(0x18E)&0x1F)<<8)+ReadRegister(0x18F);
+ data=ReadProgMem(addr);
+ if((data>>11)==4){ //if call break at return address
+ cont(addr+1,freeze);
+ icdTimer=g_timeout_add(20,(GSourceFunc)icdCheck,NULL);
+ }
+ else{ //normal step
+ step();
+ #ifdef DEBUG
+ addrDebug++;
+ #endif
+ ShowContext();
+ }
+}
+///
+///ICD: stop program
+void icdStop(GtkWidget *widget,GtkWidget *window)
+{
+#ifndef DEBUG
+ if(DeviceDetected!=1) return;
+#endif
+ if(running){
+ g_source_remove(icdTimer);
+ Halt();
+ }
+// bufferU[0]=0;
+ int j=0;
+ bufferU[j++]=EN_VPP_VCC; // reset target
+ bufferU[j++]=0x0;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x2; //set D as input
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(3);
+ if(saveLog)WriteLogIO();
+ icdConnected=0;
+ PrintMessageICD("stopped");
+ scrollToLine(source_info[0].src_line);
+}
+///
+///ICD: refresh status
+void icdRefresh(GtkWidget *widget,GtkWidget *window)
+{
+#ifndef DEBUG
+ if(DeviceDetected!=1) return;
+#endif
+ if(!running){
+ ShowContext();
+ }
+}
+///
+/// Read and display an entire bank of memory
+void ShowBank(int bank,char* status){
+ if(bank>3) bank=3;
+ if(bank<0) bank=0;
+ int b[128];
+ char temp[128];
+ int i;
+ sprintf(temp,"bank %d:",bank);
+ strcat(status,temp);
+ ReadRegisterN(bank*0x80,128,b);
+ for(i=0;i<128;i++){
+ if(i%16==0){
+ sprintf(temp,"\n0x%03X:",i+bank*0x80);
+ strcat(status,temp);
+ }
+ sprintf(temp,"%02X",b[i]);
+ strcat(status,temp);
+ }
+ strcat(status,"\n");
+}
+///
+/// Main ICD show function:
+/// prints status info according to selected options
+/// and the value of variables in the watch list
+void ShowContext(){
+ int i,addr,data,s;
+ char cmd[32]="";
+ char status[4096]="",temp[128];
+ addr=((ReadRegister(0x18E)&0x1F)<<8)+ReadRegister(0x18F);
+ data=ReadProgMem(addr);
+ s=ReadRegister(status_temp);
+ s=(s>>4)+((s<<4)&0xF0); //STATUS is swapped
+// printf("addr %X, status %X, data %X\n",addr,s,data);
+#ifdef DEBUG
+ addr=addrDebug;
+ s=statusDebug;
+ if(UseCoff) data=coff_data[addr];
+#endif
+ if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(icdMenuPC))){
+ sprintf(temp,"%s: %s (0x%04X) \nPC=0x%04X\n",strings[S_NextIns],decodeCmd(data,cmd,(s&0x60)<<2),data,addr); //"Next instruction"
+ strcat(status,temp);
+ }
+ if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(icdMenuSTAT))){
+ sprintf(temp,"STATUS=0x%02X (",s);
+ strcat(status,temp);
+ sprintf(temp,"%s ",s&0x80?"IRP":" ");
+ strcat(status,temp);
+ sprintf(temp,"%s ",s&0x40?"RP1":" ");
+ strcat(status,temp);
+ sprintf(temp,"%s ",s&0x20?"RP0":" ");
+ strcat(status,temp);
+ sprintf(temp,"%s ",s&0x10?"TO":" ");
+ strcat(status,temp);
+ sprintf(temp,"%s ",s&0x8?"PD":" ");
+ strcat(status,temp);
+ sprintf(temp,"%s ",s&0x4?"Z":" ");
+ strcat(status,temp);
+ sprintf(temp,"%s ",s&0x2?"DC":" ");
+ strcat(status,temp);
+ sprintf(temp,"%s)\n",s&0x1?"C":" ");
+ strcat(status,temp);
+ sprintf(temp,"W=0x%02X PCLATH=0x%02X FSR=0x%02X\n",ReadRegister(w_temp),ReadRegister(pclath_temp),ReadRegister(fsr_temp));
+ strcat(status,temp);
+ }
+ if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(icdMenuBank0))) ShowBank(0,status);
+ if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(icdMenuBank1))) ShowBank(1,status);
+ if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(icdMenuBank2))) ShowBank(2,status);
+ if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(icdMenuBank3))) ShowBank(3,status);
+ int rawsource=0;
+ if(UseCoff){ //hilight corresponding source line
+ if(data!=coff_data[addr]){
+ sprintf(temp,"code at address 0x%04X (0x%04X) is different than what specified in coff file (0x%04X)\n",addr,data,coff_data[addr]);
+ strcat(status,temp);
+ rawsource=1;
+ }
+#ifndef DEBUG
+ else{
+#endif
+// printf("addr %d, file %d, line %d, current %d, ptr %X\n",addr,source_info[addr].src_file,source_info[addr].src_line,currentSource,s_files[source_info[addr].src_file].ptr);
+ if(source_info[addr].src_file!=-1){
+ if(currentSource==source_info[addr].src_file) scrollToLine(source_info[addr].src_line);
+ else if(loadSource(s_files[source_info[addr].src_file].ptr)){
+ scrollToLine(source_info[addr].src_line);
+ currentSource=source_info[addr].src_file;
+ }
+ else rawsource=1;
+ }
+ else rawsource=1;
+#ifndef DEBUG
+ }
+#endif
+ }
+ if(!UseCoff || rawsource==1){ //show raw source if no source file is available
+ #define LINES_BEFORE 5
+ #define LINES_AFTER 7
+ #define NLINES LINES_BEFORE + LINES_AFTER
+ int addr0,addr1,line_pc=0;
+ char tmp[64*NLINES],t2[64];
+ tmp[0]=0;
+ int progmem[NLINES];
+ addr0=addr-LINES_BEFORE<0?0:addr-LINES_BEFORE;
+ addr1=addr+LINES_AFTER>0x1FFF?0x1FFF:addr+LINES_AFTER;
+ ReadProgMemN(addr0,addr1-addr0,progmem);
+ for(i=addr0;i<addr1;i++){
+ sprintf(t2,"0x%04X: %s (0x%04X)\n",i,decodeCmd(progmem[i-addr0],cmd,(s&0x60)<<2),progmem[i-addr0]);
+ strcat(tmp,t2);
+ if(i==addr) line_pc=i;
+ }
+ gtk_text_buffer_set_text(sourceBuf,tmp,-1);
+ currentSource=-1;
+ scrollToLine(line_pc-addr0+1);
+ }
+ for(i=0;i<nwatch;i++){
+ sprintf(temp,"%s=0x%02X\n",watch[i].name,ReadRegister(watch[i].value));
+ strcat(status,temp);
+ }
+ PrintMessageICD(status);
+ if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(icdMenuEE))){
+ unsigned char data[256];
+ str[0]=0;
+ char s[64],t[9],*g;
+ t[8]=0;
+ ReadDataMemN(0,256,data);
+ strcat(str,"EEPROM:\n");
+ for(i=0;i<0x100;i++){
+ if(i%8==0){
+ sprintf(s,"\n0x%02X: ",i);
+ strcat(str,s);
+ }
+ sprintf(s,"%02X ",data[i]);
+ strcat(str,s);
+ t[i&0x7]=isprint(data[i])?data[i]:'.';
+ if(i%8==7){
+ g=g_locale_to_utf8(t,-1,NULL,NULL,NULL);
+ if(g) strcat(str,g);
+ g_free(g);
+ }
+ }
+ AppendMessageICD(str);
+ }
+}
+///
+///Add symbol to the list of watched variables
+int addWatch(struct symbol s){
+ int i;
+ for(i=0;i<nwatch&&strcmp(watch[i].name,s.name);i++);
+ if(i<nwatch){ //remove watch
+ for(;i<nwatch-1;i++){
+ watch[i].name=watch[i+1].name;
+ watch[i].value=watch[i+1].value;
+ }
+ nwatch--;
+ watch=realloc(watch,nwatch*sizeof(struct symbol));
+ }
+ else{ //add watch
+ nwatch++;
+ watch=realloc(watch,nwatch*sizeof(struct symbol));
+ watch[nwatch-1].name=s.name;
+ watch[nwatch-1].value=s.value;
+ return 1;
+ }
+ return 0;
+}
+///
+/// ICD Command parser
+int executeCommand(char *command){
+//******************* break ********************************
+ if(strstr(command,"break")){
+ if(sscanf(command,"break %x",&break_addr)==1){
+ if(running) Halt();
+ break_addr&=0x1FFF;
+ sprintf(str,"break at address 0x%04X\n",break_addr);
+ AppendMessageICD(str);
+ SourceRemoveHilightLine(sourceHilight);
+ SourceHilightLine(source_info[break_addr].src_line);
+ sourceHilight=source_info[break_addr].src_line;
+ }
+ }
+//******************* clear ********************************
+ if(strstr(command,"clear")){
+ PrintMessageICD("");
+ }
+//******************* freeze ********************************
+ else if(strstr(command,"freeze")){
+ char option[32];
+ if(sscanf(command,"freeze %s",option)==1){
+ if(running) Halt();
+ if(!strcmp(option,"on")) freeze=1;
+ if(!strcmp(option,"off")) freeze=0;
+ WriteRegister(0x18E,(break_addr>>8)+(freeze?0x40:0));
+ }
+ sprintf(str,"peripheral freeze is %s\n",freeze?"on":"off");
+ AppendMessageICD(str);
+ }
+//******************* halt ********************************
+ else if(!strcmp(command,"h")||!strcmp(command,"halt")){
+ icdHalt(NULL,NULL);
+ }
+//******************* help ********************************
+ else if(!strcmp(command,"help")){
+ ICDHelp(NULL,NULL);
+ }
+//******************* list ********************************
+ else if(strstr(command,"list ")){
+ #define LISTLINES 10
+ int addr,i;
+ char tmp[32*LISTLINES],t2[32],cmd[32]="";
+ tmp[0]=0;
+ int progmem[LISTLINES];
+ if(sscanf(command,"list %x",&addr)==1){
+ addr&=0x1FFF;
+ ReadProgMemN(addr,LISTLINES,progmem);
+ for(i=0;i<LISTLINES;i++){
+ sprintf(t2,"0x%04X: %s (0x%04X)\n",i+addr,decodeCmd(progmem[i],cmd,0),progmem[i]);
+ strcat(tmp,t2);
+ }
+ //printf(tmp);
+ AppendMessageICD(tmp);
+ }
+ }
+//******************* print ********************************
+ else if(strstr(command,"print ")||strstr(command,"p ")){
+ int bank,i,addr,data;
+ char var[128];
+ if(strstr(command,"print p")||strstr(command,"p p")){ //program memory
+ int addr;
+ if(sscanf(command,"print p %x",&addr)==1||sscanf(command,"p p %x",&addr)==1){
+ addr&=0x1FFF;
+ if(running) Halt();
+ data=ReadProgMem(addr);
+ sprintf(str,"0x%04X: %s (0x%04X)\n",addr,decodeCmd(data,var,0x1000),data);
+ AppendMessageICD(str);
+ }
+ }
+ else if(!strcmp(command,"print ee")||!strcmp(command,"p ee")){ //eeprom
+ unsigned char data[256];
+ str[0]=0;
+ char s[64],t[9],*g;
+ t[8]=0;
+ if(running) Halt();
+ ReadDataMemN(0,256,data);
+ sprintf(str,"EEPROM:\n");
+ for(i=0;i<0x100;i++){
+ if(i%8==0){
+ sprintf(s,"\n0x%02X: ",i);
+ strcat(str,s);
+ }
+ sprintf(s,"%02X ",data[i]);
+ strcat(str,s);
+ t[i&0x7]=isprint(data[i])?data[i]:'.';
+ if(i%8==7){
+ g=g_locale_to_utf8(t,-1,NULL,NULL,NULL);
+ if(g) strcat(str,g);
+ g_free(g);
+ }
+ }
+ strcat(str,"\n");
+ //printf("EEPROM:\n");fflush(stdout);
+ AppendMessageICD(str);
+ }
+ else if(sscanf(command,"print ee %x",&addr)==1||sscanf(command,"p ee %x",&addr)==1){ //single EE address
+ addr&=0xFF;
+ if(running) Halt();
+ data=ReadDataMem(addr);
+ sprintf(str,"eeprom memory at 0x%02X=0x%02X (%c)\n",addr,data,isprint(data)?data:'.');
+ AppendMessageICD(str);
+ }
+ else if(sscanf(command,"print bank %x",&bank)==1||sscanf(command,"p bank %x",&bank)==1){ //memory bank
+ str[0]=0;
+ bank&=0x1FF;
+ if(bank>3) bank/=0x80;
+ if(running) Halt();
+ ShowBank(bank,str);
+ AppendMessageICD(str);
+ }
+ else if(sscanf(command,"print 0x%x",&print_addr)==1||sscanf(command,"p 0x%x",&print_addr)==1){ //mem address
+ print_addr&=0x1FF;
+ if(running) Halt();
+ sprintf(str,"[0x%03X]=0x%02X\n",print_addr,ReadRegister(print_addr));
+ AppendMessageICD(str);
+ }
+ else if(sscanf(command,"print %s",var)==1||sscanf(command,"p %s",var)==1){ //var name
+ str[0]=0;
+ if(running) Halt();
+ if(!strcmp("W",var)||!strcmp("w",var)) sprintf(str,"W = 0x%02X\n",ReadRegister(w_temp));
+ else if(!strcmp("STATUS",var)) sprintf(str,"0x003: STATUS = 0x%02X\n",ReadRegister(status_temp));
+ else if(!strcmp("FSR",var)) sprintf(str,"0x004: FSR = 0x%02X\n",ReadRegister(fsr_temp));
+ else if(!strcmp("PCLATH",var)) sprintf(str,"0x00A: PCLATH = 0x%02X\n",ReadRegister(pclath_temp));
+ else{
+ for(i=0;i<nsym&&strcmp(var,sym[i].name);i++);
+ if(i<nsym){
+ sprintf(str,"0x%03X: %s = 0x%02X\n",sym[i].value,sym[i].name,ReadRegister(sym[i].value));
+ }
+ else{ //look in standard variables
+ for(i=0;i<0x200;i++){
+ if(variables[i].name&&!strcmp(var,variables[i].name)){
+ sprintf(str,"0x%03X: %s = 0x%02X\n",i,variables[i].name,ReadRegister(i));
+ i=0x200;
+ }
+ }
+ }
+ }
+ AppendMessageICD(str);
+ }
+ }
+//******************* run ********************************
+ else if(!strcmp(command,"r")||!strcmp(command,"run")){
+ icdRun(NULL,NULL);
+ }
+//******************* step ********************************
+ else if(!strcmp(command,"s")||!strcmp(command,"step")||strstr(command,"step")||strstr(command,"s ")){
+ int i,n=1;
+ sscanf(command,"step %d",&n);
+ sscanf(command,"s %d",&n);
+#ifdef DEBUG
+ addrDebug+=n;
+#endif
+ if(running) Halt();
+ for(i=0;i<n;i++) step();
+ if(n>1)sprintf(str,"step %d\n",n);
+ else str[0]=0;
+ ShowContext();
+ AppendMessageICD(str);
+ }
+//******************* step over ********************************
+ else if(!strcmp(command,"ss")||!strcmp(command,"step over")||strstr(command,"step over ")||strstr(command,"ss ")){
+ int i,n=1;
+ sscanf(command,"step over %d",&n);
+ sscanf(command,"ss %d",&n);
+#ifdef DEBUG
+ addrDebug+=n;
+#endif
+ for(i=0;i<n;i++) icdStepOver(NULL,NULL);
+ if(n>1)sprintf(str,"step over %d\n",n);
+ AppendMessageICD(str);
+ }
+//******************* version ********************************
+ else if(!strcmp(command,"ver")||!strcmp(command,"version")){
+ if(running) Halt();
+ sprintf(str,"debugger version: %.1f\n",version()/10.0);
+ AppendMessageICD(str);
+ }
+//******************* watch ********************************
+ else if(strstr(command,"watch ")||strstr(command,"w ")){
+ int i,var_addr;
+ char var[64];
+ if(sscanf(command,"watch 0x%x",&var_addr)||sscanf(command,"w 0x%x",&var_addr)){
+ struct symbol s;
+ sprintf(var,"[0x%X]",var_addr);
+ s.name=strdup(var);
+ s.value=var_addr;
+ addWatch(s);
+ if(!running) ShowContext();
+ }
+ else if(sscanf(command,"watch %s",var)||sscanf(command,"w %s",var)){
+ for(i=0;i<nsym&&strcmp(var,sym[i].name);i++);
+ if(i<nsym){
+ addWatch(sym[i]);
+ if(!running) ShowContext();
+ }
+ else{ //look in standard variables
+ for(i=0;i<0x200;i++){
+ if(variables[i].name&&!strcmp(var,variables[i].name)){
+ struct symbol s;
+ s.name=variables[i].name;
+ s.value=i;
+ addWatch(s);
+ if(!running) ShowContext();
+ i=0x200;
+ }
+ }
+ }
+ }
+ }
+//******************* set variable ********************************
+//to do: special addresses (PC, status ecc)
+ else{
+ char var[64],*p;
+ int data,i,addr=-1;
+ if((p=strchr(command,'='))){
+ *p=0;
+ if(sscanf(command,"[%x]",&addr)&&sscanf(p+1,"%x",&data)){
+ if(running) Halt();
+ WriteRegister(addr,data);
+ ShowContext();
+ sprintf(str,"[0x%x]=0x%02X\n",addr,data);
+ AppendMessageICD(str);
+ }
+ else if(sscanf(command,"%s",var)&&sscanf(p+1,"%x",&data)){
+ for(i=0;i<nsym&&strcmp(var,sym[i].name);i++);
+ if(i<nsym&&sym[i].value<0x400){
+ addr=sym[i].value;
+ }
+ else{ //look in standard variables
+ for(i=0;i<0x200;i++){
+ if(variables[i].name&&!strcmp(var,variables[i].name)){
+ addr=i;
+ i=0x200;
+ }
+ }
+ }
+ if(addr!=-1){
+ if(running) Halt();
+ WriteRegister(addr,data);
+ ShowContext();
+ sprintf(str,"%s=0x%02X\n",var,data);
+ AppendMessageICD(str);
+ }
+ }
+ }
+ else return 0;
+ }
+ return 1;
+}
+///
+///Remove variable from watch list
+int removeWatch(char* name){
+ int i;
+ for(i=0;i<nwatch&&strcmp(watch[i].name,name);i++);
+ if(i<nwatch){ //remove watch
+ for(;i<nwatch-1;i++){
+ watch[i].name=watch[i+1].name;
+ watch[i].value=watch[i+1].value;
+ }
+ nwatch--;
+ watch=realloc(watch,nwatch*sizeof(struct symbol));
+ return 1;
+ }
+ return 0;
+}
+///
+///Handle mouse events in source code window
+gint source_mouse_event(GtkWidget *widget, GdkEventButton *event, gpointer func_data)
+{
+ if(GTK_IS_TEXT_VIEW(widget)&&event->type==GDK_2BUTTON_PRESS){
+ gint x,y,i;
+ GtkTextIter iter,iter2,itx;
+ gtk_text_view_window_to_buffer_coords(GTK_TEXT_VIEW(widget),GTK_TEXT_WINDOW_WIDGET,event->x,event->y,&x,&y);
+ gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(widget),&iter,x,y);
+// printf("x %d y %d\n",x,y);
+ iter2=iter;
+ char c;
+ for(itx=iter2,c=gtk_text_iter_get_char(&itx);isalnum(c)||c=='_';iter2=itx){
+ gtk_text_iter_forward_char(&itx);
+ c=gtk_text_iter_get_char(&itx);
+ }
+ for(itx=iter,c=gtk_text_iter_get_char(&itx);isalnum(c)||c=='_';iter=itx){
+ gtk_text_iter_backward_char(&itx);
+ c=gtk_text_iter_get_char(&itx);
+ }
+ gtk_text_iter_forward_char(&iter);
+ char* selection=gtk_text_buffer_get_text(sourceBuf,&iter,&iter2,FALSE);
+ for(i=0;i<nsym&&strcmp(selection,sym[i].name);i++);
+ if(i<nsym){
+ addWatch(sym[i]);
+ ShowContext();
+ }
+ else{ //set breakpoint
+ int line=gtk_text_iter_get_line(&iter)+1;
+ for(i=0;i<LMAX;i++) if(source_info[i].src_line==line){
+ //if(UseCoff && i>0 && (coff_data[i-1]>>11)!=4) i--; //if not a call break at previous address;
+ break_addr=i;
+ sprintf(str,"break at address 0x%x\n",i);
+ AppendMessageICD(str);
+ SourceRemoveHilightLine(sourceHilight);
+ SourceHilightLine(line);
+ sourceHilight=line;
+ break;
+ }
+ }
+ }
+ return FALSE;
+}
+///
+///Handle mouse events in ICD status window
+gint icdStatus_mouse_event(GtkWidget *widget, GdkEventButton *event, gpointer func_data)
+{
+ if(GTK_IS_TEXT_VIEW(widget)&&event->type==GDK_2BUTTON_PRESS){
+ gint x,y;
+ GtkTextIter iter,iter2,itx;
+ gtk_text_view_window_to_buffer_coords(GTK_TEXT_VIEW(widget),GTK_TEXT_WINDOW_WIDGET,event->x,event->y,&x,&y);
+ gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW(widget),&iter,x,y);
+ iter2=iter;
+ char c;
+ for(itx=iter2,c=gtk_text_iter_get_char(&itx);isalnum(c)||c=='_';iter2=itx){
+ gtk_text_iter_forward_char(&itx);
+ c=gtk_text_iter_get_char(&itx);
+ }
+ for(itx=iter,c=gtk_text_iter_get_char(&itx);isalnum(c)||c=='_';iter=itx){
+ gtk_text_iter_backward_char(&itx);
+ c=gtk_text_iter_get_char(&itx);
+ }
+ gtk_text_iter_forward_char(&iter);
+ char* selection=gtk_text_buffer_get_text(statusBuf,&iter,&iter2,FALSE);
+ if(removeWatch(selection)) ShowContext();
+ }
+ return FALSE;
+}
+///
+///Handle keyboard events in ICD command edit box
+gint icdCommand_key_event(GtkWidget *widget, GdkEventButton *event, gpointer func_data)
+{
+ if(event->type==GDK_KEY_PRESS&&((GdkEventKey*)event)->keyval==0xFF0D){ //enter
+ char s[64];
+ strncpy(s,gtk_entry_get_text(GTK_ENTRY(icdCommand)),63);
+ if(!strlen(s)){
+ strcpy(s,lastCmd);
+ gtk_entry_set_text(GTK_ENTRY(icdCommand),s); //briefly flash last command
+ while (gtk_events_pending ()) gtk_main_iteration();
+ msDelay(60);
+ }
+ else strcpy(lastCmd,s);
+ if(executeCommand(s)) gtk_entry_set_text(GTK_ENTRY(icdCommand),"");
+// sprintf(s,"k=%X\n",((GdkEventKey*)event)->keyval);
+// AppendMessageICD(gtk_entry_get_text(icdCommand));
+ }
+ return FALSE;
+}
+///
+///Handle keyboard events in ICD tab
+gint icd_key_event(GtkWidget *widget, GdkEventButton *event, gpointer func_data)
+{
+ while (gtk_events_pending ()) gtk_main_iteration(); //wait completion of other tasks
+ if(event->type==GDK_KEY_PRESS){
+ switch(((GdkEventKey*)event)->keyval){
+ case 0xFFBE:
+ ICDHelp(NULL,NULL); //F1 = help
+ break;
+ case 0xFFC2:
+ icdHalt(NULL,NULL); //F5 = halt
+ break;
+ case 0xFFC4:
+ icdStep(NULL,NULL); //F7 = step
+ break;
+ case 0xFFC5:
+ icdStepOver(NULL,NULL); //F8 = step over
+ break;
+ case 0xFFC6:
+ icdRun(NULL,NULL); //F9 = run
+ break;
+ }
+// char s[64];
+// sprintf(s,"k=%X\n",((GdkEventKey*)event)->keyval);
+// AppendMessageICD(s);
+ }
+ return FALSE;
+}
+
diff --git a/icd.h b/icd.h
new file mode 100644
index 0000000..e9f7ead
--- /dev/null
+++ b/icd.h
@@ -0,0 +1,185 @@
+//General routines to communicate via ICD with a target
+
+//The following commands are implemented in the debugger monitor
+//routine which is written in the last memory page on the target chip.
+#define VER 1 //;version
+#define STEP 2 //;step
+#define GO 3 //;go
+#define RREG 4 //;read register
+#define WREG 5 //;write register
+#define EEADR 0x10D
+#define EEADRH 0x10F
+#define EEDATA 0x10C
+#define EEDATH 0x10E
+#define EECON1 0x18C
+#define EECON2 0x18D
+#define w_temp 0x6B
+#define status_temp 0x6C
+#define pclath_temp 0x6D
+#define fsr_temp 0x6E
+
+extern struct var{ char* name; int display;} variables[0x200];
+
+extern GtkWidget * statusTxt;
+extern GtkWidget * sourceTxt;
+extern GtkTextBuffer * sourceBuf;
+extern GtkWidget * icdVbox1;
+extern GtkWidget * icdMenuPC;
+extern GtkWidget * icdMenuSTAT;
+extern GtkWidget * icdMenuBank0;
+extern GtkWidget * icdMenuBank1;
+extern GtkWidget * icdMenuBank2;
+extern GtkWidget * icdMenuBank3;
+extern GtkWidget * icdMenuEE;
+extern GtkWidget * icdCommand;
+extern GtkTextBuffer * statusBuf;
+
+extern int icdTimer;
+
+//Prepare ICD interface by resetting the target with a power-up sequence.
+//MCLR is low so the target is reset even if power is not supplied by the programmer.
+//Set communication speed at 1/(2*Tck us)
+void startICD(int Tck);
+
+//Check whether the target is running or is executing the debug routine.
+//This is signaled by RB7 (Data): D=1 -> debugger monitor running
+int isRunning();
+
+//Set the next breakpoint address, the freeze bit,
+//and continue execution.
+//This is necessary because at every break
+//the ICD register is loaded with the last address.
+void cont(int break_addr, int freeze);
+
+//Execute a single step
+void step();
+
+//Remove reset so that the target can start executing its code.
+void run();
+
+//Get the debugger monitor version
+int version();
+
+//Halt execution by setting RB6 (Clock) low
+void Halt();
+
+//Read register at address addr
+int ReadRegister(int addr);
+
+//Read n registers starting at address addr
+int ReadRegisterN(int addr,int n,int* buf);
+
+//Write data at address addr
+void WriteRegister(int addr,int data);
+
+//Read program memory at address addr
+int ReadProgMem(int addr);
+
+//Read program memory at address addr
+int ReadProgMemN(int addr,int n,int* buf);
+
+//Read data memory at address addr
+int ReadDataMem(int addr);
+
+//Read data memory at address addr
+int ReadDataMemN(int addr,int n,unsigned char* buf);
+
+//Disassemble a command and return string
+char* decodeCmd(int cmd,char *str, int addrH);
+
+// get register name from list
+char* getVar(int addr,char *var);
+
+///
+///Scroll source file
+void scrollToLine(int line);
+
+///
+///Hilight line in source code
+void SourceHilightLine(int line);
+
+///
+///Remove hilight line in source code
+void SourceRemoveHilightLine(int line);
+
+///
+///load source file into source pane
+int loadSource(FILE *f);
+
+///
+///load and analyze coff file
+void loadCoff(GtkWidget *widget,GtkWidget *window);
+
+///
+/// List of variables used when decoding an assembly word
+void initVar();
+
+///
+///Show ICD help window
+void ICDHelp(GtkWidget *widget,GtkWidget *window);
+
+///
+///ICD: check if program is running
+void icdCheck(GtkWidget *widget,GtkWidget *window);
+
+///
+///ICD: run program
+void icdRun(GtkWidget *widget,GtkWidget *window);
+
+///
+///ICD: halt program
+void icdHalt(GtkWidget *widget,GtkWidget *window);
+
+///
+///ICD: step program
+void icdStep(GtkWidget *widget,GtkWidget *window);
+
+///
+///ICD: step program jumping over calls
+void icdStepOver(GtkWidget *widget,GtkWidget *window);
+
+///
+///ICD: stop program
+void icdStop(GtkWidget *widget,GtkWidget *window);
+
+///
+///ICD: refresh status
+void icdRefresh(GtkWidget *widget,GtkWidget *window);
+
+///
+/// Read and display an entire bank of memory
+void ShowBank(int bank,char* status);
+
+///
+/// Main ICD show function:
+/// prints status info according to selected options
+/// and the value of variables in the watch list
+void ShowContext();
+
+///
+///Add symbol to the list of watched variables
+int addWatch(struct symbol s);
+
+///
+/// ICD Command parser
+int executeCommand(char *command);
+
+///
+///Remove variable from watch list
+int removeWatch(char* name);
+
+///
+///Handle mouse events in source code window
+gint source_mouse_event(GtkWidget *widget, GdkEventButton *event, gpointer func_data);
+
+///
+///Handle mouse events in ICD status window
+gint icdStatus_mouse_event(GtkWidget *widget, GdkEventButton *event, gpointer func_data);
+
+///
+///Handle keyboard events in ICD command edit box
+gint icdCommand_key_event(GtkWidget *widget, GdkEventButton *event, gpointer func_data);
+
+///
+///Handle keyboard events in ICD tab
+gint icd_key_event(GtkWidget *widget, GdkEventButton *event, gpointer func_data);
diff --git a/icons.c b/icons.c
new file mode 100644
index 0000000..7705a09
--- /dev/null
+++ b/icons.c
@@ -0,0 +1,546 @@
+#include <gtk/gtk.h>
+/* GdkPixbuf RGBA C-Source image dump 1-byte-run-length-encoded */
+
+#ifdef __SUNPRO_C
+#pragma align 4 (write_icon)
+#endif
+#ifdef __GNUC__
+const guint8 write_icon[] __attribute__ ((__aligned__ (4))) =
+#else
+const guint8 write_icon[] =
+#endif
+{ ""
+ /* Pixbuf magic (0x47646b50) */
+ "GdkP"
+ /* length: header (24) + pixel_data (1667) */
+ "\0\0\6\233"
+ /* pixdata_type (0x2010002) */
+ "\2\1\0\2"
+ /* rowstride (96) */
+ "\0\0\0`"
+ /* width (24) */
+ "\0\0\0\30"
+ /* height (24) */
+ "\0\0\0\30"
+ /* pixel_data: */
+ "\211\0\0\0\0\5\34\33\33\6\0\0\0\0\0\0\0-\0\1\1C\0\0\0=\202\0\0\0<\2\4"
+ "\0\0@\0\0\0\15\220\0\0\0\0\10@BBC\2\11\11\377*\0\0\3770\0\0\3774\0\0"
+ "\377/\0\0\377\0\0\0\377\3\0\0J\216\0\0\0\0\11\0\0\0\13\0\0\0\0\0\22\22"
+ "\217H\5\5\377\367\0\0\370\365\0\0\372\377\0\0\371b\0\0\377\0\0\0\253"
+ "\217\0\0\0\0\13\23\24\24\5\0\0\0\0\0\0\0qV\0\0\377\377\0\0\376\377\0"
+ "\0\377\363\0\0\377\0\0\0\377\0\1\1T\0\0\0\0\0\0\0\1\216\0\0\0\0\3\272"
+ "\201\201\23\0\26\26\312\205\0\0\377\202\377\0\0\377\2[\2\2\377\1\37\37"
+ "\265\221\0\0\0\0\12\0\12\12\77\40\11\11\377\354\0\0\370\377\0\0\376\377"
+ "\0\0\377.\1\1\377\0\15\15\361\10\0\0\303\0\0\0\275\0\0\0\1\216\0\0\0"
+ "\0\11\0\32\32l9\0\0\377\373\0\0\373\377\0\0\376\377\0\0\377\266\0\0\375"
+ "t\0\0\375$\0\0\377\0\0\0[\215\0\0\0\0\15\0\0\0\6\0""88\14\21\25\25\377"
+ "\265\0\0\377\377\0\0\377\376\0\0\376\377\0\0\377\377\0\0\376f\0\0\377"
+ "\0\0\0\317c\0\0\7\0\0\0\0\35\35\35\0\213\0\0\0\0\12\24\24\24\1\0\0\0"
+ "\7\4\0\0\3641\0\0\377\77\0\0\377\375\0\0\376\377\0\0\377\373\0\0\377"
+ "\27\0\0\377\0\0\0n\203\0\0\0\0\1""999\2\205\0\0\0\0\3""222\0""333\3A"
+ "AA\0\202\0\0\0\0\1###\2\202\0\0\0\0\11\0\0\0\23\0\0\0\325\352\0\0\377"
+ "\377\0\0\376\233\0\0\377\0\0\0\340\0\0\0\0\0\0\0\312$$$\355\202\0\0\0"
+ "\0\1\7\7\7\2\207\0\0\0\0\17///\15>>>X\0\0\0\0\5\5\5\20\0\0\0S\0\0\0\0"
+ "\3\0\0\314\355\0\0\377\360\0\0\377R\0\0\377\0\1\1=\0\0\0\26\24\24\24"
+ "\365\11\11\11\377\24\24\24\331\202\0\0\0\0\6+++\0\0\0\0\0\0\0\0\3\0\0"
+ "\0\0MMM\12,,,\225\202\0\0\0\0\17\17\17\17\377\0\0\0\\\0\0\0\0\3\3\3\377"
+ "\0\0\0T\4\0\0\266\365\0\0\377\307\0\0\377\3\0\0\373\0\0\0\247\0\0\0\357"
+ "\14\14\14\377\0\0\0\367\0\0\0\377###\327\202\0\0\0\0\17\377\377\377\0"
+ "\0\0\0:\0\0\0\265\0\0\0\0\15\15\15\377\12\12\12\234\202\202\202+\31\31"
+ "\31\377\0\0\0\377\11\11\11h\35\35\35\364\0\0\0\377\3\0\0\372\377\0\0"
+ "\377\205\0\0\376\203\0\0\0\377\16\0\0\0\374\2\2\2\377\0\0\0\375\6\6\6"
+ "\377%%%\271\0\0\0\0///\6""666\233\14\14\14\377\0\0\0\243\23\23\23\361"
+ "\14\14\14\377\35\35\35\377\0\0\0\376\204\0\0\0\377\3\1\0\0\377\377\0"
+ "\0\376\214\0\0\377\205\0\0\0\377\7\1\1\1\376\0\0\0\377\10\10\10\362Z"
+ "ZZ0\0\0\0\0\21\21\21\377\10\10\10\370\202\0\0\0\377\12\0\0\0\374\0\0"
+ "\0\372\0\0\0\376\0\0\0\377\1\1\1\373\0\0\0\376\0\0\0\377\16\2\2\376\373"
+ "\0\0\376K\1\1\377\202\0\0\0\376\15\15\15\15\377\11\11\11\376\213\213"
+ "\213\376\0\0\0\377\1\1\1\374\5\5\5\377\27\27\27\221\0\0\0\0\0\0\0\376"
+ "\0\0\0\377\3\3\3\376\1\1\1\376\2\2\2\377\202\0\0\0\376\23\7\7\7\377\0"
+ "\0\0\376\7\7\7\376.44\377\14\0\0\376\257\1\1\376\0\0\0\377.))\376QQQ"
+ "\376\377\377\377\377ccc\376\12\12\12\376\0\0\0\377\0\0\0\376\0\0\0\374"
+ "\21\21\21\377\77\77\77j\0\0\0\377\1\1\1\377\203\0\0\0\377\2\17\17\17"
+ "\377mmm\377\202\0\0\0\377\12\244\244\244\377MNN\377\0\0\0\377(\2\2\377"
+ "\0\0\0\377fee\377\77\77\77\377777\377[[[\377\12\12\12\377\202\0\0\0\377"
+ "\21\0\0\0\376\0\0\0\377\23\23\23\377\3\3\3\376\0\0\0\377\201\201\201"
+ "\376aaa\376vvv\377\0\0\0\376iii\376\331\331\331\377666\376'''\376\0\0"
+ "\0\377\3\4\4\376\0\0\0\376\2\1\1\377\202\0\0\0\376\1\0\0\0\377\202\0"
+ "\0\0\376\1\0\0\0\377\202\0\0\0\376\15\0\0\0\377\0\0\0\371\0\0\0\376\0"
+ "\0\0\377!!!\376\203\203\203\376qqq\377<<<\376\0\0\0\376\35\35\35\377"
+ "\3\3\3\376\0\0\0\376\1\1\1\377\202\0\0\0\376\5\0\0\0\377\0\0\0\376\0"
+ "\0\0\377\0\0\0\374\0\0\0\375\202\0\0\0\374\202\0\0\0\377\4\11\11\11\377"
+ "\10\10\10*\0\0\0\377\1\1\1\376\210\0\0\0\377\1\0\0\0\376\202\0\0\0\377"
+ "\3\0\0\0\376\0\0\0\377\0\0\0\374\204\0\0\0\377\12\0\0\0\177\0\0\0\222"
+ "\15\15\15\377111\250\33\33\33\374\0\0\0\377\1\1\1\376\2\2\2\376\2\2\2"
+ "\377\1\1\1\375\202\0\0\0\377\2\0\0\0\376\0\0\0\377\202\0\0\0\375\17\0"
+ "\0\0\374\3\3\3\377\0\0\0\377\10\10\10\377'''\221\0\0\0\254###{\21\21"
+ "\21\377\37\37\37\312\0\0\0\0\0\0\0\254\23\23\23\217!!!H\10\10\10\377"
+ "\0\0\0\364\202\0\0\0\377\21\1\1\1\377\16\16\16\350\0\0\0\332\10\10\10"
+ "\377\0\0\0\314\36\36\36\377MMMC\4\4\4\374\26\26\26\354NNN.\11\11\11\377"
+ "\1\1\1m\3\3\3\306&&&\311\0\0\0J\7\7\7\371444\213\202\0\0\0\0\23\325\325"
+ "\325\12\25\25\25\330\0\0\0\377\0\0\0\340\0\0\0g\2\2\2\377\"\"\"\253\0"
+ "\0\0n+++\377\16\16\16.\12\12\12\377@@@.\37\37\37\250\0\0\0\213\0\0\0"
+ "\0(((\215\0\0\0""7\1\1\1_\0\0\0o\207\0\0\0\0\14\37\37\37\360\4\4\4\315"
+ "\0\0\0\0\0\0\0C\0\0\0\305\0\0\0\3\12\12\12\322\13\13\13#\0\0\0B\0\0\0"
+ "\6\0\0\0\0\6\6\6(\205\0\0\0\0\5\0\0\0\4\5\5\5\4""222\3\0\0\0\0""333\0"};
+
+
+/* GdkPixbuf RGBA C-Source image dump 1-byte-run-length-encoded */
+
+#ifdef __SUNPRO_C
+#pragma align 4 (read_icon)
+#endif
+#ifdef __GNUC__
+const guint8 read_icon[] __attribute__ ((__aligned__ (4))) =
+#else
+const guint8 read_icon[] =
+#endif
+{ ""
+ /* Pixbuf magic (0x47646b50) */
+ "GdkP"
+ /* length: header (24) + pixel_data (1755) */
+ "\0\0\6\363"
+ /* pixdata_type (0x2010002) */
+ "\2\1\0\2"
+ /* rowstride (96) */
+ "\0\0\0`"
+ /* width (24) */
+ "\0\0\0\30"
+ /* height (24) */
+ "\0\0\0\30"
+ /* pixel_data: */
+ "\203\0\0\0\0\1\25\25\25\6\205\0\0\0\0\4HQH<FJF@JIJ<bbb\0\217\0\0\0\0"
+ "\11I9I3;7;\216A8A\177\35\1\35{\0\0\0\201\33\20\33\377\34\30\34\377\30"
+ "\31\30\377\2\2\2\3\215\0\0\0\0\13\0\0\0\2\0\0\0\267\11\5\11\361\20\1"
+ "\20\377\21\34\21\377\7c\7\377\0X\0\377\0n\0\370\0$\0\377\27\15\27\374"
+ "\377\377\377\0\215\0\0\0\0\12\0\0\0\3\0\30\0\377\0\223\0\377\0\235\0"
+ "\374\0\220\0\376\0\332\0\377\0\377\0\376\0X\0\377\0\0\0\342\34\35\34"
+ "%\216\0\0\0\0\3\0\0\0\2\0\31\0\374\0\253\0\377\203\0\377\0\377\3\0\374"
+ "\0\377\0\0\0\377\0\0\0\277\202\0\0\0\0\1,,,\1\214\0\0\0\0\12\4\0\4\2"
+ "\0\"\0\374\0r\0\377\0\335\0\376\0\377\0\376\0\377\0\377\0\377\0\376\0"
+ "\274\0\372\0\26\0\377\"\7\"\332\202\0\0\0\0\1""999\2\213\0\0\0\0\14\371"
+ "\363\371\5'\33'\377\0<\0\377\0n\0\377\0\240\0\373\0\377\0\377\0\377\0"
+ "\376\0\377\0\377\0\245\0\375\5\14\5\377)')\325\204{\204\17\203\0\0\0"
+ "\0\2""333\2""111\0\210\0\0\0\0\13\40\4\40\234\0I\0\377\0%\0\377\0\35"
+ "\0\377\0y\0\377\0\377\0\376\0\377\0\377\0\377\0\376\0\330\0\375\6\0\6"
+ "\377\40\30\40\177\202\0\0\0\0\1\22\22\22\2\202\0\0\0\0\1\25\25\25\0\205"
+ "\0\0\0\0\11""333\0\0\0\0\0\0\0\0.\0\17\0\377\0\14\0\353\0\0\0g\0\0\0"
+ "\377\0y\0\377\0\377\0\375\202\0\377\0\377\3\0D\0\377\24\0\24\360aya\34"
+ "\202\0\0\0\0\2""222\223+++\17\202\0\0\0\0\1""222\1\205\0\0\0\0\21\1\7"
+ "\1""2\1\0\1\334\0\0\0\15\0\0\0\0\0\0\0f\13\0\13\377\1z\1\377\0\375\0"
+ "\373\0\377\0\375\0\322\0\371\1\0\1\377\32\36\32\211\2\3\2\271\0\0\0\0"
+ "\0\0\0\332\4\4\4\345hhh2\202\0\0\0\0\1;;;\0\205\0\0\0\0\21\0\0\0/\0\0"
+ "\0\224\2\2\2b\0\0\0\0\77\32\77X\2\6\2\377\0\300\0\375\0\377\0\374\0\377"
+ "\0\377\0\\\0\376\23\1\23\377\4\4\4\264\0\0\0\16\24\24\24\362\11\11\11"
+ "\377\34\34\34\377...\241\203\0\0\0\0'\0\0\0\3\0\0\0\0\0\0\0\12\0\0\0"
+ "{+++w\7\7\7\377\0\0\0\377\0\0\0W\0\0\0\0\0\23\0\371\0\306\0\377\0\377"
+ "\0\377\0\377\0\376\0\206\0\377\0\0\0\374\0\0\0\346\0\0\0\352\14\14\14"
+ "\377\0\0\0\374\0\0\0\376\13\13\13\377\267\267\267\7\0\0\0\0\377\377\377"
+ "\0\0\0\0:\0\0\0\265\0\0\0\0\11\11\11\377\17\17\17\236\203\203\203.\33"
+ "\33\33\377\0\0\0\377\0\0\0\371\0\21\0\376\0\312\0\377\0\377\0\376\0\377"
+ "\0\377\0\320\0\376\0\25\0\376\202\0\0\0\377\2\0\0\0\374\2\2\2\376\202"
+ "\0\0\0\377\12$$$\267\0\0\0\0///\6""666\233\14\14\14\377\0\0\0\243\24"
+ "\24\24\361\14\14\14\377\36\36\36\377\0\0\0\376\202\0\0\0\377\2\0\22\0"
+ "\377\0\317\0\376\202\0\377\0\377\1\0\251\0\377\205\0\0\0\377\7\1\1\1"
+ "\376\0\0\0\377\10\10\10\362ZZZ0\0\0\0\0\21\21\21\377\10\10\10\370\202"
+ "\0\0\0\377\7\0\0\0\374\0\0\0\372\0\0\0\376\0\0\0\377\0\0\0\376\0\21\0"
+ "\376\0\310\0\377\202\0\377\0\376\1\2y\2\377\202\0\0\0\376\15\15\15\15"
+ "\377\11\11\11\376\213\213\213\376\0\0\0\377\1\1\1\374\5\5\5\377\27\27"
+ "\27\221\0\0\0\0\0\0\0\376\0\0\0\377\3\3\3\376\1\1\1\376\2\2\2\377\202"
+ "\0\0\0\376\1\6\6\6\377\202\0\0\0\376\20\0\2\0\377\0\0\0\376585\376\0"
+ "\0\0\377...\376QQQ\376\377\377\377\377ccc\376\12\12\12\376\0\0\0\377"
+ "\0\0\0\376\0\0\0\374\21\21\21\377\77\77\77j\0\0\0\377\1\1\1\377\203\0"
+ "\0\0\377\2\17\17\17\377mmm\377\202\0\0\0\377\12\3\3\3\377\0\0\0\377r"
+ "kr\377\263\254\263\377A>A\377VWV\377\77\77\77\377777\377[[[\377\12\12"
+ "\12\377\202\0\0\0\377\21\0\0\0\376\0\0\0\377\23\23\23\377\3\3\3\376\0"
+ "\0\0\377\201\201\201\376aaa\376vvv\377\0\0\0\376iii\376\333\333\333\377"
+ ",,,\376\0\0\0\376\0\0\0\377666\376\16\16\16\376444\377\202\0\0\0\376"
+ "\1\0\0\0\377\202\0\0\0\376\1\0\0\0\377\202\0\0\0\376\15\0\0\0\377\0\0"
+ "\0\371\0\0\0\376\0\0\0\377!!!\376\203\203\203\376qqq\377<<<\376\0\0\0"
+ "\376\35\35\35\377\4\4\4\376\0\0\0\376\1\1\1\377\202\0\0\0\376\7\0\0\0"
+ "\377\2\2\2\376\0\0\0\377\0\0\0\374\0\0\0\375\0\0\0\372\0\0\0\374\203"
+ "\0\0\0\377\3\0\0\0)\0\0\0\377\1\1\1\376\212\0\0\0\377\1\0\0\0\376\202"
+ "\0\0\0\377\1\0\0\0\374\204\0\0\0\377\12\26\26\26\375\7\7\7q\0\0\0\313"
+ "\36\36\36\254\33\33\33\374\0\0\0\377\1\1\1\376\2\2\2\376\2\2\2\377\1"
+ "\1\1\375\204\0\0\0\3777\0\0\0\373\3\3\3\377\0\0\0\377\0\0\0\356\0\0\0"
+ "\367\13\13\13\377'''\216\0\0\0\315\2\2\2P\0\0\0\232\13\13\13\377\0\0"
+ "\0\0\0\0\0h$$$\377!!!H\10\10\10\377\0\0\0\367\0\0\0\373\0\0\0\377\2\2"
+ "\2\377\16\16\16\347\0\0\0\340\0\0\0\322\0\0\0\311\35\35\35\377<<<\307"
+ "\0\0\0\346\15\15\15\262\0\0\0\0\0\0\0\360\0\0\0{888~\6\6\6\216\0\0\0"
+ "\0\0\0\0\227\0\0\0\21\0\0\0\0###\3\325\325\325\12\25\25\25\330\0\0\0"
+ "\377\10\10\10\377\26\26\26\277\0\0\0\370!!!\251\0\0\0s\2\2\2""2\0\0\0"
+ "\25\14\14\14\377333\40\0\0\0\0\22\22\22\373&&&C\0\0\0\1\0\0\0N\211\0"
+ "\0\0\0\15\36\36\36\351\12\12\12\352\0\0\0\0\0\0\0""9\0\0\0\253\0\0\0"
+ "\206\0\0\0W\0\0\0\0\0\0\0G\0\0\0\23\0\0\0\0\0\0\0\22\0\0\0\30\202\0\0"
+ "\0\0\4\30\30\30\6\5\5\5\3\0\0\0\0\0\0\0\3\203\0\0\0\0"};
+
+
+/* GdkPixbuf RGBA C-Source image dump 1-byte-run-length-encoded */
+
+#ifdef __SUNPRO_C
+#pragma align 4 (system_icon)
+#endif
+#ifdef __GNUC__
+const guint8 system_icon[] __attribute__ ((__aligned__ (4))) =
+#else
+const guint8 system_icon[] =
+#endif
+{ ""
+ /* Pixbuf magic (0x47646b50) */
+ "GdkP"
+ /* length: header (24) + pixel_data (695) */
+ "\0\0\2\317"
+ /* pixdata_type (0x2010002) */
+ "\2\1\0\2"
+ /* rowstride (96) */
+ "\0\0\0`"
+ /* width (24) */
+ "\0\0\0\30"
+ /* height (24) */
+ "\0\0\0\30"
+ /* pixel_data: */
+ "\215\240\345\201\0\207\0\0\0\377\221\240\345\201\0\1\0\0\0\377\204\377"
+ "\377\0\377\1\0\0\0\377\221\240\345\201\0\1\0\0\0\377\204\377\377\0\377"
+ "\1\0\0\0\377\222\240\345\201\0\1\0\0\0\377\204\377\377\0\377\1\0\0\0"
+ "\377\222\240\345\201\0\1\0\0\0\377\204\377\377\0\377\222\240\345\201"
+ "\0\1\0\0\0\377\204\377\377\0\377\203\0\0\0\377\220\240\345\201\0\1\0"
+ "\0\0\377\205\377\377\0\377\1\0\0\0\377\221\240\345\201\0\202\0\0\0\377"
+ "\204\377\377\0\377\1\0\0\0\377\213\240\345\201\0\1\0\0\0\377\203\240"
+ "\345\201\0\5\0\0\0\377\200\200\200\377\240\345\201\0\0\0\0\377\240\345"
+ "\201\0\203\377\377\0\377\202\240\345\201\0\3\200\200\200\377\0\0\0\377"
+ "\200\200\200\377\205\240\345\201\0\4\0\0\0\377\200\200\200\377\0\0\0"
+ "\377\200\200\200\377\202\240\345\201\0\5\0\0\0\377\200\200\200\377\240"
+ "\345\201\0\0\0\0\377\240\345\201\0\202\377\377\0\377\6\0\0\0\377\240"
+ "\345\201\0\0\0\0\377\200\200\200\377\0\0\0\377\200\200\200\377\205\240"
+ "\345\201\0\4\0\0\0\377\200\200\200\377\0\0\0\377\200\200\200\377\202"
+ "\240\345\201\0\5\0\0\0\377\200\200\200\377\240\345\201\0\0\0\0\377\240"
+ "\345\201\0\202\377\377\0\377\207\0\0\0\377\203\240\345\201\0\214\0\0"
+ "\0\377\1\377\377\0\377\210\0\0\0\377\202\240\345\201\0\226\0\0\0\377"
+ "\1\240\345\201\0\227\0\0\0\377\1\240\345\201\0\205\0\0\0\377\2\200\200"
+ "\200\377\377\377\377\377\202\0\0\0\377\3\377\377\377\377\0\0\0\377\377"
+ "\377\377\377\202\0\0\0\377\203\377\377\377\377\202\0\0\0\377\1\377\377"
+ "\377\377\203\0\0\0\377\1\240\345\201\0\202\0\0\0\377\1\377\377\377\377"
+ "\202\0\0\0\377\202\377\377\377\377\202\0\0\0\377\2\377\377\377\377\0"
+ "\0\0\377\202\377\377\377\377\4\0\0\0\377\377\377\377\377\0\0\0\377\377"
+ "\377\377\377\206\0\0\0\377\1\240\345\201\0\227\0\0\0\377\1\240\345\201"
+ "\0\227\0\0\0\377\1\240\345\201\0\227\0\0\0\377\1\240\345\201\0\221\0"
+ "\0\0\377\203\240\345\201\0\1\200\200\200\377\205\240\345\201\0\5\0\0"
+ "\0\377\200\200\200\377\240\345\201\0\0\0\0\377\200\200\200\377\202\240"
+ "\345\201\0\2\0\0\0\377\200\200\200\377\202\240\345\201\0\1\0\0\0\377"
+ "\203\240\345\201\0\1\200\200\200\377\210\240\345\201\0\5\0\0\0\377\200"
+ "\200\200\377\240\345\201\0\0\0\0\377\200\200\200\377\202\240\345\201"
+ "\0\1\0\0\0\377\203\240\345\201\0\1\0\0\0\377\214\240\345\201\0\5\0\0"
+ "\0\377\200\200\200\377\240\345\201\0\0\0\0\377\200\200\200\377\251\240"
+ "\345\201\0"};
+
+
+/* GdkPixbuf RGBA C-Source image dump 1-byte-run-length-encoded */
+
+#ifdef __SUNPRO_C
+#pragma align 4 (go_icon)
+#endif
+#ifdef __GNUC__
+const guint8 go_icon[] __attribute__ ((__aligned__ (4))) =
+#else
+const guint8 go_icon[] =
+#endif
+{ ""
+ /* Pixbuf magic (0x47646b50) */
+ "GdkP"
+ /* length: header (24) + pixel_data (599) */
+ "\0\0\2o"
+ /* pixdata_type (0x2010002) */
+ "\2\1\0\2"
+ /* rowstride (96) */
+ "\0\0\0`"
+ /* width (24) */
+ "\0\0\0\30"
+ /* height (24) */
+ "\0\0\0\30"
+ /* pixel_data: */
+ "\313\377\377\377\0\203\0\0\0\377\202\0\0\0\0\223\377\377\377\0\2\0\0"
+ "\0\377\252\0\0\377\203\0\0\0\377\202\0\0\0\0\221\377\377\377\0\1\0\0"
+ "\0\377\203\252\0\0\377\203\0\0\0\377\202\0\0\0\0\203\377\377\377\0\202"
+ "\0\0\0\0\212\377\377\377\0\3\0\0\0\377\252\0\0\377\377\0\0\377\203\252"
+ "\0\0\377\203\0\0\0\377\202\0\0\0\0\3\377\377\377\0\0\0\0\0\377\377\377"
+ "\0\202\0\0\0\0\210\377\377\377\0\2\0\0\0\377\252\0\0\377\203\377\0\0"
+ "\377\203\252\0\0\377\203\0\0\0\377\202\0\0\0\0\213\377\377\377\0\2\0"
+ "\0\0\377\252\0\0\377\205\377\0\0\377\203\252\0\0\377\203\0\0\0\377\203"
+ "\0\0\0\0\210\377\377\377\0\2\0\0\0\377\252\0\0\377\207\377\0\0\377\203"
+ "\252\0\0\377\203\0\0\0\377\203\0\0\0\0\206\377\377\377\0\2\0\0\0\377"
+ "\252\0\0\377\211\377\0\0\377\203\252\0\0\377\203\0\0\0\377\202\0\0\0"
+ "\0\205\377\377\377\0\2\0\0\0\377\252\0\0\377\213\377\0\0\377\203\252"
+ "\0\0\377\202\0\0\0\377\202\0\0\0\0\204\377\377\377\0\2\0\0\0\377\252"
+ "\0\0\377\211\377\0\0\377\203\252\0\0\377\203\0\0\0\377\202\0\0\0\0\205"
+ "\377\377\377\0\2\0\0\0\377\252\0\0\377\207\377\0\0\377\203\252\0\0\377"
+ "\203\0\0\0\377\202\0\0\0\0\207\377\377\377\0\2\0\0\0\377\252\0\0\377"
+ "\205\377\0\0\377\203\252\0\0\377\203\0\0\0\377\1\0\0\0\1\202\0\0\0\0"
+ "\210\377\377\377\0\2\0\0\0\377\252\0\0\377\203\377\0\0\377\203\252\0"
+ "\0\377\203\0\0\0\377\202\0\0\0\0\3\0\0\0\4\377\377\377\0\0\0\0\0\210"
+ "\377\377\377\0\3\0\0\0\377\252\0\0\377\377\0\0\377\203\252\0\0\377\203"
+ "\0\0\0\377\202\0\0\0\0\215\377\377\377\0\1\0\0\0\377\203\252\0\0\377"
+ "\203\0\0\0\377\202\0\0\0\0\217\377\377\377\0\2\0\0\0\377\252\0\0\377"
+ "\203\0\0\0\377\202\0\0\0\0\2\377\377\377\0\0\0\0\0\202\377\377\377\0"
+ "\2\0\0\0\0\377\377\377\0\202\0\0\0\0\211\377\377\377\0\203\0\0\0\377"
+ "\202\0\0\0\0\202\377\377\377\0\203\0\0\0\0\202\377\377\377\0\1\0\0\0"
+ "\0\350\377\377\377\0"};
+
+
+/* GdkPixbuf RGBA C-Source image dump 1-byte-run-length-encoded */
+
+#ifdef __SUNPRO_C
+#pragma align 4 (halt_icon)
+#endif
+#ifdef __GNUC__
+const guint8 halt_icon[] __attribute__ ((__aligned__ (4))) =
+#else
+const guint8 halt_icon[] =
+#endif
+{ ""
+ /* Pixbuf magic (0x47646b50) */
+ "GdkP"
+ /* length: header (24) + pixel_data (944) */
+ "\0\0\3\310"
+ /* pixdata_type (0x2010002) */
+ "\2\1\0\2"
+ /* rowstride (96) */
+ "\0\0\0`"
+ /* width (24) */
+ "\0\0\0\30"
+ /* height (24) */
+ "\0\0\0\30"
+ /* pixel_data: */
+ "\315\0\0\0\0\206\0\0\0\377\202\0\0\0\0\206\0\0\0\377\212\0\0\0\0\1\0"
+ "\0\0\377\203\252\0\0\377\2\254\6\6\371\0\0\0\377\202\0\0\0\0\1\0\0\0"
+ "\377\204\252\0\0\377\1\0\0\0\377\212\0\0\0\0\2\0\0\0\377\252\0\0\377"
+ "\202\377\0\0\377\2\261\30\27\354\0\0\0\377\202\0\0\0\0\2\0\0\0\377\252"
+ "\0\0\377\202\377\0\0\377\2\252\0\0\377\0\0\0\377\212\0\0\0\0\2\0\0\0"
+ "\377\252\0\0\377\202\377\0\0\377\6\257\20\20\362\0\0\0\377\377\377\377"
+ "\2\0\0\0\0\0\0\0\377\252\0\0\377\202\377\0\0\377\3\252\0\0\377\0\0\0"
+ "\377\377\377\377\0\211\0\0\0\0\2\0\0\0\377\252\0\0\377\202\377\0\0\377"
+ "\6\254\10\7\371\0\0\0\377\377\377\377\12\0\0\0\0\0\0\0\377\252\0\0\377"
+ "\202\377\0\0\377\3\252\0\0\377\0\0\0\377\377\377\377\0\211\0\0\0\0\2"
+ "\0\0\0\377\252\0\0\377\202\377\0\0\377\6\252\0\0\377\0\0\0\377\377\377"
+ "\377\12\0\0\0\0\0\0\0\377\252\0\0\377\202\377\0\0\377\3\252\0\0\377\0"
+ "\0\0\377\377\377\377\0\211\0\0\0\0\2\0\0\0\377\252\0\0\377\202\377\0"
+ "\0\377\6\252\0\0\377\0\0\0\377\377\377\377\0\0\0\0\0\0\0\0\377\252\0"
+ "\0\377\202\377\0\0\377\3\252\0\0\377\0\0\0\377\377\377\377\0\211\0\0"
+ "\0\0\2\0\0\0\377\252\0\0\377\202\377\0\0\377\6\252\0\0\377\0\0\0\377"
+ "\377\377\377\0\0\0\0\0\0\0\0\377\254\10\7\371\202\377\0\0\377\3\252\0"
+ "\0\377\0\0\0\377\377\377\377\0\211\0\0\0\0\2\0\0\0\377\252\0\0\377\202"
+ "\377\0\0\377\6\252\0\0\377\0\0\0\377\377\377\377\0\0\0\0\0\0\0\0\377"
+ "\252\0\0\377\202\377\0\0\377\3\252\0\0\377\0\0\0\377\377\377\377\0\211"
+ "\0\0\0\0\2\0\0\0\377\252\0\0\377\202\377\0\0\377\6\252\0\0\377\0\0\0"
+ "\377\377\377\377\0\0\0\0\0\0\0\0\377\252\0\0\377\202\377\0\0\377\3\252"
+ "\0\0\377\0\0\0\377\377\377\377\0\211\0\0\0\0\2\0\0\0\377\252\0\0\377"
+ "\202\377\0\0\377\6\252\0\0\377\0\0\0\377\377\377\377\0\0\0\0\0\0\0\0"
+ "\377\252\0\0\377\202\377\0\0\377\3\252\0\0\377\0\0\0\377\377\377\377"
+ "\0\211\0\0\0\0\2\0\0\0\377\252\0\0\377\202\377\0\0\377\6\252\0\0\377"
+ "\0\0\0\377\377\377\377\0\0\0\0\0\0\0\0\377\252\0\0\377\202\377\0\0\377"
+ "\3\252\0\0\377\0\0\0\377\377\377\377\0\211\0\0\0\0\2\0\0\0\377\252\0"
+ "\0\377\202\377\0\0\377\6\252\0\0\377\0\0\0\377\377\377\377\0\0\0\0\0"
+ "\0\0\0\377\252\0\0\377\202\377\0\0\377\3\252\0\0\377\0\0\0\377\377\377"
+ "\377\0\211\0\0\0\0\2\0\0\0\377\252\0\0\377\202\377\0\0\377\6\252\0\0"
+ "\377\0\0\0\377\377\377\377\0\0\0\0\0\0\0\0\377\252\0\0\377\202\377\0"
+ "\0\377\3\252\0\0\377\0\0\0\377\377\377\377\0\211\0\0\0\0\2\0\0\0\377"
+ "\252\0\0\377\202\377\0\0\377\6\252\0\0\377\0\0\0\377\377\377\377\0\0"
+ "\0\0\0\0\0\0\377\252\0\0\377\202\377\0\0\377\3\252\0\0\377\0\0\0\377"
+ "\377\377\377\0\211\0\0\0\0\1\0\0\0\377\204\252\0\0\377\4\0\0\0\377\377"
+ "\377\377\0\0\0\0\0\0\0\0\377\204\252\0\0\377\2\0\0\0\377\377\377\377"
+ "\0\211\0\0\0\0\206\0\0\0\377\2\377\377\377\0\0\0\0\0\206\0\0\0\377\1"
+ "\377\377\377\0\344\0\0\0\0"};
+
+
+/* GdkPixbuf RGBA C-Source image dump 1-byte-run-length-encoded */
+
+#ifdef __SUNPRO_C
+#pragma align 4 (step_icon)
+#endif
+#ifdef __GNUC__
+const guint8 step_icon[] __attribute__ ((__aligned__ (4))) =
+#else
+const guint8 step_icon[] =
+#endif
+{ ""
+ /* Pixbuf magic (0x47646b50) */
+ "GdkP"
+ /* length: header (24) + pixel_data (1265) */
+ "\0\0\5\11"
+ /* pixdata_type (0x2010002) */
+ "\2\1\0\2"
+ /* rowstride (96) */
+ "\0\0\0`"
+ /* width (24) */
+ "\0\0\0\30"
+ /* height (24) */
+ "\0\0\0\30"
+ /* pixel_data: */
+ "\262\0\0\0\0\203\0\0\0\377\210\0\0\0\0\204\0\0\0\377\1\0\0\0\0\204\0"
+ "\0\0\377\204\0\0\0\0\1\0\0\0\377\202\252\0\0\377\1\0\0\0\377\206\0\0"
+ "\0\0\2\377\377\377\0\0\0\0\377\202\252\0\0\377\3\0\0\0\377\377\377\377"
+ "\0\0\0\0\377\202\252\0\0\377\1\0\0\0\377\204\0\0\0\0\5\0\0\0\377\252"
+ "\0\0\377\377\0\0\377\252\0\0\377\0\0\0\377\205\0\0\0\0\2\377\377\377"
+ "\0\0\0\0\377\202\252\0\0\377\3\0\0\0\377\0\0\0\0\0\0\0\377\202\252\0"
+ "\0\377\1\0\0\0\377\204\0\0\0\0\2\0\0\0\377\252\0\0\377\202\377\0\0\377"
+ "\2\252\0\0\377\0\0\0\377\204\0\0\0\0\2\377\377\377\0\0\0\0\377\202\252"
+ "\0\0\377\3\0\0\0\377\0\0\0\0\0\0\0\377\202\252\0\0\377\1\0\0\0\377\204"
+ "\0\0\0\0\2\0\0\0\377\252\0\0\377\203\377\0\0\377\4\252\0\0\377\0\0\0"
+ "\377\377\377\377\4\0\0\0\0\202\377\377\377\0\1\0\0\0\377\202\252\0\0"
+ "\377\3\0\0\0\377\0\0\0\0\0\0\0\377\202\252\0\0\377\1\0\0\0\377\204\0"
+ "\0\0\0\2\0\0\0\377\252\0\0\377\204\377\0\0\377\6\252\0\0\377\0\0\0\377"
+ "\377\377\377\2\0\0\0\0\377\377\377\0\0\0\0\377\202\252\0\0\377\3\0\0"
+ "\0\377\0\0\0\0\0\0\0\377\202\252\0\0\377\1\0\0\0\377\204\0\0\0\0\2\0"
+ "\0\0\377\252\0\0\377\203\377\0\0\377\4\376\3\2\377\377\0\0\377\252\0"
+ "\0\377\0\0\0\377\202\377\377\377\0\1\0\0\0\371\202\252\0\0\377\3\0\0"
+ "\0\377\0\0\0\0\0\0\0\377\202\252\0\0\377\1\0\0\0\377\204\0\0\0\0\2\0"
+ "\0\0\377\252\0\0\377\203\377\0\0\377\1\376\14\13\375\202\377\0\0\377"
+ "\4\252\0\0\377\0\0\0\377\377\377\377\0\0\0\0\323\202\252\0\0\377\3\0"
+ "\0\0\377\0\0\0\0\0\0\0\377\202\252\0\0\377\1\0\0\0\377\204\0\0\0\0\2"
+ "\0\0\0\377\252\0\0\377\207\377\0\0\377\1\252\0\0\377\202\0\0\0\377\202"
+ "\252\0\0\377\3\0\0\0\377\0\0\0\0\0\0\0\377\202\252\0\0\377\1\0\0\0\377"
+ "\204\0\0\0\0\2\0\0\0\377\252\0\0\377\206\377\0\0\377\4\376\33\32\376"
+ "\377\0\0\377\252\0\0\377\0\0\0\377\202\252\0\0\377\3\0\0\0\377\0\0\0"
+ "\0\0\0\0\377\202\252\0\0\377\1\0\0\0\377\204\0\0\0\0\2\0\0\0\377\252"
+ "\0\0\377\207\377\0\0\377\3\252\0\0\377$$$\362\0\0\0\377\202\252\0\0\377"
+ "\3\0\0\0\377\0\0\0\0\0\0\0\377\202\252\0\0\377\1\0\0\0\377\204\0\0\0"
+ "\0\2\0\0\0\377\252\0\0\377\206\377\0\0\377\4\252\0\0\377\23\23\23\367"
+ "\377\377\377\0\0\0\0\377\202\252\0\0\377\3\0\0\0\377\0\0\0\0\0\0\0\377"
+ "\202\252\0\0\377\1\0\0\0\377\204\0\0\0\0\2\0\0\0\377\252\0\0\377\205"
+ "\377\0\0\377\5\252\0\0\377\5\5\5\376\377\377\377\1\377\377\377\0\0\0"
+ "\0\377\202\252\0\0\377\3\0\0\0\377\0\0\0\0\0\0\0\377\202\252\0\0\377"
+ "\1\0\0\0\377\204\0\0\0\0\2\0\0\0\377\252\0\0\377\204\377\0\0\377\6\252"
+ "\0\0\377\0\0\0\377\377\377\3772\0\0\0\0\377\377\377\0\0\0\0\377\202\252"
+ "\0\0\377\3\0\0\0\377\0\0\0\0\0\0\0\377\202\252\0\0\377\1\0\0\0\377\204"
+ "\0\0\0\0\2\0\0\0\377\252\0\0\377\203\377\0\0\377\4\252\0\0\377\0\0\0"
+ "\377\377\377\377\0\0\0\0\0\202\377\377\377\0\1\0\0\0\377\202\252\0\0"
+ "\377\3\0\0\0\377\0\0\0\0\0\0\0\377\202\252\0\0\377\1\0\0\0\377\204\0"
+ "\0\0\0\2\0\0\0\377\252\0\0\377\202\377\0\0\377\10\252\0\0\377\0\0\0\377"
+ "\377\377\377\0\0\0\0\0\377\377\377\0\0\0\0\0\377\377\377\0\0\0\0\377"
+ "\202\252\0\0\377\3\0\0\0\377\0\0\0\0\0\0\0\377\202\252\0\0\377\1\0\0"
+ "\0\377\204\0\0\0\0\10\0\0\0\377\252\0\0\377\377\0\0\377\252\0\0\377\0"
+ "\0\0\377\377\377\377\0\0\0\0\0\377\377\377\0\202\0\0\0\0\2\377\377\377"
+ "\0\0\0\0\377\202\252\0\0\377\3\0\0\0\377\0\0\0\0\0\0\0\377\202\252\0"
+ "\0\377\1\0\0\0\377\204\0\0\0\0\1\0\0\0\377\202\252\0\0\377\4\0\0\0\377"
+ "\377\377\377\0\0\0\0\0\377\377\377\0\203\0\0\0\0\2\377\377\377\0\0\0"
+ "\0\377\202\252\0\0\377\3\0\0\0\377\377\377\377\0\0\0\0\377\202\252\0"
+ "\0\377\1\0\0\0\377\204\0\0\0\0\203\0\0\0\377\3\377\377\377\0\0\0\0\0"
+ "\377\377\377\0\205\0\0\0\0\204\0\0\0\377\1\0\0\0\0\204\0\0\0\377\312"
+ "\0\0\0\0"};
+
+
+/* GdkPixbuf RGBA C-Source image dump 1-byte-run-length-encoded */
+
+#ifdef __SUNPRO_C
+#pragma align 4 (stepover_icon)
+#endif
+#ifdef __GNUC__
+const guint8 stepover_icon[] __attribute__ ((__aligned__ (4))) =
+#else
+const guint8 stepover_icon[] =
+#endif
+{ ""
+ /* Pixbuf magic (0x47646b50) */
+ "GdkP"
+ /* length: header (24) + pixel_data (1098) */
+ "\0\0\4b"
+ /* pixdata_type (0x2010002) */
+ "\2\1\0\2"
+ /* rowstride (96) */
+ "\0\0\0`"
+ /* width (24) */
+ "\0\0\0\30"
+ /* height (24) */
+ "\0\0\0\30"
+ /* pixel_data: */
+ "\263\0\0\0\0\1\0\0\0\377\210\0\0\0\0\1\0\0\0\377\216\0\0\0\0\202\0\0"
+ "\0\377\207\0\0\0\0\202\0\0\0\377\215\0\0\0\0\3\0\0\0\377\252\0\0\377"
+ "\0\0\0\377\206\0\0\0\0\3\0\0\0\377\252\0\0\377\0\0\0\377\213\0\0\0\0"
+ "\2\377\377\377\12\0\0\0\377\202\252\0\0\377\2\0\0\0\377\377\377\377\3"
+ "\203\0\0\0\0\6\377\377\377\0\0\0\0\377\263\34\33\373\252\0\0\377\0\0"
+ "\0\377\377\377\3772\211\0\0\0\0\21\377\377\377\12\0\0\0\377\252\0\0\377"
+ "\377\0\0\377\252\0\0\377\0\0\0\377\377\377\377\1\377\377\377\12\0\0\0"
+ "\0\377\377\377\0\0\0\0\377\263\34\34\375\377\0\0\377\252\0\0\377\0\0"
+ "\0\377\377\377\377\40\377\377\377!\207\0\0\0\0\3\377\377\377\12\0\0\0"
+ "\377\252\0\0\377\202\377\0\0\377\3\252\0\0\377\0\0\0\341\355\377\355"
+ "\1\202\377\377\377\0\2\0\0\0\377\261\30\30\375\202\377\0\0\377\4\252"
+ "\0\0\377\0\0\0\377\355\377\355\15\377\377\377\0\206\0\0\0\0\3\377\377"
+ "\377\12\0\0\0\377\252\0\0\377\203\377\0\0\377\6\252\0\0\377\0\0\0\273"
+ "\377\377\377\2\377\377\377\0\0\0\0\377\260\23\23\375\203\377\0\0\377"
+ "\4\252\0\0\377\0\0\0\377\377\377\377\33\377\377\377\23\205\0\0\0\0\3"
+ "\377\377\377\12\0\0\0\377\252\0\0\377\204\377\0\0\377\5\252\0\0\377\0"
+ "\0\0\377\377\377\377\0\0\0\0\377\261\27\26\375\204\377\0\0\377\4\252"
+ "\0\0\377\0\0\0\377\377\377\377\16\377\377\377\5\204\0\0\0\0\3\377\377"
+ "\377\12\0\0\0\377\252\0\0\377\205\377\0\0\377\1\252\0\0\377\202\0\0\0"
+ "\377\1\254\11\10\376\205\377\0\0\377\4\252\0\0\377\0\0\0\377\377\377"
+ "\372\3\377\377\377\5\203\0\0\0\0\3\377\377\377\12\0\0\0\377\252\0\0\377"
+ "\206\377\0\0\377\3\252\0\0\377\0\0\0\377\252\0\0\377\206\377\0\0\377"
+ "\4\252\0\0\377\0\0\0\377\377\377\377\4\377\377\377\3\202\0\0\0\0\3\377"
+ "\377\377\12\0\0\0\377\252\0\0\377\205\377\0\0\377\4\252\0\0\377\24\25"
+ "\24\362\0\0\0\377\252\0\0\377\205\377\0\0\377\4\252\0\0\377\22\23\22"
+ "\360\377\377\371\1\377\377\377\0\203\0\0\0\0\3\377\377\377\10\0\0\0\377"
+ "\252\0\0\377\204\377\0\0\377\5\252\0\0\377\7\7\6\372\373\377\373\0\0"
+ "\0\0\377\252\0\0\377\204\377\0\0\377\4\252\0\0\377\7\7\6\372\370\377"
+ "\370\0\377\377\377\0\204\0\0\0\0\3\377\377\377\0\0\0\0\377\252\0\0\377"
+ "\203\377\0\0\377\6\252\0\0\377\0\0\0\377\377\377\377\3\377\377\377\0"
+ "\0\0\0\377\252\0\0\377\203\377\0\0\377\4\252\0\0\377\0\0\0\377\377\377"
+ "\377\0\377\377\377\1\205\0\0\0\0\3\377\377\377\2\0\0\0\377\252\0\0\377"
+ "\202\377\0\0\377\7\252\0\0\377\0\0\0\377\370\377\370\10\377\377\377\5"
+ "\377\377\377\0\0\0\0\377\252\0\0\377\202\377\0\0\377\4\252\0\0\377\0"
+ "\0\0\377\370\377\370\0\377\377\377\0\206\0\0\0\0\21\377\377\3770\0\0"
+ "\0\377\252\0\0\377\377\0\0\377\252\0\0\377\0\0\0\330\377\377\377\2\377"
+ "\377\377\0\0\0\0\0\377\377\377\0\0\0\0\377\252\0\0\377\377\0\0\377\252"
+ "\0\0\377\0\0\0\377\377\377\377\2\377\377\377\1\207\0\0\0\0\2\377\377"
+ "\377\22\0\0\0\377\202\252\0\0\377\3\0\0\0\377\377\377\377\6\377\377\377"
+ "\0\202\0\0\0\0\2\377\377\377\0\0\0\0\377\202\252\0\0\377\3\0\0\0\377"
+ "\377\377\377\7\377\377\377\1\210\0\0\0\0\6\377\377\377\"\0\0\0\377\252"
+ "\0\0\377\0\0\0\377\377\377\377\5\377\377\377\1\203\0\0\0\0\6\377\377"
+ "\377\0\0\0\0\377\252\0\0\377\0\0\0\377\377\377\377\4\377\377\377\1\211"
+ "\0\0\0\0\1\377\377\377\0\202\0\0\0\377\2\377\377\377\14\377\377\377\5"
+ "\204\0\0\0\0\1\377\377\377\0\202\0\0\0\377\2\377\377\377\16\377\377\377"
+ "\2\212\0\0\0\0\2\377\377\377\0\0\0\0\377\202\377\377\377\1\205\0\0\0"
+ "\0\4\377\377\377\0\0\0\0\377\377\377\377\7\377\377\377\1\321\0\0\0\0"};
+
+
+/* GdkPixbuf RGBA C-Source image dump 1-byte-run-length-encoded */
+
+#ifdef __SUNPRO_C
+#pragma align 4 (stop_icon)
+#endif
+#ifdef __GNUC__
+const guint8 stop_icon[] __attribute__ ((__aligned__ (4))) =
+#else
+const guint8 stop_icon[] =
+#endif
+{ ""
+ /* Pixbuf magic (0x47646b50) */
+ "GdkP"
+ /* length: header (24) + pixel_data (435) */
+ "\0\0\1\313"
+ /* pixdata_type (0x2010002) */
+ "\2\1\0\2"
+ /* rowstride (96) */
+ "\0\0\0`"
+ /* width (24) */
+ "\0\0\0\30"
+ /* height (24) */
+ "\0\0\0\30"
+ /* pixel_data: */
+ "\344\0\0\0\0\213\0\0\0\377\5\10\0\0\373\22\0\0\366\35\0\0\361'\0\0\355"
+ "\11\0\0\372\210\0\0\0\0\1\0\0\0\377\216\252\0\0\377\1+\0\0\353\210\0"
+ "\0\0\0\2\0\0\0\377\252\0\0\377\214\377\0\0\377\2\252\0\0\377/\0\0\351"
+ "\210\0\0\0\0\2\0\0\0\377\252\0\0\377\214\377\0\0\377\2\252\0\0\3775\0"
+ "\0\347\210\0\0\0\0\2\0\0\0\377\252\0\0\377\214\377\0\0\377\2\252\0\0"
+ "\3779\0\0\346\210\0\0\0\0\2\0\0\0\377\252\0\0\377\214\377\0\0\377\2\252"
+ "\0\0\377:\0\0\345\210\0\0\0\0\2\0\0\0\377\252\0\0\377\214\377\0\0\377"
+ "\2\252\0\0\377;\0\0\344\210\0\0\0\0\2\0\0\0\377\252\0\0\377\214\377\0"
+ "\0\377\2\252\0\0\377;\0\0\344\210\0\0\0\0\2\0\0\0\377\252\0\0\377\214"
+ "\377\0\0\377\2\252\0\0\377:\0\0\345\210\0\0\0\0\2\0\0\0\377\252\0\0\377"
+ "\214\377\0\0\377\2\252\0\0\3779\0\0\346\210\0\0\0\0\2\0\0\0\377\252\0"
+ "\0\377\214\377\0\0\377\2\252\0\0\3775\0\0\347\210\0\0\0\0\2\0\0\0\377"
+ "\252\0\0\377\214\377\0\0\377\2\252\0\0\3770\0\0\351\210\0\0\0\0\2\0\0"
+ "\0\377\252\0\0\377\214\377\0\0\377\2\252\0\0\377+\0\0\353\210\0\0\0\0"
+ "\2\0\0\0\377\252\0\0\377\214\377\0\0\377\2\252\0\0\377%\0\0\355\210\0"
+ "\0\0\0\1\0\0\0\377\216\252\0\0\377\1\36\0\0\360\210\0\0\0\0\215\0\0\0"
+ "\377\3\7\0\0\373\20\0\0\367\2\0\0\376\344\0\0\0\0"};
+
+
diff --git a/ihex.c b/ihex.c
new file mode 100644
index 0000000..39d3b94
--- /dev/null
+++ b/ihex.c
@@ -0,0 +1,15 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+
+int main (int argc, char **argv) {
+ int i,s=0,t;
+ for (i = 1; i < argc; i++){
+ sscanf(argv[i], "%X", &t);
+ s+=t;
+ }
+ printf("checksum=%02X\n",(-s)&0xff);
+ return 0;
+}
+
diff --git a/instructions.h b/instructions.h
new file mode 100644
index 0000000..bb96aa0
--- /dev/null
+++ b/instructions.h
@@ -0,0 +1,99 @@
+// programmer instructions v0.12.0
+#define NOP 0x00
+#define PROG_RST 0x01 // ->10B
+#define PROG_ID 0x02 // ->6B
+#define CHECK_INS 0x03 //+1B ->1B
+#define FLUSH 0x04 //no echo
+#define VREG_EN 0x05
+#define VREG_DIS 0x06
+#define SET_PARAMETER 0x07 //+3B: 1B parameter, 2B data
+ #define SET_T1T2 0 //T1, T2
+ #define SET_T3 1 //T3(H,L)
+ #define SET_timeout 2 //timeout(H,L)
+ #define SET_MN 3 //M, N
+#define WAIT_T1 0x08
+#define WAIT_T2 0x09
+#define WAIT_T3 0x0A
+#define WAIT_US 0x0B //+1B
+#define READ_ADC 0x0C // ->2B
+#define SET_VPP 0x0D //+1B ->1B
+#define EN_VPP_VCC 0x0E //+1B
+#define SET_CK_D 0x0F //+1B
+#define READ_PINS 0x10 // ->1B
+#define LOAD_CONF 0x11 //+2B 000000
+#define LOAD_DATA_PROG 0x12 //+2B 000010
+#define LOAD_DATA_DATA 0x13 //+2B 000011
+#define READ_DATA_PROG 0x14 // ->2B 000100
+#define READ_DATA_DATA 0x15 // ->1B 000101
+#define INC_ADDR 0x16 // 000110
+#define INC_ADDR_N 0x17 //+1B 000110
+#define BEGIN_PROG 0x18 // 001000
+#define BULK_ERASE_PROG 0x19 // 001001
+#define END_PROG 0x1A // 001010
+#define BULK_ERASE_DATA 0x1B // 001011
+#define END_PROG2 0x1C // 001110
+#define ROW_ERASE_PROG 0x1D // 010001
+#define BEGIN_PROG2 0x1E // 011000
+#define CUST_CMD 0x1F //+1B
+#define PROG_C 0x20 //+2B ->1B 001000&001110
+#define CORE_INS 0x21 //+2B 0000
+#define SHIFT_TABLAT 0x22 // ->1B 0010
+#define TABLE_READ 0x23 // ->1B 1000
+#define TBLR_INC_N 0x24 //+1B ->1+NB 1001
+#define TABLE_WRITE 0x25 //+2B 1100
+#define TBLW_INC_N 0x26 //+1+2NB 1101
+#define TBLW_PROG 0x27 //+4B 1111
+#define TBLW_PROG_INC 0x28 //+4B 1110
+#define SEND_DATA 0x29 //+3B
+#define READ_DATA 0x2A //+1B ->1B
+#define I2C_INIT 0x2B //+1B
+#define I2C_READ 0x2C //+3B ->1+NB
+#define I2C_WRITE 0x2D //+3+NB ->1B
+#define I2C_READ2 0x2E //+4B ->1+NB
+#define SPI_INIT 0x2F //+1B
+#define SPI_READ 0x30 //+1B ->1+NB
+#define SPI_WRITE 0x31 //+1+NB ->1B
+#define EXT_PORT 0x32 //+2B
+#define AT_READ_DATA 0x33 //+3B ->1+2NB
+#define AT_LOAD_DATA 0x34 //+3+2NB ->1B
+#define CLOCK_GEN 0x35 //+1B
+#define SIX 0x36 //+3B
+#define REGOUT 0x37 // ->2B
+#define ICSP_NOP 0x38 //
+#define TX16 0x39 //+1+2NB
+#define RX16 0x3A //+1B ->1+2NB
+#define uW_INIT 0x3B //
+#define uWTX 0x3C //+1+NB
+#define uWRX 0x3D //+1B ->+1+NB
+#define SIX_LONG 0x3E //+3B
+#define SIX_N 0x3F //+1+3NB ->1B
+#define OW_RESET 0x40 // ->1B
+#define OW_WRITE 0x41 //+1+NB
+#define OW_READ 0x42 //+1B ->1+NB
+#define UNIO_STBY 0x43 //
+#define UNIO_COM 0x44 //+2+NB ->1+NB
+#define SET_PORT_DIR 0x45 //+2B
+#define READ_B 0x46 // ->1B
+#define READ_AC 0x47 // ->1B
+#define AT_HV_RTX 0x48 //+1+NB ->1B
+#define SIX_LONG5 0x49 //+3B
+#define LOAD_PC 0x50 //+2B 011101
+#define LOAD_DATA_INC 0x51 //+2B 100010
+#define READ_DATA_INC 0x52 // ->2B 100100
+#define JTAG_SET_MODE 0x53 //+1B
+#define JTAG_SEND_CMD 0x54 //+1B
+#define JTAG_XFER_DATA 0x55 //+4B -> 4B
+#define JTAG_XFER_F_DATA 0x56 //+4B -> 4B
+#define ICSP8_SHORT 0x57 //+1B
+#define ICSP8_READ 0x58 //+1B -> 2B
+#define ICSP8_LOAD 0x59 //+3B
+// special ins.
+#define SPI_TEST 0xEF //+2B ->2B
+#define READ_RAM 0xF0 //+2B ->3B
+#define WRITE_RAM 0xF1 //+3B ->3B
+#define LOOP 0xF2
+#define TBLRD 0xF3 //+3B ->2B
+#define TBLWT 0xF4 //+5B
+#define REPEAT 0xF5 //+1B
+#define REPEAT_END 0xF6
+#define MAX_INS 0x59 //last instruction
diff --git a/op.c b/op.c
new file mode 100644
index 0000000..3e55dbc
--- /dev/null
+++ b/op.c
@@ -0,0 +1,1358 @@
+/*
+ * op.c - control program for the open programmer
+ * Copyright (C) 2009-2020 Alberto Maccioni
+ * for detailed info see:
+ * http://openprog.altervista.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
+ * or see <http://www.gnu.org/licenses/>
+ */
+
+
+#include "common.h"
+#include "I2CSPI.h"
+#include "deviceRW.h"
+#include "fileIO.h"
+#include "progAVR.h"
+
+
+#if !defined _WIN32 && !defined __CYGWIN__
+DWORD GetTickCount();
+#include <sys/select.h>
+int kbhit()
+{
+ struct timeval tv;
+ fd_set read_fd;
+ tv.tv_sec=0;
+ tv.tv_usec=0;
+ FD_ZERO(&read_fd);
+ FD_SET(0,&read_fd);
+ if(select(1, &read_fd, NULL, NULL, &tv) == -1) return 0;
+ if(FD_ISSET(0,&read_fd)) return 1;
+ return 0;
+}
+#define getch getchar
+#else
+#include "conio.h"
+#endif
+#define MinDly 0
+
+void msDelay(double delay);
+void TestHw();
+int StartHVReg(double V);
+void ProgID();
+void DisplayEE();
+int FindDevice();
+int CheckS1();
+
+char** strings;
+int saveLog=0,programID=0,load_osccal=0,load_BKosccal=0;
+int use_osccal=1,use_BKosccal=0;
+int load_calibword=0,max_err=200;
+int AVRlock=0x100,AVRfuse=0x100,AVRfuse_h=0x100,AVRfuse_x=0x100;
+int ICDenable=0,ICDaddr=0x1FF0;
+int FWVersion=0,HwID=0;
+
+FILE* logfile=0;
+char LogFileName[512]="";
+char loadfile[512]="",savefile[512]="";
+char loadfileEE[512]="",savefileEE[512]="";
+int info=0;
+int vid=0x1209,pid=0x5432;
+int new_vid=0x1209,new_pid=0x5432;
+int old_vid=0x04D8,old_pid=0x0100;
+
+WORD *memCODE_W=0;
+int size=0,sizeW=0,sizeEE=0,sizeCONFIG=0,sizeUSERID=0;
+unsigned char *memCODE=0,*memEE=0,memID[64],memCONFIG[48],memUSERID[8];
+double hvreg=0;
+int DeviceDetected=0;
+int skipV33check=0;
+int progress=0;
+int RWstop=0;
+int forceConfig=0;
+char dev[64]="";
+int devType=0x10000;
+char str[4096];
+
+#if !defined _WIN32 && !defined __CYGWIN__ //Linux
+ int fd = -1;
+ struct hiddev_report_info rep_info_i,rep_info_u;
+ struct hiddev_usage_ref_multi ref_multi_i,ref_multi_u;
+ char path[512]="";
+ unsigned char bufferU[128],bufferI[128];
+#else //Windows
+ unsigned char bufferU0[128],bufferI0[128];
+ unsigned char *bufferU,*bufferI;
+ DWORD NumberOfBytesRead,BytesWritten;
+ ULONG Result;
+ HANDLE WriteHandle,ReadHandle;
+ OVERLAPPED HIDOverlapped;
+ HANDLE hEventObject;
+#endif
+
+
+
+int main (int argc, char **argv) {
+
+ int ee=0,r=0,ver=0,c=0,support=0,i2c=0,spi_mode=0,i,j,testhw=0,s1=0;
+ int spi_speed=0,command=0,langfile=0,help=0;
+ char lang[32]="";
+ unsigned char tmpbuf[128];
+ opterr = 0;
+ int option_index = 0;
+ int fuse3k=0;
+ char* langid=0;
+ int cw1,cw2,cw3,cw4,cw5,cw6,cw7;
+ cw1=cw2=cw3=cw4=cw5=cw6=cw7=0x10000;
+#if defined _WIN32 || defined __CYGWIN__ //Windows
+ bufferI=bufferI0+1;
+ bufferU=bufferU0+1;
+ bufferI0[0]=0;
+ bufferU0[0]=0;
+#endif
+
+ struct option long_options[] =
+ {
+ {"BKosccal", no_argument, &load_BKosccal, 1},
+ {"calib", no_argument, &load_calibword, 1},
+ {"command", no_argument, &command, 1},
+ {"cw1", required_argument, 0, '1'},
+ {"cw2", required_argument, 0, '2'},
+ {"cw3", required_argument, 0, '3'},
+ {"cw4", required_argument, 0, '4'},
+ {"cw5", required_argument, 0, '5'},
+ {"cw6", required_argument, 0, '6'},
+ {"cw7", required_argument, 0, '7'},
+ {"d", required_argument, 0, 'd'},
+ {"device", required_argument, 0, 'd'},
+ {"ee", no_argument, &ee, 1},
+ {"err", required_argument, 0, 'e'},
+ {"fuse", required_argument, 0, 'f'},
+ {"fuseh", required_argument, 0, 'F'},
+ {"fusex", required_argument, 0, 'X'},
+ {"fuse3k", required_argument, 0, 'k'},
+ {"h", no_argument, &help,1},
+ {"help", no_argument, &help,1},
+ {"HWtest", no_argument, &testhw, 1},
+ {"info", no_argument, &info, 1},
+ {"i", no_argument, &info, 1},
+ {"i2c_r", no_argument, &i2c, 1},
+ {"i2c_r2", no_argument, &i2c, 2},
+ {"i2c_w", no_argument, &i2c, 3},
+ {"i2c_w2", no_argument, &i2c, 4},
+ {"i2cspeed", required_argument, 0, 'D'},
+ {"id", no_argument, &programID, 1},
+ {"icd", required_argument, 0, 'I'},
+ {"l", optional_argument, 0, 'l'}, //-l=val
+ {"log", optional_argument, 0, 'l'},
+ {"lang", required_argument, 0, 'n'},
+ {"langfile", no_argument, &langfile, 1},
+ {"lock", required_argument, 0, 'L'},
+ {"mode", required_argument, 0, 'm'},
+ {"nolvcheck", no_argument, &skipV33check, 1},
+ {"osccal", no_argument, &load_osccal, 1},
+#if !defined _WIN32 && !defined __CYGWIN__
+ {"p", required_argument, 0, 'p'},
+ {"path", required_argument, 0, 'p'},
+#endif
+ {"pid", required_argument, 0, 'P'},
+ {"rep" , required_argument, 0, 'R'},
+ {"reserved", no_argument, &r, 1},
+ {"r", no_argument, &r, 1},
+ {"s1", no_argument, &s1, 1},
+ {"S1", no_argument, &s1, 1},
+ {"s", required_argument, 0, 's'},
+ {"save", required_argument, 0, 's'},
+ {"saveEE", required_argument, 0, 'S'},
+ {"se", required_argument, 0, 'S'},
+ {"spi_r", no_argument, &i2c, 5},
+ {"spi_w", no_argument, &i2c, 6},
+ {"spispeed", required_argument, 0, 'D'},
+ {"support", no_argument, &support, 1},
+ {"use_BKosccal", no_argument, &use_BKosccal, 1},
+ {"version", no_argument, &ver, 1},
+ {"v", no_argument, &ver, 1},
+ {"vid", required_argument, 0, 'V'},
+ {"w", required_argument, 0, 'w'},
+ {"write", required_argument, 0, 'w'},
+ {"we", required_argument, 0, 'W'},
+ {"writeEE", required_argument, 0, 'W'},
+ {0, 0, 0, 0}
+ };
+ while ((c = getopt_long_only (argc, argv, "",long_options,&option_index)) != -1)
+ /*{ printf("optarg=%X\n",optarg);
+ if(optarg) printf("%s\n",optarg);
+ printf("c=%X %c\noption_index=%d name=%s\n",c,c,option_index,long_options[option_index].name); }
+ exit(0);*/
+ switch (c)
+ {
+ case '1': //force config word 1
+ i=sscanf(optarg, "%x", &cw1);
+ if(i!=1||cw1<0||cw1>0x3FFF) cw1=0x10000;
+ break;
+ case '2': //force config word 2
+ i=sscanf(optarg, "%x", &cw2);
+ if(i!=1||cw2<0||cw2>0x3FFF) cw2=0x10000;
+ break;
+ case '3': //force config word 3
+ i=sscanf(optarg, "%x", &cw3);
+ if(i!=1||cw3<0||cw3>0x3FFF) cw3=0x10000;
+ break;
+ case '4': //force config word 4
+ i=sscanf(optarg, "%x", &cw4);
+ if(i!=1||cw4<0||cw4>0x3FFF) cw4=0x10000;
+ break;
+ case '5': //force config word 5
+ i=sscanf(optarg, "%x", &cw5);
+ if(i!=1||cw5<0||cw5>0x3FFF) cw5=0x10000;
+ break;
+ case '6': //force config word 6
+ i=sscanf(optarg, "%x", &cw6);
+ if(i!=1||cw6<0||cw6>0x3FFF) cw6=0x10000;
+ break;
+ case '7': //force config word 7
+ i=sscanf(optarg, "%x", &cw7);
+ if(i!=1||cw7<0||cw7>0x3FFF) cw7=0x10000;
+ break;
+ case 'd': //device
+ strncpy(dev,optarg,sizeof(dev)-1);
+ break;
+ case 'e': //max write errors
+ max_err = atoi(optarg);
+ break;
+ case 'D': //spi speed
+ spi_speed = atoi(optarg);
+ if(spi_speed<0)spi_speed=0;
+ if(spi_speed>3)spi_speed=3;
+ break;
+ case 'f': //Atmel FUSE low
+ i=sscanf(optarg, "%x", &AVRfuse);
+ if(i!=1||AVRfuse<0||AVRfuse>0xFF) AVRfuse=0x100;
+ break;
+ case 'F': //Atmel FUSE high
+ i=sscanf(optarg, "%x", &AVRfuse_h);
+ if(i!=1||AVRfuse_h<0||AVRfuse_h>0xFF) AVRfuse_h=0x100;
+ break;
+ case 'I': //ICD routine address
+ i=sscanf(optarg, "%x", &ICDaddr);
+ if(i!=1||ICDaddr<0||ICDaddr>0xFFFF) ICDaddr=0x1F00;
+ ICDenable=1;
+ break;
+ case 'k': //Atmel FUSE low @ 3kHz
+ i=sscanf(optarg, "%x", &AVRfuse);
+ if(i!=1||AVRfuse<0||AVRfuse>0xFF) AVRfuse=0x100;
+ else fuse3k=1;
+ break;
+ case 'l': //save Log
+ saveLog=1;
+ if(optarg) strncpy(LogFileName,optarg,sizeof(LogFileName));
+ break;
+ case 'L': //Atmel LOCK
+ i=sscanf(optarg, "%x", &AVRlock);
+ if(i!=1||AVRlock<0||AVRlock>0xFF) AVRlock=0x100;
+ break;
+ case 'm': //SPI mode
+ spi_mode = atoi(optarg);
+ if(spi_mode<0) spi_mode=0;
+ if(spi_mode>3) spi_mode=3;
+ break;
+ case 'n': //language
+ strncpy(lang,optarg,sizeof(lang)-1);
+ break;
+#if !defined _WIN32 && !defined __CYGWIN__
+ case 'p': //hiddev path
+ strncpy(path,optarg,sizeof(path)-1);
+ break;
+#endif
+ case 'P': //pid
+ sscanf(optarg, "%x", &pid);
+ break;
+ case 'R': //USB HID report size
+ //DIMBUF = atoi(optarg);
+ break;
+ case 's': //save
+ strncpy(savefile,optarg,sizeof(savefile)-1);
+ break;
+ case 'S': //save EE
+ strncpy(savefileEE,optarg,sizeof(savefileEE)-1);
+ break;
+ case 'V': //vid
+ sscanf(optarg, "%x", &vid);
+ break;
+ case 'X': //Atmel extended FUSE
+ i=sscanf(optarg, "%x", &AVRfuse_x);
+ if(i!=1||AVRfuse_x<0||AVRfuse_x>0xFF) AVRfuse_x=0x100;
+ break;
+ case 'w': //write file
+ strncpy(loadfile,optarg,sizeof(loadfile)-1);
+ break;
+ case 'W': //write EE file
+ strncpy(loadfileEE,optarg,sizeof(loadfileEE)-1);
+ break;
+ case '?':
+ fprintf (stderr,strings[L_OPTERR]); //errore opzioni
+ return 1;
+ default:
+
+ break;
+ }
+
+ for(j=0,i = optind; i < argc&&i<128; i++,j++) sscanf(argv[i], "%x", &tmpbuf[j]);
+ for(;j<128;j++) tmpbuf[j]=0;
+
+ strinit();
+ i=0;
+ if(lang[0]){ //explicit language selection
+ if(lang[0]=='i'&&langid[1]=='t'){ //built-in
+ strings=strings_it;
+ i=1;
+ }
+ else if(lang[0]=='e'&&lang[1]=='n'){ //built-in
+ strings=strings_en;
+ i=1;
+ }
+ else i=strfind(lang,"languages.rc"); //file look-up
+ }
+ if(i==0){
+ #if defined _WIN32
+ langid=malloc(19);
+ int n=GetLocaleInfo(LOCALE_USER_DEFAULT,LOCALE_SISO639LANGNAME,langid,9);
+ langid[n-1] = '-';
+ GetLocaleInfo(LOCALE_USER_DEFAULT,LOCALE_SISO3166CTRYNAME,langid+n, 9);
+ //printf("%d >%s<\n",n,langid);
+ #else
+ langid=getenv("LANG");
+ #endif
+ if(langid){
+ if(langid[0]=='i'&&langid[1]=='t') strings=strings_it;
+ else if(langid[0]=='e'&&langid[1]=='n') strings=strings_en;
+ else if(strfind(langid,"languages.rc")); //first try full code
+ else { //then only first language code
+ char* p=strchr(langid,'-');
+ if(p) *p=0;
+ if(!strfind(langid,"languages.rc")) strings=strings_en;
+ }
+ }
+ else strings=strings_en;
+ }
+
+ strncpy(LogFileName,strings[S_LogFile],sizeof(LogFileName));
+ if(argc==1){
+ printf(strings[L_HELP]);
+ exit(1);
+ }
+
+ if(help){
+ printf(strings[L_HELP]);
+ return 1;
+ }
+
+ if(langfile) GenerateLangFile(langid,"languages.rc");
+
+ if (ver){
+ printf("OP v%s\nCopyright (C) Alberto Maccioni 2009-2022\
+\n For detailed info see http://openprog.altervista.org/\
+\nThis program is free software; you can redistribute it and/or modify it under \
+the terms of the GNU General Public License as published by the Free Software \
+Foundation; either version 2 of the License, or (at your option) any later version.\
+ \n",VERSION);
+ return 0;
+ }
+ if (support){
+ char list[20000]; //make sure list is long enough!!
+ AddDevices(list);
+ printf("%s\n",list);
+ return 0;
+ }
+ DeviceDetected=FindDevice(vid,pid); //connect to USB programmer
+ if(!DeviceDetected){
+ DeviceDetected=FindDevice(new_vid,new_pid); //try default
+ if(DeviceDetected){
+ vid=new_vid;
+ pid=new_pid;
+ }
+ }
+ if(!DeviceDetected) DeviceDetected=FindDevice(old_vid,old_pid); //try old one
+ if(!DeviceDetected) exit(1);
+ ProgID(); //get firmware version and reset
+
+#if !defined _WIN32 && !defined __CYGWIN__
+ if(info){
+ #ifndef hiddevIO //use raw USB device
+ struct hidraw_devinfo device_info;
+ char name[256],path[256];
+ ioctl(fd, HIDIOCGRAWINFO, &device_info);
+ ioctl(fd, HIDIOCGRAWNAME(256), name);
+ ioctl(fd, HIDIOCGRAWPHYS(256), path);
+ printf("VID 0x%04X PID 0x%04X\n",device_info.vendor, device_info.product);
+ printf(strings[L_NAME], path, name);//"The device on %s says its name is %s\n"
+ #else //use hiddev device (old method)
+ struct hiddev_devinfo device_info;
+ ioctl(fd, HIDIOCGDEVINFO, &device_info);
+ printf(strings[L_INFO1],device_info.vendor, device_info.product, device_info.version);
+ printf(strings[L_INFO2],device_info.busnum, device_info.devnum, device_info.ifnum);
+ char name[256];
+ strcpy(name,strings[L_UNKNOWN]);//"Unknown"
+ if(ioctl(fd, HIDIOCGNAME(sizeof(name)), name) < 0) perror("evdev ioctl");
+ printf(strings[L_NAME], path, name);//"The device on %s says its name is %s\n"
+ #endif
+ return 0;
+ }
+#endif
+
+ DWORD t0,t;
+ t=t0=GetTickCount();
+ if(testhw){
+ TestHw();
+ return 0;
+ }
+
+ if(command){
+ //bufferU[0]=0;
+ for(i=0;i<DIMBUF;i++) bufferU[i]=(char) tmpbuf[i];
+ PacketIO(100);
+ printf("> ");
+ for(i=0;i<DIMBUF;i++) printf("%02X ",bufferU[i]);
+ printf("\n< ");
+ for(i=0;i<DIMBUF;i++) printf("%02X ",bufferI[i]);
+ printf("\n");
+ return 0;
+ }
+
+#define CS 8
+#define HLD 16
+ if(i2c){ //I2C, SPI
+ if(i2c==1){ //I2C receive 8 bit mode
+ I2CReceive(0,spi_speed,tmpbuf[0],tmpbuf+1);
+ }
+ else if(i2c==2){ //I2C receive 16 bit mode
+ I2CReceive(1,spi_speed,tmpbuf[0],tmpbuf+1);
+ }
+ else if(i2c==3){ //I2C transmit 8 bit mode
+ I2CSend(0,spi_speed,tmpbuf[0],tmpbuf+1);
+ }
+ else if(i2c==4){ //I2C transmit 16 bit mode
+ I2CSend(1,spi_speed,tmpbuf[0],tmpbuf+1);
+ }
+ else if(i2c==5){ //SPI receive
+ I2CReceive(2+spi_mode,spi_speed,tmpbuf[0],tmpbuf+1);
+ }
+ else if(i2c==6){ //SPI receive
+ I2CSend(2+spi_mode,spi_speed,tmpbuf[0],tmpbuf+1);
+ }
+ return 0 ;
+ }
+
+ struct DevInfo info;
+ info=GetDevInfo(dev);
+ devType=info.family;
+
+ if(fuse3k){ //write fuse low @ 3kHz
+ if(AVRfuse<0x100) WriteATfuseSlow(AVRfuse);
+ return 0;
+ }
+
+ if(loadfile[0]){ //write
+ if(Load(dev,loadfile)==-1){
+ PrintMessage(strings[S_NoCode2]);
+ PrintMessage("\n");
+ exit(-1);
+ }
+ if(!strncmp(dev,"AT",2)&&loadfileEE[0]) LoadEE(dev,loadfileEE);
+ //force config words
+ 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"
+ }
+ }
+/* if(CW1_force!=-1||CW2_force!=-1){
+ if((!strncmp(dev,"16F1",4)||!strncmp(dev,"12F1",4))){ //16F1xxx
+ if(CW1_force!=-1&&sizeW>0x8007) memCODE_W[0x8007]=CW1_force;
+ if(CW2_force!=-1&&sizeW>0x8008) memCODE_W[0x8008]=CW2_force;
+ }
+ else if((!strncmp(dev,"16F",3)||!strncmp(dev,"12F6",4))&&strncmp(dev,"16F5",4)){ //16Fxxx
+ if(CW1_force!=-1&&sizeW>0x2007) memCODE_W[0x2007]=CW1_force;
+ if(CW2_force!=-1&&sizeW>0x2008) memCODE_W[0x2008]=CW2_force;
+ }
+ else if((!strncmp(dev,"12F",3)||!strncmp(dev,"10F",3)||!strncmp(dev,"16F5",4))){ //12Fxxx
+ if(CW1_force!=-1&&sizeW>0xFFF) memCODE_W[0xFFF]=CW1_force&0xFFF;
+ }
+ if(CW1_force!=-1) PrintMessage1(strings[S_ForceConfigWx],CW1_force); //"forcing config word1 (0x%04X)"
+ if(CW2_force!=-1) PrintMessage1(strings[S_ForceConfigWx],CW2_force); //"forcing config word2 (0x%04X)"
+ }
+*/
+ //Start with button
+ if(s1){
+ PrintMessage(strings[S_WaitS1W]); //"Press S1 to program, any key to exit"
+ fflush(stdout);
+ for(;!kbhit();msDelay(50)){
+ if(CheckS1()){ //wait for S1
+ Write(dev,ee); //choose the right function
+ PrintMessage(strings[S_WaitS1W]); //"Press S1 to program, any key to exit"
+ fflush(stdout);
+ for(;CheckS1();msDelay(50)); //wait for S1 open
+ }
+ }
+ getch();
+ }
+ else Write(dev,ee); //choose the right function
+ }
+ else{ //read
+ if(s1){
+ PrintMessage(strings[S_WaitS1R]); //"Press S1 to read, any key to exit"
+ fflush(stdout);
+ for(;!kbhit();msDelay(50)){
+ if(CheckS1()){ //wait for S1
+ Read(dev,ee,r); //choose the right function
+ PrintMessage(strings[S_WaitS1R]); //"Press S1 to read, any key to exit"
+ fflush(stdout);
+ for(;CheckS1();msDelay(50)); //wait for S1 open
+ }
+ }
+ getch();
+ }
+ else Read(dev,ee,r); //choose the right function
+
+ if(savefile[0]) Save(dev,savefile);
+ if(!strncmp(dev,"AT",2)&&savefileEE[0]) SaveEE(dev,savefileEE);
+ }
+
+#if !defined _WIN32 && !defined __CYGWIN__ //Linux
+ close(fd);
+#endif
+ return 0 ;
+}
+
+
+///
+///Display contents of EEprom memory
+void DisplayEE(){
+ char s[256],t[256],v[256];
+ int valid=0,empty=1;
+ int i,j;
+ s[0]=0;
+ v[0]=0;
+ PrintMessage(strings[S_EEMem]); //"\r\nmemoria EEPROM:\r\n"
+ for(i=0;i<sizeEE;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]:'.');
+ strcat(v,t);
+ if(memEE[j]<0xff) valid=1;
+ }
+ if(valid){
+ PrintMessage3("%04X: %s %s\r\n",i,s,v);
+ empty=0;
+ }
+ s[0]=0;
+ v[0]=0;
+ }
+ if(empty) PrintMessage(strings[S_Empty]); //empty
+}
+
+///
+///Start HV regulator
+int StartHVReg(double V){
+ int j=0,z;
+ int vreg=(int)(V*10.0);
+ if(saveLog&&logfile) fprintf(logfile,"StartHVReg(%.2f)\n",V);
+ DWORD t0,t;
+ if(V==-1){
+ bufferU[j++]=VREG_DIS; //disable HV regulator
+ bufferU[j++]=FLUSH;
+ PacketIO(5);
+ msDelay(40);
+ return -1;
+ }
+ t=t0=GetTickCount();
+ bufferU[j++]=VREG_EN; //enable HV regulator
+ bufferU[j++]=SET_VPP;
+ bufferU[j++]=vreg;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2000>>8;
+ bufferU[j++]=2000&0xff;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=READ_ADC;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ msDelay(20);
+ for(z=0;z<DIMBUF-2&&bufferI[z]!=READ_ADC;z++);
+ int v=(bufferI[z+1]<<8)+bufferI[z+2];
+// PrintMessage2("v=%d=%fV\n",v,v/G);
+ if(v==0){
+ PrintMessage(strings[S_lowUsbV]); //"Tensione USB troppo bassa (VUSB<4.5V)\r\n"
+ return 0;
+ }
+ j=0;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=READ_ADC;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ for(;(v<(vreg/10.0-1)*G||v>(vreg/10.0+1)*G)&&t<t0+1500;t=GetTickCount()){
+ PacketIO(5);
+ msDelay(20);
+ for(z=0;z<DIMBUF-2&&bufferI[z]!=READ_ADC;z++);
+ v=(bufferI[z+1]<<8)+bufferI[z+2];
+ if(HwID==3) v>>=2; //if 12 bit ADC
+// PrintMessage2("v=%d=%fV\n",v,v/G);
+ }
+ if(v>(vreg/10.0+1)*G){
+ PrintMessage(strings[S_HiVPP]); //"Attenzione: tensione regolatore troppo alta\r\n\r\n"
+ return 0;
+ }
+ else if(v<(vreg/10.0-1)*G){
+ PrintMessage(strings[S_LowVPP]); //"Attenzione: tensione regolatore troppo bassa\r\n\r\n"
+ return 0;
+ }
+ else if(v==0){
+ PrintMessage(strings[S_lowUsbV]); //"Tensione USB troppo bassa (VUSB<4.5V)\r\n"
+ return 0;
+ }
+ else{
+ PrintMessage2(strings[S_reg],t-t0,v/G); //"Regolatore avviato e funzionante dopo T=%d ms VPP=%.1f\r\n\r\n"
+ if(saveLog&&logfile) fprintf(logfile,strings[S_reg],t-t0,v/G);
+ return vreg;
+ }
+}
+
+///
+///Read programmer ID
+void ProgID()
+{
+ if(DeviceDetected!=1) return;
+ int j=0;
+ bufferU[j++]=PROG_RST;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ for(j=0;j<DIMBUF-7&&bufferI[j]!=PROG_RST;j++);
+ PrintMessage3(strings[S_progver],bufferI[j+1],bufferI[j+2],bufferI[j+3]); //"FW versione %d.%d.%d\r\n"
+ FWVersion=(bufferI[j+1]<<16)+(bufferI[j+2]<<8)+bufferI[j+3];
+ PrintMessage3(strings[S_progid],bufferI[j+4],bufferI[j+5],bufferI[j+6]); //"ID Hw: %d.%d.%d"
+ HwID=bufferI[j+6];
+ if(HwID==1) PrintMessage(" (18F2550)\r\n\r\n");
+ else if(HwID==2) PrintMessage(" (18F2450)\r\n\r\n");
+ else if(HwID==3) PrintMessage(" (18F2458/2553)\r\n\r\n");
+ else if(HwID==4) PrintMessage(" (18F25K50)\r\n\r\n");
+ else PrintMessage(" (?)\r\n\r\n");
+}
+
+///
+///Check if a 3.3V regulator is present
+int CheckV33Regulator()
+{
+ int i,j=0;
+ if(skipV33check) return 1;
+ bufferU[j++]=WRITE_RAM;
+ bufferU[j++]=0x0F;
+ bufferU[j++]=0x93;
+ bufferU[j++]=0xFE; //B0 = output
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0x01; //B0=1
+ bufferU[j++]=0;
+ bufferU[j++]=READ_RAM;
+ bufferU[j++]=0x0F;
+ bufferU[j++]=0x81; //Check if B1=1
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0x00; //B0=0
+ bufferU[j++]=0;
+ bufferU[j++]=READ_RAM;
+ bufferU[j++]=0x0F;
+ bufferU[j++]=0x81; //Check if B1=0
+ bufferU[j++]=WRITE_RAM;
+ bufferU[j++]=0x0F;
+ bufferU[j++]=0x93;
+ bufferU[j++]=0xFF; //BX = input
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ for(j=0;j<DIMBUF-3&&bufferI[j]!=READ_RAM;j++);
+ i=bufferI[j+3]&0x2; //B1 should be high
+ for(j+=3;j<DIMBUF-3&&bufferI[j]!=READ_RAM;j++);
+ return (i+(bufferI[j+3]&0x2))==2?1:0;
+}
+
+///
+///Check if S1 is pressed
+int CheckS1()
+{
+ int i,j=0;
+ bufferU[j++]=READ_RAM;
+ bufferU[j++]=0x0F;
+ bufferU[j++]=0x84; //READ PORTE
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ for(j=0;j<DIMBUF-3&&bufferI[j]!=READ_RAM;j++);
+ i=bufferI[j+3]&0x8; //i=E3
+ return i?0:1; //S1 open -> E3=1
+}
+
+///
+///Execute hardware test
+void TestHw()
+{
+#ifndef DEBUG
+ if(DeviceDetected!=1) return;
+#endif
+ char str[256];
+ StartHVReg(13);
+ int j=0;
+ PrintMessage(strings[I_TestHW]); //"Test hardware ..."
+ fflush(stdout);
+ getchar();
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=EN_VPP_VCC; //VDD+VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ strcpy(str,strings[I_TestMSG]);
+ strcat(str,"\n VDD=5V\n VPP=13V\n PGD(RB5)=0V\n PGC(RB6)=0V\n PGM(RB7)=0V");
+ PrintMessage(str);
+ fflush(stdout);
+ getchar();
+ 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 VDD=5V\n VPP=0V\n PGD(RB5)=5V\n PGC(RB6)=5V\n PGM(RB7)=5V");
+ PrintMessage(str);
+ fflush(stdout);
+ getchar();
+ 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 VDD=0V\n VPP=13V\n PGD(RB5)=5V\n PGC(RB6)=0V\n PGM(RB7)=0V");
+ PrintMessage(str);
+ fflush(stdout);
+ getchar();
+ 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 VDD=0V\n VPP=0V\n PGD(RB5)=0V\n PGC(RB6)=5V\n PGM(RB7)=0V");
+ PrintMessage(str);
+ fflush(stdout);
+ getchar();
+ j=0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ if(FWVersion>=0x900){ //IO test
+ int j=0,i,x,r;
+ strcpy(str,"0000000000000");
+ PrintMessage("IO test\nRC|RA|--RB--|\n");
+ for(i=0;i<13;i++){
+ x=1<<i;
+ j=0;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_PORT_DIR;
+ bufferU[j++]=0x0; //TRISB
+ bufferU[j++]=0x0; //TRISA-C (RC7:RC6:RA5:RA4:RA3:X:X:X)
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=x&0xFF; //PORTB
+ bufferU[j++]=(x>>5)&0xFF; //PORTA-C
+ bufferU[j++]=READ_B;
+ bufferU[j++]=READ_AC;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ for(j=0;j<DIMBUF-1&&bufferI[j]!=READ_B;j++);
+ r=bufferI[j+1];
+ for(j+=2;j<DIMBUF-1&&bufferI[j]!=READ_AC;j++);
+ r+=(bufferI[j+1]&0xF8)<<5;
+ for(j=0;j<13;j++) str[12-j]=x&(1<<j)?'1':'0';
+ PrintMessage(str);
+ PrintMessage1(" (%s)\n",r==x?"OK":strings[S_ErrSing]);
+ }
+ }
+}
+
+///
+///Wait for X milliseconds
+void msDelay(double delay)
+{
+#if !defined _WIN32 && !defined __CYGWIN__
+ long x=(int)(delay*1000.0);
+ usleep(x>MinDly?x:MinDly);
+#else
+// Sleep((long)ceil(delay)>MinDly?(long)ceil(delay):MinDly);
+ __int64 stop,freq,timeout;
+ QueryPerformanceCounter((LARGE_INTEGER *)&stop);
+ QueryPerformanceFrequency((LARGE_INTEGER *)&freq);
+ timeout=stop+delay*freq/1000.0;
+ while(stop<timeout) QueryPerformanceCounter((LARGE_INTEGER *)&stop);
+#endif
+}
+
+#if !defined _WIN32 && !defined __CYGWIN__ //Linux
+///
+/// Get system time
+DWORD GetTickCount(){
+ struct timeb now;
+ ftime(&now);
+ return now.time*1000+now.millitm;
+}
+#endif
+
+///
+///Write data packet, wait for X milliseconds, read response
+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
+}
+
+///
+///Find the USB peripheral with proper vid&pid code
+/// return 0 if not found
+ #define FALSE 0
+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;
+ }
+ }
+ printf(strings[S_progDev],path);
+ MyDeviceDetected = TRUE;
+ rep_info_u.report_type=HID_REPORT_TYPE_OUTPUT;
+ rep_info_i.report_type=HID_REPORT_TYPE_INPUT;
+ rep_info_u.report_id=rep_info_i.report_id=HID_REPORT_ID_FIRST;
+ rep_info_u.num_fields=rep_info_i.num_fields=1;
+ ref_multi_u.uref.report_type=HID_REPORT_TYPE_OUTPUT;
+ ref_multi_i.uref.report_type=HID_REPORT_TYPE_INPUT;
+ ref_multi_u.uref.report_id=ref_multi_i.uref.report_id=HID_REPORT_ID_FIRST;
+ ref_multi_u.uref.field_index=ref_multi_i.uref.field_index=0;
+ ref_multi_u.uref.usage_index=ref_multi_i.uref.usage_index=0;
+ ref_multi_u.num_values=ref_multi_i.num_values=DIMBUF;
+ #endif
+#else //Windows
+ PSP_DEVICE_INTERFACE_DETAIL_DATA detailData;
+ HANDLE DeviceHandle;
+ HANDLE hDevInfo;
+ GUID HidGuid;
+ char MyDevicePathName[1024];
+ ULONG Length;
+ ULONG Required;
+ typedef struct _HIDD_ATTRIBUTES {
+ ULONG Size;
+ USHORT VendorID;
+ USHORT ProductID;
+ USHORT VersionNumber;
+ } HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES;
+ typedef void (__stdcall*GETHIDGUID) (OUT LPGUID HidGuid);
+ typedef BOOLEAN (__stdcall*GETATTRIBUTES)(IN HANDLE HidDeviceObject,OUT PHIDD_ATTRIBUTES Attributes);
+ typedef BOOLEAN (__stdcall*SETNUMINPUTBUFFERS)(IN HANDLE HidDeviceObject,OUT ULONG NumberBuffers);
+ typedef BOOLEAN (__stdcall*GETNUMINPUTBUFFERS)(IN HANDLE HidDeviceObject,OUT PULONG NumberBuffers);
+ typedef BOOLEAN (__stdcall*GETFEATURE) (IN HANDLE HidDeviceObject, OUT PVOID ReportBuffer, IN ULONG ReportBufferLength);
+ typedef BOOLEAN (__stdcall*SETFEATURE) (IN HANDLE HidDeviceObject, IN PVOID ReportBuffer, IN ULONG ReportBufferLength);
+ typedef BOOLEAN (__stdcall*GETREPORT) (IN HANDLE HidDeviceObject, OUT PVOID ReportBuffer, IN ULONG ReportBufferLength);
+ typedef BOOLEAN (__stdcall*SETREPORT) (IN HANDLE HidDeviceObject, IN PVOID ReportBuffer, IN ULONG ReportBufferLength);
+ typedef BOOLEAN (__stdcall*GETMANUFACTURERSTRING) (IN HANDLE HidDeviceObject, OUT PVOID ReportBuffer, IN ULONG ReportBufferLength);
+ typedef BOOLEAN (__stdcall*GETPRODUCTSTRING) (IN HANDLE HidDeviceObject, OUT PVOID ReportBuffer, IN ULONG ReportBufferLength);
+ typedef BOOLEAN (__stdcall*GETINDEXEDSTRING) (IN HANDLE HidDeviceObject, IN ULONG StringIndex, OUT PVOID ReportBuffer, IN ULONG ReportBufferLength);
+ HIDD_ATTRIBUTES Attributes;
+ SP_DEVICE_INTERFACE_DATA devInfoData;
+ int LastDevice = FALSE;
+ int MemberIndex = 0;
+ LONG Result;
+ Length=0;
+ detailData=NULL;
+ DeviceHandle=NULL;
+ HMODULE hHID=0;
+ GETHIDGUID HidD_GetHidGuid=0;
+ GETATTRIBUTES HidD_GetAttributes=0;
+ SETNUMINPUTBUFFERS HidD_SetNumInputBuffers=0;
+ GETNUMINPUTBUFFERS HidD_GetNumInputBuffers=0;
+ GETFEATURE HidD_GetFeature=0;
+ SETFEATURE HidD_SetFeature=0;
+ GETREPORT HidD_GetInputReport=0;
+ SETREPORT HidD_SetOutputReport=0;
+ GETMANUFACTURERSTRING HidD_GetManufacturerString=0;
+ GETPRODUCTSTRING HidD_GetProductString=0;
+ hHID = LoadLibrary("hid.dll");
+ if(!hHID){
+ PrintMessage("Can't find hid.dll");
+ return 0;
+ }
+ HidD_GetHidGuid=(GETHIDGUID)GetProcAddress(hHID,"HidD_GetHidGuid");
+ HidD_GetAttributes=(GETATTRIBUTES)GetProcAddress(hHID,"HidD_GetAttributes");
+ HidD_SetNumInputBuffers=(SETNUMINPUTBUFFERS)GetProcAddress(hHID,"HidD_SetNumInputBuffers");
+ HidD_GetNumInputBuffers=(GETNUMINPUTBUFFERS)GetProcAddress(hHID,"HidD_GetNumInputBuffers");
+ HidD_GetFeature=(GETFEATURE)GetProcAddress(hHID,"HidD_GetFeature");
+ HidD_SetFeature=(SETFEATURE)GetProcAddress(hHID,"HidD_SetFeature");
+ HidD_GetInputReport=(GETREPORT)GetProcAddress(hHID,"HidD_GetInputReport");
+ HidD_SetOutputReport=(SETREPORT)GetProcAddress(hHID,"HidD_SetOutputReport");
+ HidD_GetManufacturerString=(GETMANUFACTURERSTRING)GetProcAddress(hHID,"HidD_GetManufacturerString");
+ HidD_GetProductString=(GETPRODUCTSTRING)GetProcAddress(hHID,"HidD_GetProductString");
+ if(HidD_GetHidGuid==NULL\
+ ||HidD_GetAttributes==NULL\
+ ||HidD_GetFeature==NULL\
+ ||HidD_SetFeature==NULL\
+ ||HidD_GetInputReport==NULL\
+ ||HidD_SetOutputReport==NULL\
+ ||HidD_GetManufacturerString==NULL\
+ ||HidD_GetProductString==NULL\
+ ||HidD_SetNumInputBuffers==NULL\
+ ||HidD_GetNumInputBuffers==NULL) return 0;
+ HMODULE hSAPI=0;
+ hSAPI = LoadLibrary("setupapi.dll");
+ if(!hSAPI){
+ PrintMessage("Can't find setupapi.dll");
+ return 0;
+ }
+ typedef HDEVINFO (WINAPI* SETUPDIGETCLASSDEVS) (CONST GUID*,PCSTR,HWND,DWORD);
+ typedef BOOL (WINAPI* SETUPDIENUMDEVICEINTERFACES) (HDEVINFO,PSP_DEVINFO_DATA,CONST GUID*,DWORD,PSP_DEVICE_INTERFACE_DATA);
+ typedef BOOL (WINAPI* SETUPDIGETDEVICEINTERFACEDETAIL) (HDEVINFO,PSP_DEVICE_INTERFACE_DATA,PSP_DEVICE_INTERFACE_DETAIL_DATA_A,DWORD,PDWORD,PSP_DEVINFO_DATA);
+ typedef BOOL (WINAPI* SETUPDIDESTROYDEVICEINFOLIST) (HDEVINFO);
+ SETUPDIGETCLASSDEVS SetupDiGetClassDevsA=0;
+ SETUPDIENUMDEVICEINTERFACES SetupDiEnumDeviceInterfaces=0;
+ SETUPDIGETDEVICEINTERFACEDETAIL SetupDiGetDeviceInterfaceDetailA=0;
+ SETUPDIDESTROYDEVICEINFOLIST SetupDiDestroyDeviceInfoList=0;
+ SetupDiGetClassDevsA=(SETUPDIGETCLASSDEVS) GetProcAddress(hSAPI,"SetupDiGetClassDevsA");
+ SetupDiEnumDeviceInterfaces=(SETUPDIENUMDEVICEINTERFACES) GetProcAddress(hSAPI,"SetupDiEnumDeviceInterfaces");
+ SetupDiGetDeviceInterfaceDetailA=(SETUPDIGETDEVICEINTERFACEDETAIL) GetProcAddress(hSAPI,"SetupDiGetDeviceInterfaceDetailA");
+ SetupDiDestroyDeviceInfoList=(SETUPDIDESTROYDEVICEINFOLIST) GetProcAddress(hSAPI,"SetupDiDestroyDeviceInfoList");
+ if(SetupDiGetClassDevsA==NULL\
+ ||SetupDiEnumDeviceInterfaces==NULL\
+ ||SetupDiDestroyDeviceInfoList==NULL\
+ ||SetupDiGetDeviceInterfaceDetailA==NULL) return 0;
+ /*
+ The following code is adapted from Usbhidio_vc6 application example by Jan Axelson
+ for more information see see http://www.lvr.com/hidpage.htm
+ */
+ /*
+ API function: HidD_GetHidGuid
+ Get the GUID for all system HIDs.
+ Returns: the GUID in HidGuid.
+ */
+ HidD_GetHidGuid(&HidGuid);
+ /*
+ API function: SetupDiGetClassDevs
+ Returns: a handle to a device information set for all installed devices.
+ Requires: the GUID returned by GetHidGuid.
+ */
+ hDevInfo=SetupDiGetClassDevs(&HidGuid,NULL,NULL,DIGCF_PRESENT|DIGCF_INTERFACEDEVICE);
+ devInfoData.cbSize = sizeof(devInfoData);
+ //Step through the available devices looking for the one we want.
+ //Quit on detecting the desired device or checking all available devices without success.
+ MemberIndex = 0;
+ LastDevice = FALSE;
+ do
+ {
+ /*
+ API function: SetupDiEnumDeviceInterfaces
+ On return, MyDeviceInterfaceData contains the handle to a
+ SP_DEVICE_INTERFACE_DATA structure for a detected device.
+ Requires:
+ The DeviceInfoSet returned in SetupDiGetClassDevs.
+ The HidGuid returned in GetHidGuid.
+ An index to specify a device.
+ */
+ Result=SetupDiEnumDeviceInterfaces (hDevInfo, 0, &HidGuid, MemberIndex, &devInfoData);
+ if (Result != 0)
+ {
+ //A device has been detected, so get more information about it.
+ /*
+ API function: SetupDiGetDeviceInterfaceDetail
+ Returns: an SP_DEVICE_INTERFACE_DETAIL_DATA structure
+ containing information about a device.
+ To retrieve the information, call this function twice.
+ The first time returns the size of the structure in Length.
+ The second time returns a pointer to the data in DeviceInfoSet.
+ Requires:
+ A DeviceInfoSet returned by SetupDiGetClassDevs
+ The SP_DEVICE_INTERFACE_DATA structure returned by SetupDiEnumDeviceInterfaces.
+ The final parameter is an optional pointer to an SP_DEV_INFO_DATA structure.
+ This application doesn't retrieve or use the structure.
+ If retrieving the structure, set
+ MyDeviceInfoData.cbSize = length of MyDeviceInfoData.
+ and pass the structure's address.
+ */
+ //Get the Length value.
+ //The call will return with a "buffer too small" error which can be ignored.
+ Result = SetupDiGetDeviceInterfaceDetail(hDevInfo, &devInfoData, NULL, 0, &Length, NULL);
+ //Allocate memory for the hDevInfo structure, using the returned Length.
+ detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(Length);
+ //Set cbSize in the detailData structure.
+ detailData -> cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
+ //Call the function again, this time passing it the returned buffer size.
+ Result = SetupDiGetDeviceInterfaceDetail(hDevInfo, &devInfoData, detailData, Length,&Required, NULL);
+ // Open a handle to the device.
+ // To enable retrieving information about a system mouse or keyboard,
+ // don't request Read or Write access for this handle.
+ /*
+ API function: CreateFile
+ Returns: a handle that enables reading and writing to the device.
+ Requires:
+ The DevicePath in the detailData structure
+ returned by SetupDiGetDeviceInterfaceDetail.
+ */
+ DeviceHandle=CreateFile(detailData->DevicePath,
+ 0, FILE_SHARE_READ|FILE_SHARE_WRITE,
+ (LPSECURITY_ATTRIBUTES)NULL,OPEN_EXISTING, 0, NULL);
+ /*
+ API function: HidD_GetAttributes
+ Requests information from the device.
+ Requires: the handle returned by CreateFile.
+ Returns: a HIDD_ATTRIBUTES structure containing
+ the Vendor ID, Product ID, and Product Version Number.
+ Use this information to decide if the detected device is
+ the one we're looking for.
+ */
+ //Set the Size to the number of bytes in the structure.
+ Attributes.Size = sizeof(Attributes);
+ Result = HidD_GetAttributes(DeviceHandle,&Attributes);
+ //Is it the desired device?
+ MyDeviceDetected = FALSE;
+ if (Attributes.VendorID == vid)
+ {
+ if (Attributes.ProductID == pid)
+ {
+ //Both the Vendor ID and Product ID match.
+ MyDeviceDetected = TRUE;
+ strcpy(MyDevicePathName,detailData->DevicePath);
+ // Get a handle for writing Output reports.
+ WriteHandle=CreateFile(detailData->DevicePath,
+ GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,
+ (LPSECURITY_ATTRIBUTES)NULL,OPEN_EXISTING,0,NULL);
+ //Get a handle to the device for the overlapped ReadFiles.
+ ReadHandle=CreateFile(detailData->DevicePath,
+ GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,(LPSECURITY_ATTRIBUTES)NULL,
+ OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
+ if (hEventObject) CloseHandle(hEventObject);
+ hEventObject = CreateEvent(NULL,TRUE,TRUE,"");
+ //Set the members of the overlapped structure.
+ HIDOverlapped.hEvent = hEventObject;
+ HIDOverlapped.Offset = 0;
+ HIDOverlapped.OffsetHigh = 0;
+ Result=HidD_SetNumInputBuffers(DeviceHandle,64);
+ }
+ else
+ //The Product ID doesn't match.
+ CloseHandle(DeviceHandle);
+ }
+ else
+ //The Vendor ID doesn't match.
+ CloseHandle(DeviceHandle);
+ //Free the memory used by the detailData structure (no longer needed).
+ free(detailData);
+ }
+ else
+ //SetupDiEnumDeviceInterfaces returned 0, so there are no more devices to check.
+ LastDevice=TRUE;
+ //If we haven't found the device yet, and haven't tried every available device,
+ //try the next one.
+ MemberIndex = MemberIndex + 1;
+ } //do
+ while ((LastDevice == FALSE) && (MyDeviceDetected == FALSE));
+ //Free the memory reserved for hDevInfo by SetupDiClassDevs.
+ SetupDiDestroyDeviceInfoList(hDevInfo);
+
+ if(info&&MyDeviceDetected == TRUE){
+ char string[1024];
+ PrintMessage3("Device detected: vid=0x%04X pid=0x%04X\nPath: %s\n",vid,pid,MyDevicePathName);
+ if(HidD_GetManufacturerString(DeviceHandle,string,sizeof(string))==TRUE) wprintf(L"Manufacturer string: %s\n",string);
+ if(HidD_GetProductString(DeviceHandle,string,sizeof(string))==TRUE) wprintf(L"Product string: %s\n",string);
+ }
+#endif
+ if (MyDeviceDetected == FALSE){
+ PrintMessage(strings[S_noprog]); //"Programmer not detected\r\n"
+ //gtk_statusbar_push(status_bar,statusID,strings[S_noprog]);
+ }
+ else{
+ PrintMessage(strings[S_prog]); //"Programmer detected\r\n");
+ //gtk_statusbar_push(status_bar,statusID,strings[S_prog]);
+ }
+ return MyDeviceDetected;
+} \ No newline at end of file
diff --git a/opgui.c b/opgui.c
new file mode 100644
index 0000000..1268901
--- /dev/null
+++ b/opgui.c
@@ -0,0 +1,2503 @@
+/**
+ * \file opgui.c
+ * main control program for the open programmer
+ *
+ * Copyright (C) 2009-2023 Alberto Maccioni
+ * for detailed info see:
+ * http://openprog.altervista.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
+ * or see <http://www.gnu.org/licenses/>
+ */
+#include "common.h"
+#include "I2CSPI.h"
+#include "coff.h"
+#include "icd.h"
+#include "deviceRW.h"
+#include "fileIO.h"
+#include "progAVR.h"
+#include <string.h>
+
+#define MAXLINES 600
+#define CONFIG_FILE "opgui.ini"
+#define CONFIG_DIR ".opgui"
+#define MinDly 0
+void Connect(GtkWidget *widget,GtkWidget *window);
+void Quit(GtkWidget *widget,GtkWidget *window) { gtk_main_quit(); }
+void I2cspiR();
+void I2cspiS();
+void ProgID();
+void PrintMessageI2C(const char *msg);
+void ShowContext();
+int FindDevice(int vid,int pid);
+void TestHw();
+int CheckS1();
+char** strings; //!localized strings
+int cmdline=0;
+int saveLog=0,programID=0,load_osccal=0,load_BKosccal=0;
+int use_osccal=1,use_BKosccal=0;
+int load_calibword=0,max_err=200;
+int AVRlock=0x100,AVRfuse=0x100,AVRfuse_h=0x100,AVRfuse_x=0x100;
+int ICDenable=0,ICDaddr=0x1FF0;
+int FWVersion=0,HwID=0;
+FILE* logfile=0;
+char LogFileName[512]="";
+char loadfile[512]="",savefile[512]="";
+char loadfileEE[512]="",savefileEE[512]="";
+char CoffFileName[512]="";
+int vid=0x1209,pid=0x5432;
+int new_vid=0x1209,new_pid=0x5432;
+int old_vid=0x04D8,old_pid=0x0100;
+WORD *memCODE_W=0;
+int size=0,sizeW=0,sizeEE=0,sizeCONFIG=0,sizeUSERID=0;
+unsigned char *memCODE=0,*memEE=0,memID[64],memCONFIG[48],memUSERID[8];
+double hvreg=0;
+int DeviceDetected=0;
+int IOTimer=0;
+int skipV33check=0;
+int waitS1=0,waitingS1=0;
+int progress=0;
+int RWstop=0;
+int forceConfig=0;
+#ifdef DEBUG
+ int addrDebug=0;
+ unsigned short dataDebug=0;
+ unsigned short statusDebug=0x3FFF;
+#endif
+//List of gtk controls
+GtkTextBuffer * dataBuf;
+GtkWidget * data,*data_scroll;
+GtkWidget * window;
+GtkWidget * toolbar;
+GtkWidget * button;
+GtkWidget * b_open;
+GtkWidget * b_save;
+GtkWidget * b_read;
+GtkWidget * b_write;
+GtkWidget * notebook;
+GtkWidget * label;
+GtkWidget * status_bar;
+GtkWidget * img;
+GtkWidget * devTree;
+GtkWidget * devTypeCombo;
+GtkWidget * devFramePIC;
+GtkWidget * ICD_check;
+GtkWidget * ICD_addr_entry;
+GtkWidget * EEPROM_RW;
+GtkWidget * ReadReserved;
+GtkWidget * Write_ID_BKCal;
+GtkWidget * WriteCalib12;
+GtkWidget * UseOSCCAL;
+GtkWidget * UseBKOSCCAL;
+GtkWidget * UseFileCal;
+GtkWidget * devFrameAVR;
+GtkWidget * AVR_FuseLow,* AVR_FuseLowWrite,* AVR_FuseHigh,* AVR_FuseHighWrite,* AVR_FuseExt;
+GtkWidget * AVR_FuseExtWrite,* AVR_Lock,* AVR_LockWrite;
+GtkWidget * b_WfuseLF;
+GtkWidget * b_connect;
+GtkWidget * b_testhw;
+GtkWidget * b_log;
+GtkWidget * VID_entry;
+GtkWidget * PID_entry;
+GtkWidget * Errors_entry;
+GtkWidget * I2C8bit;
+GtkWidget * I2C16bit;
+GtkWidget * SPI00;
+GtkWidget * SPI01;
+GtkWidget * SPI10;
+GtkWidget * SPI11;
+GtkWidget * I2CDataSend;
+GtkWidget * I2CDataReceive;
+GtkWidget * I2CSendBtn;
+GtkWidget * I2CReceiveBtn;
+GtkWidget * I2CNbyte;
+GtkWidget * I2CSpeed;
+GtkWidget * DCDC_ON;
+GtkWidget * DCDC_voltage;
+GtkWidget * VPP_ON;
+GtkWidget * VDD_ON;
+GtkWidget * b_io_active;
+GtkWidget * commandSend;
+GtkWidget * commandTransfer;
+GtkWidget * b_V33check;
+GtkWidget * Hex_entry;
+GtkWidget * Address_entry;
+GtkWidget * Data_entry;
+GtkWidget * Hex_data;
+GtkWidget * Hex_data2;
+GtkWidget * CW1_entry;
+GtkWidget * CW2_entry;
+GtkWidget * CW3_entry;
+GtkWidget * CW4_entry;
+GtkWidget * CW5_entry;
+GtkWidget * CW6_entry;
+GtkWidget * CW7_entry;
+GtkWidget * ConfigForce;
+GtkWidget * b_WaitS1;
+GtkWidget * devFrameConfigW;
+GtkWidget * devFrameICD;
+GtkWidget * devFrameOsc;
+GtkWidget * devPIC_CW1;
+GtkWidget * devPIC_CW2;
+GtkWidget * devPIC_CW3;
+GtkWidget * devPIC_CW4;
+GtkWidget * devPIC_CW5;
+GtkWidget * devPIC_CW6;
+GtkWidget * devPIC_CW7;
+GtkWidget * devPIC_CW8;
+GtkWidget * devinfo;
+GtkWidget* stopBtn;
+GtkWidget* readBtn;
+GtkWidget* writeBtn;
+GtkListStore *devStore;
+GtkWidget *devTree, *devFiltEntry, *devFrame;
+GtkTreeSelection *devSel;
+///array of radio buttons for IO manual control
+struct io_btn { char * name;
+ int x;
+ int y;
+ GtkWidget * r_0; //radio button 0
+ GtkWidget * r_1; //radio button 1
+ GtkWidget * r_I; //radio button I
+ GtkWidget * e_I; //entry
+ } ioButtons[13];
+int statusID;
+int ee = 0;
+int readRes=0;
+char dev[64]="";
+int devType=-1;
+char str[4096]="";
+char* cur_path=0;
+char* cur_pathEE=0;
+enum dev_column_t {
+ DEVICE_ID_COLUMN = 0,
+ DEVICE_NAME_COLUMN,
+ DEVICE_GROUP_COLUMN,
+ DEVICE_N_COLUMNS
+};
+enum sort_type_t {
+ SORT_STRING_NAME = 0,
+ SORT_STRING_GROUP
+};
+enum sort_data_type_t { SDT_STRING = 0 };
+char *groupNames[NUM_GROUPS] = {
+ "PIC10/12",
+ "PIC16",
+ "PIC18",
+ "PIC24",
+ "PIC30/33",
+ "ATMEL AVR",
+ "MEMORY"
+};
+char *GROUP_ALL="*";
+
+#if !defined _WIN32 && !defined __CYGWIN__ //Linux
+ int fd = -1;
+#ifdef hiddevIO
+ struct hiddev_report_info rep_info_i,rep_info_u;
+ struct hiddev_usage_ref_multi ref_multi_i,ref_multi_u;
+#endif
+ char path[512]="";
+ unsigned char bufferU[128],bufferI[128];
+#else //Windows
+ unsigned char bufferU0[128],bufferI0[128];
+ unsigned char *bufferU,*bufferI;
+ DWORD NumberOfBytesRead,BytesWritten;
+ ULONG Result;
+ HANDLE WriteHandle,ReadHandle;
+ OVERLAPPED HIDOverlapped;
+ HANDLE hEventObject;
+#endif
+///
+///Exit
+gint delete_event( GtkWidget *widget,GdkEvent *event,gpointer data )
+{
+gtk_main_quit ();
+return FALSE;
+}
+///
+///Show program info window
+void info(GtkWidget *widget,GtkWidget *window)
+{
+ const gchar *license =
+ "This program is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU Library General Public License as\n"
+ "published by the Free Software Foundation; either version 2 of the\n"
+ "License, or (at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n"
+ "Library General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU Library General Public\n"
+ "License along with the Gnome Library; see the file COPYING.LIB. If not,\n"
+ "write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n"
+ "Boston, MA 02111-1307, USA.\n";
+ gtk_show_about_dialog (NULL,
+ //"artists" GStrv* : Read / Write
+ //"authors" GStrv* : Read / Write
+ //"authors","Alberto Maccioni",NULL,
+ "comments", "A graphical interface for the Open Programmer",
+ "copyright",
+ "Copyright (C) Alberto Maccioni 2009-2022\n\n"
+ "This program is free software; you can \n"
+ "redistribute it and/or modify it under \n"
+ "the terms of the GNU General Public License \n"
+ "as published by the Free Software Foundation;\n"
+ "either version 2 of the License, or \n"
+ "(at your option) any later version.",
+ //"documenters" GStrv* : Read / Write
+ "license",license,
+ "logo",gdk_pixbuf_new_from_resource("/res/sys.png", NULL),
+ // "logo-icon-name" gchar* : Read / Write
+ "program-name", "OPGUI",
+ // "translator-credits" gchar* : Read / Write
+ "version",VERSION,
+ "website","www.openprog.altervista.org",
+ // "website-label" gchar* : Read / Write
+ "wrap-license",TRUE,
+ "title","Info about OPGUI",
+ NULL);
+}
+///
+///Append a message on the data tab; shorten the length of the entry field to MAXLINES
+void PrintMessage(const char *msg){
+ if(cmdline) return; //do not print anything if using command line mode
+ GtkTextIter iter,iter2;
+ gtk_text_buffer_get_end_iter(dataBuf,&iter);
+ gtk_text_buffer_insert(dataBuf,&iter,msg,-1);
+ gtk_text_buffer_get_start_iter(dataBuf,&iter2);
+ gtk_text_buffer_get_end_iter(dataBuf,&iter);
+ int l=gtk_text_buffer_get_line_count(dataBuf);
+ if(l>MAXLINES+10){ //MAXLINES
+ gtk_text_iter_set_line(&iter,l-MAXLINES);
+ gtk_text_buffer_delete(dataBuf,&iter2,&iter);
+ }
+ while (gtk_events_pending ()) gtk_main_iteration();
+ gtk_text_buffer_get_end_iter(dataBuf,&iter);
+ gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(data),&iter,0.0,FALSE,0,0);
+}
+///
+///Print a message on the I2C data field
+void PrintMessageI2C(const char *msg){
+ GtkTextIter iter;
+ GtkTextBuffer * dataBuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(I2CDataReceive));
+ gtk_text_buffer_set_text(dataBuf,msg,-1);
+ gtk_text_buffer_get_end_iter(dataBuf,&iter);
+ gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(I2CDataReceive),&iter,0.0,FALSE,0,0);
+ while (gtk_events_pending ()) gtk_main_iteration();
+}
+///
+///Print a message on the "command" data field
+void PrintMessageCMD(const char *msg){
+ GtkTextIter iter;
+ GtkTextBuffer * dataBuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(commandTransfer));
+ gtk_text_buffer_set_text(dataBuf,msg,-1);
+ gtk_text_buffer_get_end_iter(dataBuf,&iter);
+ gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(commandTransfer),&iter,0.0,FALSE,0,0);
+}
+///
+///Update option variables according to actual control values
+void getOptions()
+{
+ vid=htoi(gtk_entry_get_text(GTK_ENTRY(VID_entry)),4);
+ pid=htoi(gtk_entry_get_text(GTK_ENTRY(PID_entry)),4);
+ saveLog = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_log));
+ ee = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(EEPROM_RW))?0xFFFF:0;
+ programID = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(Write_ID_BKCal));
+ max_err=atoi(gtk_entry_get_text(GTK_ENTRY(Errors_entry)));
+ load_calibword= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(WriteCalib12));
+ load_osccal= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(UseOSCCAL));
+ load_BKosccal= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(UseBKOSCCAL));
+ ICDenable= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ICD_check));
+ readRes= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ReadReserved));
+ skipV33check=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_V33check));
+ waitS1=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_WaitS1));
+ int i=sscanf(gtk_entry_get_text(GTK_ENTRY(ICD_addr_entry)),"%x",&ICDaddr);
+ if(i!=1||ICDaddr<0||ICDaddr>0xFFFF) ICDaddr=0x1FF0;
+ char *str=0;//gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(devCombo));
+ if(str) strncpy(dev,str,sizeof(dev)-1);
+ g_free(str);
+ AVRfuse=AVRfuse_h=AVRfuse_x=AVRlock=0x100;
+ if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(AVR_FuseLowWrite))){
+ i=sscanf(gtk_entry_get_text(GTK_ENTRY(AVR_FuseLow)),"%x",&AVRfuse);
+ if(i!=1||AVRfuse<0||AVRfuse>0xFF) AVRfuse=0x100;
+ }
+ if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(AVR_FuseHighWrite))){
+ i=sscanf(gtk_entry_get_text(GTK_ENTRY(AVR_FuseHigh)),"%x",&AVRfuse_h);
+ if(i!=1||AVRfuse_h<0||AVRfuse_h>0xFF) AVRfuse_h=0x100;
+ }
+ if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(AVR_FuseExtWrite))){
+ i=sscanf(gtk_entry_get_text(GTK_ENTRY(AVR_FuseExt)),"%x",&AVRfuse_x);
+ if(i!=1||AVRfuse_x<0||AVRfuse_x>0xFF) AVRfuse_x=0x100;
+ }
+ if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(AVR_LockWrite))){
+ i=sscanf(gtk_entry_get_text(GTK_ENTRY(AVR_Lock)),"%x",&AVRlock);
+ if(i!=1||AVRlock<0||AVRlock>0xFF) AVRlock=0x100;
+ }
+ str=malloc(128);
+ if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ConfigForce))){
+ int cw1,cw2,cw3,cw4,cw5,cw6,cw7;
+ cw1=cw2=cw3=cw4=cw5=cw6=cw7=0x10000;
+ i=sscanf(gtk_entry_get_text(GTK_ENTRY(CW1_entry)),"%x",&cw1);
+ i=sscanf(gtk_entry_get_text(GTK_ENTRY(CW2_entry)),"%x",&cw2);
+ i=sscanf(gtk_entry_get_text(GTK_ENTRY(CW3_entry)),"%x",&cw3);
+ i=sscanf(gtk_entry_get_text(GTK_ENTRY(CW4_entry)),"%x",&cw4);
+ i=sscanf(gtk_entry_get_text(GTK_ENTRY(CW5_entry)),"%x",&cw5);
+ i=sscanf(gtk_entry_get_text(GTK_ENTRY(CW6_entry)),"%x",&cw6);
+ i=sscanf(gtk_entry_get_text(GTK_ENTRY(CW7_entry)),"%x",&cw7);
+ if(devType==PIC16){
+ if((!strncmp(dev,"16F1",4)||!strncmp(dev,"12F1",4))&&sizeW>0x8008){ //16F1xxx
+ if(cw1<=0x3FFF){
+ memCODE_W[0x8007]=cw1;
+ PrintMessage3(strings[S_ForceConfigWx],1,0x8007,cw1); //"forcing config word%d [0x%04X]=0x%04X"
+ }
+ if(cw2<=0x3FFF){
+ memCODE_W[0x8008]=cw2;
+ PrintMessage3(strings[S_ForceConfigWx],2,0x8008,cw2); //"forcing config word%d [0x%04X]=0x%04X"
+ }
+ }
+ else{ //16Fxxx
+ if(cw1<=0x3FFF&&sizeW>0x2007){
+ memCODE_W[0x2007]=cw1;
+ PrintMessage3(strings[S_ForceConfigWx],1,0x2007,cw1); //"forcing config word%d [0x%04X]=0x%04X"
+ }
+ if(cw2<=0x3FFF&&sizeW>0x2008){
+ memCODE_W[0x2008]=cw2;
+ printf("2\n");
+ PrintMessage3(strings[S_ForceConfigWx],2,0x2008,cw2); //"forcing config word%d [0x%04X]=0x%04X"
+ }
+ }
+ }
+ else if(devType==PIC12){ //12Fxxx
+ if(cw1<=0xFFF&&sizeW>0xFFF){
+ memCODE_W[0xFFF]=cw1;
+ PrintMessage3(strings[S_ForceConfigWx],1,0xFFF,cw1); //"forcing config word%d [0x%04X]=0x%04X"
+ }
+ }
+ else if(devType==PIC18){ //18Fxxx
+ if(cw1<=0xFFFF){
+ memCONFIG[0]=cw1&0xFF;
+ memCONFIG[1]=(cw1>>8)&0xFF;
+ }
+ if(cw2<=0xFFFF){
+ memCONFIG[2]=cw2&0xFF;
+ memCONFIG[3]=(cw2>>8)&0xFF;
+ }
+ if(cw3<=0xFFFF){
+ memCONFIG[4]=cw3&0xFF;
+ memCONFIG[5]=(cw3>>8)&0xFF;
+ }
+ if(cw4<=0xFFFF){
+ memCONFIG[6]=cw4&0xFF;
+ memCONFIG[7]=(cw4>>8)&0xFF;
+ }
+ if(cw5<=0xFFFF){
+ memCONFIG[8]=cw5&0xFF;
+ memCONFIG[9]=(cw5>>8)&0xFF;
+ }
+ if(cw6<=0xFFFF){
+ memCONFIG[10]=cw6&0xFF;
+ memCONFIG[11]=(cw6>>8)&0xFF;
+ }
+ if(cw7<=0xFFFF){
+ memCONFIG[12]=cw7&0xFF;
+ memCONFIG[13]=(cw7>>8)&0xFF;
+ }
+ PrintMessage(strings[S_ForceConfigW]); //"forcing config words"
+ for(i=0;i<7;i++){
+ PrintMessage2(strings[S_ConfigWordH],i+1,memCONFIG[i*2+1]); //"CONFIG%dH: 0x%02X\t"
+ PrintMessage2(strings[S_ConfigWordL],i+1,memCONFIG[i*2]); //"CONFIG%dL: 0x%02X\r\n"
+ }
+ }
+ }
+ free(str);
+}
+///
+///Check GUI for selected device and put in variable 'dev'. Also enable/disable R/W buttons
+void GetSelectedDevice() {
+ GtkTreeModel *tmpModel;
+ GtkTreeIter tmpIter;
+ char *devName;
+ if (!GTK_IS_TREE_SELECTION(devSel)) { // Not initialised yet
+ return;
+ }
+ if (gtk_tree_selection_get_selected(devSel, &tmpModel, &tmpIter)) {
+ gtk_tree_model_get(tmpModel, &tmpIter, DEVICE_NAME_COLUMN, &devName, -1);
+ strcpy(dev,devName);
+ gtk_widget_set_sensitive(GTK_WIDGET(readBtn), TRUE);
+ gtk_widget_set_sensitive(GTK_WIDGET(writeBtn), TRUE);
+ g_free(devName);
+ } else { // Shouldn't ever happen, but just in case
+ dev[0] = '\0';
+ gtk_widget_set_sensitive(GTK_WIDGET(readBtn), FALSE);
+ gtk_widget_set_sensitive(GTK_WIDGET(writeBtn), FALSE);
+ }
+}
+///
+///Choose a file to open and call Load()
+void Fopen(GtkWidget *widget,GtkWidget *window)
+{
+ GetSelectedDevice();
+ if(progress) return;
+ progress=1;
+ GtkFileChooser *dialog;
+ dialog = (GtkFileChooser*) gtk_file_chooser_dialog_new (strings[I_Fopen], //"Open File"
+ GTK_WINDOW(window),
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ strings[I_CANCEL], GTK_RESPONSE_CANCEL,
+ strings[I_OPEN], GTK_RESPONSE_ACCEPT,
+ NULL);
+ if(cur_path) gtk_file_chooser_set_current_folder(dialog,cur_path);
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT){
+ char *filename;
+ filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
+ if(cur_path) free(cur_path);
+ cur_path = gtk_file_chooser_get_current_folder(dialog);
+ Load(dev,filename);
+ g_free (filename);
+ if(!strncmp(dev,"AT",2)){ //load EEPROM from separate file for ATMEL chips
+ GtkFileChooser *dialog2;
+ dialog2 = (GtkFileChooser*) gtk_file_chooser_dialog_new (strings[S_openEEfile],
+ GTK_WINDOW(window),
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ strings[I_CANCEL],GTK_RESPONSE_CANCEL,
+ strings[I_OPEN],GTK_RESPONSE_ACCEPT,
+ NULL);
+ if(!cur_pathEE) cur_pathEE = gtk_file_chooser_get_current_folder(dialog);
+ if(cur_pathEE) gtk_file_chooser_set_current_folder(dialog2,cur_pathEE);
+ if (gtk_dialog_run (GTK_DIALOG (dialog2)) == GTK_RESPONSE_ACCEPT){
+ char *filename2;
+ filename2 = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog2));
+ if(cur_pathEE) free(cur_pathEE);
+ cur_pathEE = gtk_file_chooser_get_current_folder(dialog2);
+ LoadEE(dev,filename2);
+ g_free (filename2);
+ }
+ gtk_widget_destroy(GTK_WIDGET(dialog2));
+ }
+ }
+ gtk_widget_destroy (GTK_WIDGET(dialog));
+ progress=0;
+}
+///
+///Choose a file to save and call Save()
+void Fsave(GtkWidget *widget,GtkWidget *window)
+{
+ if(progress) return;
+ progress=1;
+ GtkFileChooser *dialog;
+ dialog = (GtkFileChooser*) gtk_file_chooser_dialog_new (strings[I_Fsave], //"Save File",
+ GTK_WINDOW(window),
+ GTK_FILE_CHOOSER_ACTION_SAVE,
+ strings[I_CANCEL], GTK_RESPONSE_CANCEL,
+ strings[I_SAVE], GTK_RESPONSE_ACCEPT,
+ NULL);
+ if(cur_path) gtk_file_chooser_set_current_folder(dialog,cur_path);
+ gtk_file_chooser_set_do_overwrite_confirmation(dialog,TRUE);
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
+ {
+ char *filename;
+ filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
+ if(cur_path) free(cur_path);
+ cur_path = gtk_file_chooser_get_current_folder(dialog);
+ Save(dev,filename);
+ PrintMessage1(strings[S_FileSaved],filename);
+ g_free (filename);
+ if(!strncmp(dev,"AT",2)&&sizeEE){ //save EEPROM on separate file for ATMEL chips
+ GtkFileChooser *dialog2;
+ dialog2 = (GtkFileChooser*) gtk_file_chooser_dialog_new (strings[S_saveEEfile],
+ GTK_WINDOW(window),
+ GTK_FILE_CHOOSER_ACTION_SAVE,
+ strings[I_CANCEL], GTK_RESPONSE_CANCEL,
+ strings[I_SAVE], GTK_RESPONSE_ACCEPT,
+ NULL);
+ if(!cur_pathEE) cur_pathEE = gtk_file_chooser_get_current_folder(dialog);
+ if(cur_pathEE) gtk_file_chooser_set_current_folder(dialog2,cur_pathEE);
+ gtk_file_chooser_set_do_overwrite_confirmation(dialog2,TRUE);
+ if (gtk_dialog_run (GTK_DIALOG (dialog2)) == GTK_RESPONSE_ACCEPT){
+ char *filename2;
+ filename2 = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog2));
+ if(cur_pathEE) free(cur_pathEE);
+ cur_pathEE = gtk_file_chooser_get_current_folder(dialog2);
+ SaveEE(dev,filename2);
+ PrintMessage1(strings[S_FileSaved],filename2);
+ g_free (filename2);
+ }
+ gtk_widget_destroy(GTK_WIDGET(dialog2));
+ }
+ }
+ gtk_widget_destroy (GTK_WIDGET(dialog));
+ progress=0;
+}
+///
+///Select data tab
+void selectDataTab() { gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), 0); }
+///
+///Call device write function
+void DevWrite(GtkWidget *widget,GtkWidget *window)
+{
+#ifndef DEBUG
+ if(DeviceDetected!=1) return;
+#endif
+ selectDataTab();
+ gtk_statusbar_push(GTK_STATUSBAR(status_bar),statusID,"");
+ RWstop=0;
+ getOptions();
+ if(!waitingS1&&waitS1){
+ waitingS1=1;
+ int i,S1=0;
+ PrintMessage(strings[I_PRESSS1]); //"press S1 to start"
+ for(i=0;!S1&&waitS1&&waitingS1;i++){
+ S1=CheckS1();
+ msDelay(50);
+ PrintMessage(".");
+ if(i%64==63) PrintMessage(strings[S_NL]); //"\n"
+ while (gtk_events_pending ()) gtk_main_iteration(); //handle UI events, including write button
+ msDelay(50);
+ }
+ PrintMessage(strings[S_NL]); //"\n"
+ if(!progress&&S1){
+ gtk_widget_set_sensitive(stopBtn,TRUE);
+ progress=1;
+ Write(dev,ee); //choose the right function
+ progress=0;
+ gtk_widget_set_sensitive(stopBtn,FALSE);
+ }
+ waitingS1=0;
+ }
+ else if(waitingS1) waitingS1=0;
+ else if(!progress){
+ gtk_widget_set_sensitive(stopBtn,TRUE);
+ progress=1;
+ Write(dev,ee); //choose the right function
+ progress=0;
+ gtk_widget_set_sensitive(stopBtn,FALSE);
+ }
+}
+///
+///Call device read function
+void DevRead(GtkWidget *widget,GtkWidget *window)
+{
+#ifndef DEBUG
+ if(DeviceDetected!=1) return;
+#endif
+ selectDataTab();
+ gtk_statusbar_push(GTK_STATUSBAR(status_bar),statusID,"");
+ getOptions();
+ RWstop=0;
+ if(!waitingS1&&waitS1){
+ waitingS1=1;
+ int i,S1=0;
+ PrintMessage(strings[I_PRESSS1]); //"press S1 to start"
+ for(i=0;!S1&&waitS1&&waitingS1;i++){
+ S1=CheckS1();
+ msDelay(50);
+ PrintMessage(".");
+ if(i%64==63) PrintMessage(strings[S_NL]); //"\n"
+ while (gtk_events_pending ()) gtk_main_iteration(); //handle UI events, including write button
+ msDelay(50);
+ }
+ PrintMessage(strings[S_NL]); //"\n"
+ if(!progress&&S1){
+ gtk_widget_set_sensitive(stopBtn,TRUE);
+ progress=1;
+ Read(dev,ee,readRes); //choose the right function
+ progress=0;
+ gtk_widget_set_sensitive(stopBtn,FALSE);
+ }
+ waitingS1=0;
+ }
+ else if(waitingS1) waitingS1=0;
+ else if(!progress){
+ gtk_widget_set_sensitive(stopBtn,TRUE);
+ progress=1;
+ Read(dev,ee,readRes); //choose the right function
+ progress=0;
+ gtk_widget_set_sensitive(stopBtn,FALSE);
+ }
+}
+///
+/// Write fuse low byte at low frequency
+void WriteATfuseLowLF(GtkWidget *widget,GtkWidget *window){
+#ifndef DEBUG
+ if(DeviceDetected!=1) return;
+#endif
+ if(progress) return;
+ getOptions();
+ if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(AVR_FuseLowWrite))){
+ progress=1;
+ if(AVRfuse<0x100) WriteATfuseSlow(AVRfuse);
+ progress=0;
+ }
+}
+///
+///Callback function to set available options for each device type
+void onDevSel_Changed(GtkWidget *widget,GtkWidget *window)
+{
+ struct DevInfo info;
+ char str2[256],str3[64],strF[32];
+ double x;
+ GetSelectedDevice();
+ if (strlen(dev) == 0) return; // None selected
+ info=GetDevInfo(dev);
+ sprintf(str, "<b>%s: %s</b>", strings[I_Dev], dev);
+ gtk_label_set_markup(GTK_LABEL(devFrame), str);
+ devType=info.family;
+ gtk_label_set_text(GTK_LABEL(devinfo),info.features);
+ if(devType==PIC12||devType==PIC16||devType==PIC18||devType==PIC24){
+ gtk_widget_show_all(GTK_WIDGET(devFramePIC));
+ gtk_widget_hide(GTK_WIDGET(devFrameAVR));
+ gtk_widget_show_all(GTK_WIDGET(EEPROM_RW));
+ }
+ else if(devType==AVR){ //ATMEL
+ gtk_widget_hide(GTK_WIDGET(devFramePIC));
+ gtk_widget_show_all(GTK_WIDGET(devFrameAVR));
+ gtk_widget_show_all(GTK_WIDGET(EEPROM_RW));
+ }
+ else{
+ gtk_widget_hide(GTK_WIDGET(devFramePIC));
+ gtk_widget_hide(GTK_WIDGET(devFrameAVR));
+ gtk_widget_hide(GTK_WIDGET(EEPROM_RW));
+ }
+ if(devType==PIC16) //ICD
+ gtk_widget_show_all(GTK_WIDGET(devFrameICD));
+ else gtk_widget_hide(GTK_WIDGET(devFrameICD));
+ if(devType==PIC12||devType==PIC16) //Osc options
+ gtk_widget_show_all(GTK_WIDGET(devFrameOsc));
+ else gtk_widget_hide(GTK_WIDGET(devFrameOsc));
+ if(devType==PIC12||devType==PIC16||devType==PIC18) //program ID
+ gtk_widget_show_all(GTK_WIDGET(Write_ID_BKCal));
+ else gtk_widget_hide(GTK_WIDGET(Write_ID_BKCal));
+ if(devType==PIC16) //Program Calib
+ gtk_widget_show_all(GTK_WIDGET(WriteCalib12));
+ else gtk_widget_hide(GTK_WIDGET(WriteCalib12));
+ if(devType==PIC12||devType==PIC16||devType==PIC18){ //Force config
+ gtk_widget_show_all(GTK_WIDGET(devFrameConfigW));
+ gtk_widget_hide(GTK_WIDGET(devPIC_CW2));
+ gtk_widget_hide(GTK_WIDGET(devPIC_CW3));
+ gtk_widget_hide(GTK_WIDGET(devPIC_CW4));
+ gtk_widget_hide(GTK_WIDGET(devPIC_CW5));
+ gtk_widget_hide(GTK_WIDGET(devPIC_CW6));
+ gtk_widget_hide(GTK_WIDGET(devPIC_CW7));
+ gtk_widget_hide(GTK_WIDGET(devPIC_CW8));
+ if(devType==PIC16){
+ gtk_widget_show_all(GTK_WIDGET(devPIC_CW2));
+ }
+ else if(devType==PIC18){
+ gtk_widget_show_all(GTK_WIDGET(devPIC_CW2));
+ gtk_widget_show_all(GTK_WIDGET(devPIC_CW3));
+ gtk_widget_show_all(GTK_WIDGET(devPIC_CW4));
+ gtk_widget_show_all(GTK_WIDGET(devPIC_CW5));
+ gtk_widget_show_all(GTK_WIDGET(devPIC_CW6));
+ gtk_widget_show_all(GTK_WIDGET(devPIC_CW7));
+ gtk_widget_show_all(GTK_WIDGET(devPIC_CW8));
+ }
+ }
+ else{
+ gtk_widget_hide(GTK_WIDGET(devFrameConfigW));
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ConfigForce),FALSE);
+ }
+ gtk_statusbar_push(GTK_STATUSBAR(status_bar),statusID,dev);
+}
+/// Walk the TreeModel until we find an entry with the passed device name
+/// Select that entry and then stop walking
+gboolean selectDev_ForeachFunc(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, char *devNameToSelect) {
+ char *thisEntryDevName;
+ gtk_tree_model_get(model, iter, DEVICE_NAME_COLUMN, &thisEntryDevName, -1);
+ int matched = (strcmp(thisEntryDevName, devNameToSelect) == 0);
+ if (matched) gtk_tree_selection_select_iter(devSel, iter);
+ g_free(thisEntryDevName);
+ return matched;
+}
+///
+/// Comparison function used when sorting the device tree
+int sortIterCompareFunc(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer userdata) {
+ enum sort_type_t sortcol = GPOINTER_TO_INT(userdata);
+ int ret = 0;
+ enum sort_data_type_t sortDataType;
+ int dataCol;
+ switch (sortcol) {
+ case SORT_STRING_NAME:
+ sortDataType = SDT_STRING;
+ dataCol = DEVICE_NAME_COLUMN;
+ break;
+ case SORT_STRING_GROUP:
+ sortDataType = SDT_STRING;
+ dataCol = DEVICE_GROUP_COLUMN;
+ break;
+ default:
+ return 0;
+ }
+ switch (sortDataType) {
+ case SDT_STRING:
+ {
+ char *nameA, *nameB;
+ gtk_tree_model_get(model, a, dataCol, &nameA, -1);
+ gtk_tree_model_get(model, b, dataCol, &nameB, -1);
+ if (nameA == NULL || nameB == NULL) {
+ if (nameA == NULL && nameB == NULL) break; // Both null. return 0 (no need to free)
+ ret = (nameA == NULL) ? -1 : 1;
+ }
+ else {
+ ret = g_utf8_collate(nameA,nameB);
+ }
+ g_free(nameA);
+ g_free(nameB);
+ break;
+ }
+ default:
+ g_return_val_if_reached(0);
+ }
+ return ret;
+}
+///
+///Add devices to the device ListStore (which may not have been created)
+///groupFilter: add devices in this group (-1 for all)
+///textFilter: only add devices containing this string (NULL for all)
+void AddDevices(enum group_t groupFilter, const char *textFilter) {
+ if (GTK_IS_TREE_SELECTION(devSel))
+ g_signal_handlers_disconnect_by_func(G_OBJECT(devSel),G_CALLBACK(onDevSel_Changed),NULL);
+ if (!GTK_IS_LIST_STORE(devStore)) {
+ devStore = gtk_list_store_new (DEVICE_N_COLUMNS,
+ G_TYPE_UINT,
+ G_TYPE_STRING,
+ G_TYPE_STRING);
+ gtk_tree_view_set_model(GTK_TREE_VIEW(devTree), GTK_TREE_MODEL(devStore));
+ gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(devStore), SORT_STRING_NAME,
+ sortIterCompareFunc, GINT_TO_POINTER(SORT_STRING_NAME), NULL);
+ gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(devStore), SORT_STRING_GROUP,
+ sortIterCompareFunc, GINT_TO_POINTER(SORT_STRING_GROUP), NULL);
+ gtk_tree_view_column_set_sort_column_id(
+ gtk_tree_view_get_column(GTK_TREE_VIEW(devTree), 0), SORT_STRING_NAME);
+ gtk_tree_view_column_set_sort_column_id(
+ gtk_tree_view_get_column(GTK_TREE_VIEW(devTree), 1), SORT_STRING_GROUP);
+ g_object_unref (G_OBJECT(devStore));
+ }
+ else gtk_list_store_clear(devStore);
+ int i,j=0;
+ char *devices=0,*tok;
+ for(i=0;i<NDEVLIST;i++) {
+ if(devices) free(devices);
+ devices=malloc(strlen(DEVLIST[i].device)+1);
+ strcpy(devices,DEVLIST[i].device);
+ struct DevInfo info;
+ populateDevInfo(&info, &(DEVLIST[i]));
+ for(tok=strtok(devices,", \t");tok;tok=strtok(NULL,", \t")) {
+ //info.device=malloc(strlen(tok)+1);
+ //strcpy(info.device,tok);
+ info.group=nameToGroup(tok);
+ if(info.group!=-1&&(!textFilter || strlen(textFilter) == 0 || strstr(tok, textFilter)) &&
+ (groupFilter == -1 || info.group == groupFilter)) {
+ gtk_list_store_insert_with_values(devStore, NULL, -1,
+ DEVICE_ID_COLUMN, j++,
+ DEVICE_NAME_COLUMN, tok,
+ DEVICE_GROUP_COLUMN, groupNames[info.group], -1);
+ }
+ }
+ }
+ free(devices);
+ if(GTK_IS_TREE_SELECTION(devSel)) {
+ gtk_tree_selection_unselect_all(devSel);
+ }
+ else {
+ devSel = gtk_tree_view_get_selection(GTK_TREE_VIEW(devTree));
+ gtk_tree_selection_set_mode(devSel, GTK_SELECTION_SINGLE);
+ }
+ g_signal_connect(G_OBJECT(devSel),"changed",G_CALLBACK(onDevSel_Changed),NULL);
+ gtk_tree_model_foreach(GTK_TREE_MODEL(devStore),
+ (GtkTreeModelForeachFunc)selectDev_ForeachFunc,
+ dev);
+}
+///
+///Filter device list (in gtk_tree) according to type selected
+void FilterDevType(GtkWidget *widget,GtkWidget *window)
+{
+ char *selGroupName = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(devTypeCombo));
+ const char *filtText = gtk_entry_get_text(GTK_ENTRY(devFiltEntry));
+ enum group_t selGroup = -1;
+ for (int i=0; i<NUM_GROUPS; i++) {
+ if (strcmp(selGroupName, groupNames[i]) == 0) {
+ selGroup = i;
+ i = NUM_GROUPS;
+ }
+ }
+ // If no specific group selected, ALL should be selected
+ if (selGroup == -1 && strcmp(GROUP_ALL, selGroupName)) {
+ PrintMessage1("ERR: group name '%s' invalid", selGroupName);
+ return;
+ }
+ AddDevices(selGroup, filtText);
+ g_free(selGroupName);
+ onDevSel_Changed(NULL, NULL);
+}
+///
+/// Check or set IO signals according to IO tab controls
+void IOchanged(GtkWidget *widget,GtkWidget *window)
+{
+ if(progress) return;
+#ifndef DEBUG
+ if(DeviceDetected!=1) return;
+#endif
+ if(!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_io_active))) return;
+ int i,j=0;
+ int trisa=1,trisb=0,trisc=0x30,latac=0,latb=0;
+ int port=0,z;
+ //char str[128]="IO:";
+ char s2[64];
+ str[0]=0;
+ for(i=0;i<sizeof(ioButtons)/sizeof(ioButtons[0]);i++){
+ if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ioButtons[i].r_0))){
+ //strcat(str,"0");
+ }
+ else if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ioButtons[i].r_1))){
+ //strcat(str,"1");
+ if(i<8) latb|=1<<i;
+ else if(i==8) latac|=0x80; //RC7
+ else if(i==9) latac|=0x40; //RC6
+ else if(i==10) latac|=0x20; //RA5
+ else if(i==11) latac|=0x10; //RA4
+ else if(i==12) latac|=0x08; //RA3
+ }
+ else if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ioButtons[i].r_I))){
+ //strcat(str,"I");
+ if(i<8) trisb|=1<<i;
+ else if(i==8) trisc|=0x80; //RC7
+ else if(i==9) trisc|=0x40; //RC6
+ else if(i==10) trisa|=0x20; //RA5
+ else if(i==11) trisa|=0x10; //RA4
+ else if(i==12) trisa|=0x8; //RA3
+ }
+ }
+ //sprintf(s2," trisb=%02X latb=%02X trisc=%02X trisa=%02X latac=%02X",trisb,latb,trisc,trisa,latac);
+ //strcat(str,s2);
+ //gtk_statusbar_push(GTK_STATUSBAR(status_bar),statusID,str);
+ bufferU[j++]=READ_RAM;
+ bufferU[j++]=0x0F;
+ bufferU[j++]=0x80; //PORTA
+ bufferU[j++]=READ_RAM;
+ bufferU[j++]=0x0F;
+ bufferU[j++]=0x81; //PORTB
+ bufferU[j++]=READ_RAM;
+ bufferU[j++]=0x0F;
+ bufferU[j++]=0x82; //PORTC
+ bufferU[j++]=WRITE_RAM;
+ bufferU[j++]=0x0F;
+ bufferU[j++]=0x92; //TRISA
+ bufferU[j++]=trisa;
+ bufferU[j++]=WRITE_RAM;
+ bufferU[j++]=0x0F;
+ bufferU[j++]=0x93; //TRISB
+ bufferU[j++]=trisb;
+ bufferU[j++]=WRITE_RAM;
+ bufferU[j++]=0x0F;
+ bufferU[j++]=0x94; //TRISC
+ bufferU[j++]=trisc;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=latb;
+ bufferU[j++]=latac;
+ bufferU[j++]=READ_ADC;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ for(z=0;z<DIMBUF-3&&bufferI[z]!=READ_RAM;z++);
+ port=bufferI[z+3]; //PORTA
+ //sprintf(s2," porta=%02X",port);
+ //strcat(str,s2);
+ //gtk_statusbar_push(GTK_STATUSBAR(status_bar),statusID,str);
+ gtk_label_set_text(GTK_LABEL(ioButtons[10].e_I),(port&0x20)?"1":"0");
+ gtk_label_set_text(GTK_LABEL(ioButtons[11].e_I),(port&0x10)?"1":"0");
+ gtk_label_set_text(GTK_LABEL(ioButtons[12].e_I),(port&0x8)?"1":"0");
+ for(z+=4;z<DIMBUF-3&&bufferI[z]!=READ_RAM;z++);
+ port=bufferI[z+3]; //PORTB
+ for(i=0;i<8;i++) gtk_label_set_text(GTK_LABEL(ioButtons[i].e_I),(port&(1<<i))?"1":"0");
+ for(z+=4;z<DIMBUF-3&&bufferI[z]!=READ_RAM;z++);
+ port=bufferI[z+3]; //PORTC
+ gtk_label_set_text(GTK_LABEL(ioButtons[8].e_I),(port&0x80)?"1":"0");
+ gtk_label_set_text(GTK_LABEL(ioButtons[9].e_I),(port&0x40)?"1":"0");
+ for(z+=4;z<DIMBUF-2&&bufferI[z]!=READ_ADC;z++);
+ double vpp=((bufferI[z+1]<<8)+bufferI[z+2])/1024.0*5*34/12; //VPP
+ sprintf(str,"VPP=%.2fV",vpp);
+ gtk_statusbar_push(GTK_STATUSBAR(status_bar),statusID,str);
+ return;
+}
+///
+/// Start/stop timer to check for IO status
+void IOactive(GtkWidget *widget,GtkWidget *window)
+{
+ if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_io_active))&&!icdTimer){
+ IOTimer=g_timeout_add(100,(GSourceFunc)IOchanged,NULL);
+ }
+ else if(IOTimer){
+ g_source_remove(IOTimer);
+ }
+}
+///
+/// Enable/disable VPP and VCC from IO tab
+void VPPVDDactive(GtkWidget *widget,GtkWidget *window)
+{
+#ifndef DEBUG
+ if(DeviceDetected!=1) return;
+#endif
+ int j=0,vdd_vpp=0;
+ char str[16]="";
+ if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(VPP_ON))){
+ vdd_vpp+=4;
+ strcat(str,"VPP ");
+ }
+ if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(VDD_ON))){
+ vdd_vpp+=1;
+ strcat(str,"VDD ");
+ }
+ gtk_statusbar_push(GTK_STATUSBAR(status_bar),statusID,str);
+ bufferU[j++]=EN_VPP_VCC; //VDD+VPP
+ bufferU[j++]=vdd_vpp;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+}
+///
+/// Enable/disable DCDC from IO tab or update DCDC voltage
+void DCDCactive(GtkWidget *widget,GtkWidget *window)
+{
+#ifndef DEBUG
+ if(DeviceDetected!=1) return;
+#endif
+ if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(DCDC_ON))){
+ int j=0,vreg=0;
+ char str[16];
+ double voltage=gtk_range_get_value(GTK_RANGE(DCDC_voltage));
+ vreg=voltage*10.0;
+ sprintf(str,"DCDC %.1fV",voltage);
+ gtk_statusbar_push(GTK_STATUSBAR(status_bar),statusID,str);
+ bufferU[j++]=VREG_EN; //enable HV regulator
+ bufferU[j++]=SET_VPP;
+ bufferU[j++]=vreg;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ }
+ else{
+ int j=0;
+ bufferU[j++]=VREG_DIS; //disable HV regulator
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ }
+}
+///
+/// convert hex line
+void HexConvert(GtkWidget *widget,GtkWidget *window)
+{
+ char hex[256],str[256],s2[32];
+ int i,address,length,sum=0;
+ strncpy(hex,(const char *)gtk_entry_get_text(GTK_ENTRY(Hex_entry)),sizeof(hex));
+ if(strlen(hex)>0){
+ if(hex[0]==':'&&strlen(hex)>8){
+ length=htoi(hex+1,2);
+ address=htoi(hex+3,4);
+ if(strlen(hex)<11+length*2) gtk_entry_set_text(GTK_ENTRY(Hex_data),"__line too short");
+ else{
+ for (i=1;i<=length*2+9;i+=2) sum += htoi(hex+i,2);
+ if ((sum & 0xff)!=0){
+ sprintf(str,"__checksum error, expected 0x%02X",(-sum+htoi(hex+9+length*2,2))&0xFF);
+ gtk_entry_set_text(GTK_ENTRY(Hex_data),str);
+ }
+ else{
+ switch(htoi(hex+7,2)){
+ case 0: //Data record
+ sprintf(str,"address: 0x%04X ",address);
+ if(i&&length) strcat(str,"data: 0x");
+ for (i=0;i<length;i++){
+ sprintf(s2,"%02X",htoi(hex+9+i*2,2));
+ strcat(str,s2);
+ }
+ gtk_entry_set_text(GTK_ENTRY(Hex_data),str);
+ break;
+ case 4: //extended linear address record
+ if(strlen(hex)>14){
+ sprintf(str,"extended linear address = %04X",htoi(hex+9,4));
+ gtk_entry_set_text(GTK_ENTRY(Hex_data),str);
+ }
+ break;
+ default:
+ gtk_entry_set_text(GTK_ENTRY(Hex_data),"__unknown record type");
+ break;
+ }
+ }
+ }
+ }
+ else gtk_entry_set_text(GTK_ENTRY(Hex_data),"__invalid line");
+ }
+ else gtk_entry_set_text(GTK_ENTRY(Hex_entry),"");
+}
+///
+/// convert address & data to hex line
+void DataToHexConvert(GtkWidget *widget,GtkWidget *window)
+{
+ char hex[256],str[256],s2[32];
+ int i,address,length,sum=0,x;
+ i=sscanf(gtk_entry_get_text(GTK_ENTRY(Address_entry)),"%x",&address);
+ if(i!=1) address=0;
+ strncpy(hex,(const char *)gtk_entry_get_text(GTK_ENTRY(Data_entry)),sizeof(hex));
+ length=strlen(hex);
+ length&=0xFF;
+ if(length>0){
+ sprintf(str,":--%04X00",address&0xFFFF);
+ for(i=0;i+1<length;i+=2){
+ x=htoi(hex+i,2);
+ //x&=0xFF;
+ sum+=x;
+ sprintf(s2,"%02X",x);
+ strcat(str,s2);
+ }
+ sprintf(s2,"%02X",i/2);
+ str[1]=s2[0];
+ str[2]=s2[1];
+ x=sum;
+ sum+=i/2+(address&0xff)+((address>>8)&0xff);
+ sprintf(s2,"%02X",(-sum)&0xFF);
+ strcat(str,s2);
+ gtk_entry_set_text(GTK_ENTRY(Hex_data2),str);
+ }
+}
+///
+///Choose a file to save a hex line
+void HexSave(GtkWidget *widget,GtkWidget *window)
+{
+ GtkFileChooser *dialog;
+ if(strlen((const char *)gtk_entry_get_text(GTK_ENTRY(Hex_data2)))<11) return;
+ dialog = (GtkFileChooser*) gtk_file_chooser_dialog_new (strings[I_Fsave], //"Save File",
+ GTK_WINDOW(window),
+ GTK_FILE_CHOOSER_ACTION_SAVE,
+ strings[I_CANCEL], GTK_RESPONSE_CANCEL,
+ strings[I_SAVE], GTK_RESPONSE_ACCEPT,
+ NULL);
+ if(cur_path) gtk_file_chooser_set_current_folder(dialog,cur_path);
+ gtk_file_chooser_set_do_overwrite_confirmation(dialog,TRUE);
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
+ {
+ char *filename;
+ filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
+ if(cur_path) free(cur_path);
+ cur_path = gtk_file_chooser_get_current_folder(dialog);
+ FILE* f=fopen(filename,"w");
+ if(f){
+ fprintf(f,(const char *)gtk_entry_get_text(GTK_ENTRY(Hex_data2)));
+ fclose(f);
+ }
+ g_free (filename);
+ }
+ gtk_widget_destroy (GTK_WIDGET(dialog));
+}
+///
+/// Stop read or write
+void Stop(GtkWidget *widget,GtkWidget *window)
+{
+#ifndef DEBUG
+ if(DeviceDetected!=1) return;
+#endif
+ if(progress==1&&RWstop==0){
+ RWstop=1;
+ PrintMessage(strings[I_STOP]);
+ }
+}
+///
+///Close program
+void Xclose(){
+// char *str=gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(devCombo));
+// if(str) strncpy(dev,str,sizeof(dev)-1);
+ gtk_main_quit();
+}
+///
+/// Show a message box
+void MsgBox(const char* msg)
+{
+ GtkWidget * dialog = gtk_message_dialog_new (GTK_WINDOW(window),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_INFO,
+ GTK_BUTTONS_OK,
+ msg);
+ gtk_window_set_title(GTK_WINDOW(dialog)," ");
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+}
+///
+/// Find the programmer and setup communication
+void Connect(GtkWidget *widget,GtkWidget *window){
+ vid=htoi(gtk_entry_get_text(GTK_ENTRY(VID_entry)),4);
+ pid=htoi(gtk_entry_get_text(GTK_ENTRY(PID_entry)),4);
+ DeviceDetected=FindDevice(vid,pid); //connect to USB programmer
+ if(!DeviceDetected){
+ DeviceDetected=FindDevice(new_vid,new_pid); //try default
+ if(DeviceDetected){
+ vid=new_vid;
+ pid=new_pid;
+ }
+ }
+ if(!DeviceDetected) DeviceDetected=FindDevice(old_vid,old_pid); //try old one
+ hvreg=0;
+ ProgID();
+}
+///
+/// I2C/SPI receive
+void I2cspiR()
+{
+ //if(DeviceDetected!=1) return;
+ gtk_statusbar_push(GTK_STATUSBAR(status_bar),statusID,"");
+ saveLog = (int) gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_log));
+ int nbyte=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(I2CNbyte));
+ if(nbyte<0) nbyte=0;
+ if(nbyte>60) nbyte=60;
+ int mode=0;
+ if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(I2C16bit))) mode=1; //I2C mode
+ if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(SPI00))) mode=2; //SPI mode 00
+ if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(SPI01))) mode=3; //SPI mode 01
+ if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(SPI10))) mode=4; //SPI mode 10
+ if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(SPI11))) mode=5; //SPI mode 11
+ char* tok;
+ char tokbuf[512];
+ BYTE tmpbuf[128];
+ int i=0,x;
+ strncpy(tokbuf, (const char *)gtk_entry_get_text(GTK_ENTRY(I2CDataSend)), sizeof(tokbuf));
+ for(tok=strtok(tokbuf," ");tok&&i<128;tok=strtok(NULL," ")){
+ if(sscanf(tok,"%x",&x)){
+ tmpbuf[i] = (BYTE)x;
+ i++;
+ }
+ }
+ for(;i<128;i++) tmpbuf[i]=0;
+ I2CReceive(mode,gtk_combo_box_get_active(GTK_COMBO_BOX(I2CSpeed)),nbyte,tmpbuf);
+}
+///
+/// I2C/SPI send
+void I2cspiS()
+{
+ //if(DeviceDetected!=1) return;
+ gtk_statusbar_push(GTK_STATUSBAR(status_bar),statusID,"");
+ saveLog = (int) gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_log));
+ int nbyte=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(I2CNbyte));
+ if(nbyte<0) nbyte=0;
+ if(nbyte>57) nbyte=57;
+ int mode=0;
+ if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(I2C16bit))) mode=1; //I2C mode
+ if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(SPI00))) mode=2; //SPI mode 00
+ if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(SPI01))) mode=3; //SPI mode 01
+ if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(SPI10))) mode=4; //SPI mode 10
+ if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(SPI11))) mode=5; //SPI mode 11
+ char* tok;
+ char tokbuf[512];
+ BYTE tmpbuf[128];
+ int i=0,x;
+ strncpy(tokbuf, (const char *)gtk_entry_get_text(GTK_ENTRY(I2CDataSend)), sizeof(tokbuf));
+ for(tok=strtok(tokbuf," ");tok&&i<128;tok=strtok(NULL," ")){
+ if(sscanf(tok,"%x",&x)){
+ tmpbuf[i] = (BYTE)x;
+ i++;
+ }
+ }
+ for(;i<128;i++) tmpbuf[i]=0;
+ I2CSend(mode,gtk_combo_box_get_active(GTK_COMBO_BOX(I2CSpeed)),nbyte,tmpbuf);
+}
+///
+/// send manual command
+void CommandIO()
+{
+ if(DeviceDetected!=1) return;
+ gtk_statusbar_push(GTK_STATUSBAR(status_bar),statusID,"");
+ saveLog = (int) gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_log));
+ char* tok;
+ char tokbuf[512],str[16];
+ int i=0,x;
+ strncpy(tokbuf, (const char *)gtk_entry_get_text(GTK_ENTRY(commandSend)), sizeof(tokbuf));
+ for(tok=strtok(tokbuf," ");tok&&i<DIMBUF;tok=strtok(NULL," ")){
+ if(sscanf(tok,"%x",&x)){
+ bufferU[i] = (BYTE)x;
+ i++;
+ }
+ }
+ for(;i<DIMBUF;i++) bufferU[i]=0x0;
+ PacketIO(150);
+ sprintf(tokbuf,">[");
+ for(i=0;i<DIMBUF;i++){
+ sprintf(str," %02X",bufferU[i]);
+ strcat(tokbuf,str);
+ if(i%32==31&&i!=DIMBUF-1)strcat(tokbuf,"\n ");
+ }
+ strcat(tokbuf," ]\n<[");
+ for(i=0;i<DIMBUF;i++){
+ sprintf(str," %02X",bufferI[i]);
+ strcat(tokbuf,str);
+ if(i%32==31&&i!=DIMBUF-1)strcat(tokbuf,"\n ");
+ }
+ strcat(tokbuf," ]");
+ PrintMessageCMD(tokbuf);
+}
+///
+///Display contents of EEprom memory
+void DisplayEE(){
+ char s[256],t[256],v[256],*aux,*g;
+ int valid=0,empty=1,lines=0;
+ int i,j,max;
+ s[0]=0;
+ v[0]=0;
+ aux=malloc((sizeEE/COL+1)*(16+COL*5));
+ aux[0]=0;
+ PrintMessage(strings[S_EEMem]); //"\r\nEEPROM memory:\r\n"
+ max=sizeEE>7000?7000:sizeEE;
+ for(i=0;i<max;i+=COL){
+ valid=0;
+ for(j=i;j<i+COL&&j<sizeEE;j++){
+ sprintf(t,"%02X ",memEE[j]);
+ strcat(s,t);
+ sprintf(t,"%c",isprint(memEE[j])&&(memEE[j]<0xFF)?memEE[j]:'.');
+ g=g_locale_to_utf8(t,-1,NULL,NULL,NULL);
+ if(g) strcat(v,g);
+ g_free(g);
+ if(memEE[j]<0xff) valid=1;
+ }
+ if(valid){
+ sprintf(t,"%04X: %s %s\r\n",i,s,v);
+ strcat(aux,t);
+ empty=0;
+ lines++;
+ if(lines>500){ //limit number of lines printed
+ strcat(aux,"(...)\r\n");
+ i=max-COL*2;
+ lines=490;
+ }
+ }
+ s[0]=0;
+ v[0]=0;
+ }
+ if(empty) PrintMessage(strings[S_Empty]); //empty
+ else{
+ PrintMessage(aux);
+ if(sizeEE>max) PrintMessage("(...)\r\n");
+ }
+ free(aux);
+}
+///
+///Start HV regulator
+int StartHVReg(double V){
+ int j=0,z;
+ int vreg=(int)(V*10.0);
+ if(saveLog&&logfile) fprintf(logfile,"StartHVReg(%.2f)\n",V);
+ DWORD t0,t;
+ if(V==-1){
+ bufferU[j++]=VREG_DIS; //disable HV regulator
+ bufferU[j++]=FLUSH;
+ PacketIO(5);
+ msDelay(40);
+ return -1;
+ }
+ t=t0=GetTickCount();
+ bufferU[j++]=VREG_EN; //enable HV regulator
+ bufferU[j++]=SET_VPP;
+ bufferU[j++]=vreg;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2000>>8;
+ bufferU[j++]=2000&0xff;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=READ_ADC;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ msDelay(20);
+ for(z=0;z<DIMBUF-2&&bufferI[z]!=READ_ADC;z++);
+ int v=(bufferI[z+1]<<8)+bufferI[z+2];
+// PrintMessage2("v=%d=%fV\n",v,v/G);
+ if(v==0){
+ PrintMessage(strings[S_lowUsbV]); //"Tensione USB troppo bassa (VUSB<4.5V)\r\n"
+ return 0;
+ }
+ j=0;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=READ_ADC;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ for(;(v<(vreg/10.0-1)*G||v>(vreg/10.0+1)*G)&&t<t0+1500;t=GetTickCount()){
+ PacketIO(5);
+ msDelay(20);
+ for(z=0;z<DIMBUF-2&&bufferI[z]!=READ_ADC;z++);
+ v=(bufferI[z+1]<<8)+bufferI[z+2];
+ if(HwID==3) v>>=2; //if 12 bit ADC
+// PrintMessage2("v=%d=%fV\n",v,v/G);
+ }
+ if(v>(vreg/10.0+1)*G){
+ PrintMessage(strings[S_HiVPP]); //"Attenzione: tensione regolatore troppo alta\r\n\r\n"
+ return 0;
+ }
+ else if(v<(vreg/10.0-1)*G){
+ PrintMessage(strings[S_LowVPP]); //"Attenzione: tensione regolatore troppo bassa\r\n\r\n"
+ return 0;
+ }
+ else if(v==0){
+ PrintMessage(strings[S_lowUsbV]); //"Tensione USB troppo bassa (VUSB<4.5V)\r\n"
+ return 0;
+ }
+ else{
+ PrintMessage2(strings[S_reg],t-t0,v/G); //"Regolatore avviato e funzionante dopo T=%d ms VPP=%.1f\r\n\r\n"
+ if(saveLog&&logfile) fprintf(logfile,strings[S_reg],t-t0,v/G);
+ return vreg;
+ }
+}
+///
+///Read programmer ID
+void ProgID()
+{
+ if(DeviceDetected!=1) return;
+ int j=0;
+ bufferU[j++]=PROG_RST;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ for(j=0;j<DIMBUF-7&&bufferI[j]!=PROG_RST;j++);
+ PrintMessage3(strings[S_progver],bufferI[j+1],bufferI[j+2],bufferI[j+3]); //"FW versione %d.%d.%d\r\n"
+ FWVersion=(bufferI[j+1]<<16)+(bufferI[j+2]<<8)+bufferI[j+3];
+ PrintMessage3(strings[S_progid],bufferI[j+4],bufferI[j+5],bufferI[j+6]); //"ID Hw: %d.%d.%d"
+ HwID=bufferI[j+6];
+ if(HwID==1) PrintMessage(" (18F2550)\r\n\r\n");
+ else if(HwID==2) PrintMessage(" (18F2450)\r\n\r\n");
+ else if(HwID==3) PrintMessage(" (18F2458/2553)\r\n\r\n");
+ else if(HwID==4) PrintMessage(" (18F25K50)\r\n\r\n");
+ else PrintMessage(" (?)\r\n\r\n");
+}
+///
+///Check if a 3.3V regulator is present
+int CheckV33Regulator()
+{
+ int i,j=0;
+ if(skipV33check) return 1;
+ bufferU[j++]=WRITE_RAM;
+ bufferU[j++]=0x0F;
+ bufferU[j++]=0x93;
+ bufferU[j++]=0xFE; //B0 = output
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0x01; //B0=1
+ bufferU[j++]=0;
+ bufferU[j++]=READ_RAM;
+ bufferU[j++]=0x0F;
+ bufferU[j++]=0x81; //Check if B1=1
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0x00; //B0=0
+ bufferU[j++]=0;
+ bufferU[j++]=READ_RAM;
+ bufferU[j++]=0x0F;
+ bufferU[j++]=0x81; //Check if B1=0
+ bufferU[j++]=WRITE_RAM;
+ bufferU[j++]=0x0F;
+ bufferU[j++]=0x93;
+ bufferU[j++]=0xFF; //BX = input
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ for(j=0;j<DIMBUF-3&&bufferI[j]!=READ_RAM;j++);
+ i=bufferI[j+3]&0x2; //B1 should be high
+ for(j+=3;j<DIMBUF-3&&bufferI[j]!=READ_RAM;j++);
+ return (i+(bufferI[j+3]&0x2))==2?1:0;
+}
+///
+///Check if S1 is pressed
+int CheckS1()
+{
+ int i,j=0;
+ bufferU[j++]=READ_RAM;
+ bufferU[j++]=0x0F;
+ bufferU[j++]=0x84; //READ PORTE
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ for(j=0;j<DIMBUF-3&&bufferI[j]!=READ_RAM;j++);
+ i=bufferI[j+3]&0x8; //i=E3
+ return i?0:1; //S1 open -> E3=1
+}
+///
+///Execute hardware test
+void TestHw(GtkWidget *widget,GtkWindow* parent)
+{
+#ifndef DEBUG
+ if(DeviceDetected!=1) return;
+#endif
+ char str[256];
+ StartHVReg(13);
+ int j=0;
+ MsgBox(strings[I_TestHW]); //"Test hardware ..."
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=EN_VPP_VCC; //VDD+VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ strcpy(str,strings[I_TestMSG]);
+ strcat(str,"\n VDDU=5V\n VPPU=13V\n PGD(RB5)=0V\n PGC(RB6)=0V\n PGM(RB7)=0V");
+ MsgBox(str);
+ j=0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x15;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x1; //VDD
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ strcpy(str,strings[I_TestMSG]);
+ strcat(str,"\n VDDU=5V\n VPPU=0V\n PGD(RB5)=5V\n PGC(RB6)=5V\n PGM(RB7)=5V");
+ MsgBox(str);
+ j=0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x4; //VPP
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ strcpy(str,strings[I_TestMSG]);
+ strcat(str,"\n VDDU=0V\n VPPU=13V\n PGD(RB5)=5V\n PGC(RB6)=0V\n PGM(RB7)=0V");
+ MsgBox(str);
+ j=0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x4;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ strcpy(str,strings[I_TestMSG]);
+ strcat(str,"\n VDDU=0V\n VPPU=0V\n PGD(RB5)=0V\n PGC(RB6)=5V\n PGM(RB7)=0V");
+ MsgBox(str);
+ j=0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ if(FWVersion>=0x900){ //IO test
+ int j=0,i,x,r;
+ strcpy(str,"0000000000000");
+ PrintMessage("IO test\nRC|RA|--RB--|\n");
+ for(i=0;i<13;i++){
+ x=1<<i;
+ j=0;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_PORT_DIR;
+ bufferU[j++]=0x0; //TRISB
+ bufferU[j++]=0x0; //TRISA-C (RC7:RC6:RA5:RA4:RA3:X:X:X)
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=x&0xFF; //PORTB
+ bufferU[j++]=(x>>5)&0xFF; //PORTA-C
+ bufferU[j++]=READ_B;
+ bufferU[j++]=READ_AC;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ for(j=0;j<DIMBUF-1&&bufferI[j]!=READ_B;j++);
+ r=bufferI[j+1];
+ for(j+=2;j<DIMBUF-1&&bufferI[j]!=READ_AC;j++);
+ r+=(bufferI[j+1]&0xF8)<<5;
+ for(j=0;j<13;j++) str[12-j]=x&(1<<j)?'1':'0';
+ PrintMessage(str);
+ PrintMessage1(" (%s)\n",r==x?"OK":strings[S_ErrSing]);
+ }
+ }
+}
+///
+///Wait for X milliseconds
+void msDelay(double delay)
+{
+#if !defined _WIN32 && !defined __CYGWIN__
+ long x=(int)(delay*1000.0);
+ usleep(x>MinDly?x:MinDly);
+#else
+// Sleep((long)ceil(delay)>MinDly?(long)ceil(delay):MinDly);
+ __int64 stop,freq,timeout;
+ QueryPerformanceCounter((LARGE_INTEGER *)&stop);
+ QueryPerformanceFrequency((LARGE_INTEGER *)&freq);
+ timeout=stop+delay*freq/1000.0;
+ while(stop<timeout) QueryPerformanceCounter((LARGE_INTEGER *)&stop);
+#endif
+}
+#if !defined _WIN32 && !defined __CYGWIN__ //Linux
+///
+/// Get system time
+DWORD GetTickCount(){
+ struct timeb now;
+ ftime(&now);
+ return now.time*1000+now.millitm;
+}
+#endif
+
+///
+///Write data packet, wait for X milliseconds, read response
+///real waiting happens only if the desired delay is greater than 40ms;
+///in case of smaller delays the function simply waits for a response (up to 50ms)
+///
+void PacketIO(double delay){
+ #define TIMEOUT 50
+ if(saveLog&&logfile) fprintf(logfile,"PacketIO(%.2f)\n",delay);
+ int delay0=delay;
+#if !defined _WIN32 && !defined __CYGWIN__ //Linux
+ struct timespec ts;
+ uint64_t start,stop;
+ fd_set set;
+ struct timeval timeout;
+ int rv,i;
+ FD_ZERO(&set); /* clear the set */
+ FD_SET(fd, &set); /* add our file descriptor to the set */
+ timeout.tv_sec = 0;
+ timeout.tv_usec = TIMEOUT*1000;
+ clock_gettime( CLOCK_REALTIME, &ts );
+ start=ts.tv_nsec/1000;
+ delay-=TIMEOUT-10; //shorter delays are covered by 50ms timeout
+ if(delay<MinDly) delay=MinDly;
+ #ifndef hiddevIO //use raw USB device
+ //wait before writing
+/* rv = select(fd + 1, NULL, &set, NULL, &timeout); //wait for write event
+ if(rv == -1){
+ PrintMessage(strings[S_ErrSing]); //error
+ if(saveLog&&logfile) fprintf(logfile,strings[S_ErrSing]);
+ return;
+ }
+ else if(rv == 0){
+ PrintMessage(strings[S_comTimeout]); //"comm timeout\r\n"
+ if(saveLog&&logfile) fprintf(logfile,strings[S_comTimeout]);
+ return;
+ }*/
+ //write
+ int res = write(fd,bufferU,DIMBUF);
+ if (res < 0) {
+ printf("Error: %d\n", errno);
+ perror("write");
+ }
+ usleep((int)(delay*1000.0));
+ //wait before reading
+ rv = select(fd + 1, &set, NULL, NULL, &timeout); //wait for event
+ if(rv == -1){
+ PrintMessage(strings[S_ErrSing]); /*error*/
+ if(saveLog&&logfile) fprintf(logfile,strings[S_ErrSing]);
+ return;
+ }
+ else if(rv == 0){
+ PrintMessage(strings[S_comTimeout]); /*"comm timeout\r\n"*/
+ if(saveLog&&logfile) fprintf(logfile,strings[S_comTimeout]);
+ return;
+ }
+ //read
+ res = read(fd, bufferI, DIMBUF);
+ if (res < 0) {
+ perror("read");
+ }
+ #else //use hiddev device (old method)
+ struct hiddev_event ev[80];
+ int n=DIMBUF;
+ for(i=0;i<DIMBUF;i++) ref_multi_u.values[i]=bufferU[i];
+ //write
+ ioctl(fd, HIDIOCSUSAGES, &ref_multi_u);
+ ioctl(fd,HIDIOCSREPORT, &rep_info_u);
+ usleep((int)(delay*1000.0));
+ //read
+ rv = select(fd + 1, &set, NULL, NULL, &timeout); //wait for event
+ if(rv == -1){
+ PrintMessage(strings[S_ErrSing]); /*error*/
+ if(saveLog&&logfile) fprintf(logfile,strings[S_ErrSing]);
+ }
+ else if(rv == 0){
+ PrintMessage(strings[S_comTimeout]); /*"comm timeout\r\n"*/
+ if(saveLog&&logfile) fprintf(logfile,strings[S_comTimeout]);
+ }
+ else{
+ // ioctl(fd, HIDIOCGUSAGES, &ref_multi_i);
+ // ioctl(fd,HIDIOCGREPORT, &rep_info_i);
+ #undef read()
+ rv=read(fd, ev,sizeof(struct hiddev_event) *n);
+ for(i=0;(ev[0].value!=bufferU[0])&&i<40;i++){ //read too early; try again after 5ms
+ msDelay(5);
+ rv=read(fd, ev,sizeof(struct hiddev_event) *n);
+ if(saveLog&&logfile) fprintf(logfile,"Packet not ready, wait extra time\n");
+ }
+ if(i==40) fprintf(logfile,"Cannot read correct packet!!\n");
+ for(i=0;i<n;i++) bufferI[i]=ev[i].value&0xFF;
+ }
+ #endif
+ clock_gettime( CLOCK_REALTIME, &ts );
+ stop = ts.tv_nsec / 1000;
+ if(saveLog&&logfile){
+ WriteLogIO();
+ fprintf(logfile,"T=%.2f ms (%+.2f ms)\n",(stop-start)/1000.0,(stop-start)/1000.0-delay0);
+ if(bufferU[0]!=bufferI[0]) fprintf(logfile,"Cannot read correct packet!!\n");
+ }
+#else //Windows
+ __int64 start,stop,freq,timeout;
+ QueryPerformanceCounter((LARGE_INTEGER *)&start);
+ QueryPerformanceFrequency((LARGE_INTEGER *)&freq);
+ delay-=TIMEOUT-10; //shorter delays are covered by 50ms timeout
+ if(delay<MinDly) delay=MinDly;
+ //write
+ Result = WriteFile(WriteHandle,bufferU0,DIMBUF+1,&BytesWritten,NULL);
+ QueryPerformanceCounter((LARGE_INTEGER *)&stop);
+ timeout=stop+delay*freq/1000.0;
+ while(stop<timeout) QueryPerformanceCounter((LARGE_INTEGER *)&stop);
+ //read
+ Result = ReadFile(ReadHandle,bufferI0,DIMBUF+1,&NumberOfBytesRead,(LPOVERLAPPED) &HIDOverlapped);
+ Result = WaitForSingleObject(hEventObject,TIMEOUT);
+ if(saveLog&&logfile) WriteLogIO();
+ ResetEvent(hEventObject);
+ if(Result!=WAIT_OBJECT_0){
+ PrintMessage(strings[S_comTimeout]); /*"comm timeout\r\n"*/
+ if(saveLog&&logfile) fprintf(logfile,strings[S_comTimeout]);
+ }
+ QueryPerformanceCounter((LARGE_INTEGER *)&stop);
+ if(saveLog&&logfile) fprintf(logfile,"T=%.2f ms (%+.2f ms)\n",(stop-start)*1000.0/freq,(stop-start)*1000.0/freq-delay0);
+#endif
+}
+
+///-----------------------------------
+///Main function
+///-----------------------------------
+int main( int argc, char *argv[])
+{
+ //int langID=GetUserDefaultLangID();
+ DWORD t0=GetTickCount();
+ FILE *f;
+ gchar *homedir,*config_dir,*fname=0;
+ char lang[32]="";
+ int langfile=0;
+ homedir = (gchar *) g_get_home_dir ();
+ if(homedir){
+ config_dir=g_build_path(G_DIR_SEPARATOR_S,homedir,CONFIG_DIR, NULL);
+ if(!g_file_test(config_dir,G_FILE_TEST_IS_DIR))
+ #if defined _WIN32
+ mkdir(config_dir);
+ #else
+ mkdir(config_dir,0755);
+ #endif
+ fname = g_build_path(G_DIR_SEPARATOR_S,config_dir,CONFIG_FILE, NULL);
+ f=fopen(fname,"r");
+ if(f){
+ char temp[256],line[256];
+ int X;
+ for(;fgets(line,256,f);){
+ if(sscanf(line,"device %s",temp)>0) strcpy(dev,temp);
+ else if(sscanf(line,"vid %X",&X)>0) vid=X;
+ else if(sscanf(line,"pid %X",&X)>0) pid=X;
+ else sscanf(line,"maxerr %d",&max_err);
+ }
+ fclose(f);
+ }
+ }
+ char dev_ini[64];
+ strncpy(dev_ini,dev,sizeof(dev_ini));
+ int vid_ini=vid,pid_ini=pid,max_err_ini=max_err;
+ vid_ini=vid;
+ pid_ini=pid;
+ max_err_ini=max_err;
+#if defined _WIN32 || defined __CYGWIN__ //Windows
+ bufferI=bufferI0+1;
+ bufferU=bufferU0+1;
+ bufferI0[0]=0;
+ bufferU0[0]=0;
+#endif
+ gtk_init(&argc, &argv);
+ unsigned int tmpbuf[128];
+ opterr = 0;
+ int option_index = 0;
+ int help=0,command=0,i,j;
+ char c;
+ struct option long_options[] =
+ {
+ {"?", no_argument, &help, 1},
+ {"h", no_argument, &help, 1},
+ {"help", no_argument, &help, 1},
+ {"c", no_argument, &command, 1},
+ {"command", no_argument, &command, 1},
+ {"lang", required_argument, 0, 'l'},
+ {"langfile", no_argument, &langfile, 1},
+ {0, 0, 0, 0}
+ };
+ while ((j = getopt_long_only (argc, argv, "",long_options,&option_index)) != -1){
+ if(j=='l'){ //language
+ strncpy(lang,optarg,sizeof(lang)-1);
+ }
+ }
+ for(j=0,i = optind; i < argc&&i<128; i++,j++) sscanf(argv[i], "%x", &tmpbuf[j]);
+ for(;j<128;j++) tmpbuf[j]=0;
+ strinit();
+ char* langid=0;
+ i=0;
+ if(lang[0]){ //explicit language selection
+ if(lang[0]=='i'&&langid[1]=='t'){ //built-in
+ strings=strings_it;
+ i=1;
+ }
+ else if(lang[0]=='e'&&lang[1]=='n'){ //built-in
+ strings=strings_en;
+ i=1;
+ }
+ else i=strfind(lang,"languages.rc"); //file look-up
+ }
+ if(i==0){
+ #if defined _WIN32
+ langid=malloc(19);
+ int n=GetLocaleInfo(LOCALE_USER_DEFAULT,LOCALE_SISO639LANGNAME,langid,9);
+ langid[n-1] = '-';
+ GetLocaleInfo(LOCALE_USER_DEFAULT,LOCALE_SISO3166CTRYNAME,langid+n, 9);
+ //printf("%d >%s<\n",n,langid);
+ #else
+ langid=getenv("LANG");
+ #endif
+ if(langid){
+ if(langid[0]=='i'&&langid[1]=='t') strings=strings_it;
+ else if(langid[0]=='e'&&langid[1]=='n') strings=strings_en;
+ else if(strfind(langid,"languages.rc")); //first try full code
+ else { //then only first language code
+ char* p=strchr(langid,'-');
+ if(p) *p=0;
+ if(!strfind(langid,"languages.rc")) strings=strings_en;
+ }
+ }
+ else strings=strings_en;
+ }
+ if(langfile) GenerateLangFile(langid,"languages.rc");
+ if(help){
+ printf(strings[I_GUI_CMD_HELP]);
+ exit(0);
+ }
+ if(command){
+ cmdline=1;
+ DeviceDetected=FindDevice(vid,pid); //connect to USB programmer
+ if(!DeviceDetected){
+ DeviceDetected=FindDevice(new_vid,new_pid); //try default
+ if(DeviceDetected){
+ vid=new_vid;
+ pid=new_pid;
+ }
+ }
+ if(!DeviceDetected) DeviceDetected=FindDevice(old_vid,old_pid); //try old one
+ if(DeviceDetected){
+ bufferU[0]=0;
+ for(i=1;i<DIMBUF;i++) bufferU[i]=(char) tmpbuf[i-1];
+ PacketIO(100);
+ printf("> ");
+ for(i=1;i<DIMBUF;i++) printf("%02X ",bufferU[i]);
+ printf("\n< ");
+ for(i=1;i<DIMBUF;i++) printf("%02X ",bufferI[i]);
+ printf("\n");
+ }
+ else printf(strings[S_noprog]);
+ exit(0);
+ }
+
+ GtkBuilder *builder = NULL;
+ builder=gtk_builder_new_from_resource ("/res/opgui.glade");
+ window = GTK_WIDGET(gtk_builder_get_object (builder,"window"));
+ g_signal_connect (window, "destroy", G_CALLBACK (Xclose), NULL);
+ gtk_window_set_icon(GTK_WINDOW(window),gdk_pixbuf_new_from_resource("/res/sys.png", NULL));
+ GtkCssProvider *cssProvider = gtk_css_provider_new();
+ gtk_css_provider_load_from_resource(cssProvider, "/res/style.css");
+ gtk_style_context_add_provider_for_screen(gdk_screen_get_default(),GTK_STYLE_PROVIDER(cssProvider),GTK_STYLE_PROVIDER_PRIORITY_USER);
+ GtkWidget* w=NULL;
+ sprintf(str,"opgui v%s",VERSION);
+ gtk_window_set_title(GTK_WINDOW(window),str);
+ notebook = GTK_WIDGET(gtk_builder_get_object(builder,"NOTEBOOK"));
+//------toolbar-------------
+ w=GTK_WIDGET(gtk_builder_get_object(builder,"OPEN_T"));
+ gtk_widget_set_tooltip_text(w,strings[I_Fopen]);//"Open File"
+ g_signal_connect(w,"clicked",G_CALLBACK(Fopen), NULL);
+ w=GTK_WIDGET(gtk_builder_get_object(builder,"SAVE_T"));
+ gtk_widget_set_tooltip_text(w,strings[I_Fsave]);//"Save File"
+ g_signal_connect(w,"clicked",G_CALLBACK(Fsave), NULL);
+ readBtn=GTK_WIDGET(gtk_builder_get_object(builder,"READ_T"));
+ gtk_widget_set_tooltip_text(readBtn,strings[I_DevR]);//"Read device"
+ g_signal_connect(readBtn,"clicked",G_CALLBACK(DevRead), NULL);
+ writeBtn=GTK_WIDGET(gtk_builder_get_object(builder,"WRITE_T"));
+ gtk_widget_set_tooltip_text(writeBtn,strings[I_DevW]);//"Write device"
+ g_signal_connect(writeBtn,"clicked",G_CALLBACK(DevWrite), NULL);
+ stopBtn=GTK_WIDGET(gtk_builder_get_object(builder,"STOP_T"));
+ gtk_widget_set_tooltip_text(stopBtn,strings[I_ICD_STOP]);//"Stop"
+ g_signal_connect(stopBtn,"clicked",G_CALLBACK(Stop), NULL);
+ w=GTK_WIDGET(gtk_builder_get_object(builder,"CONNECT_T"));
+ gtk_widget_set_tooltip_text(w,strings[I_CONN]);//"Reconnect"
+ g_signal_connect(w,"clicked",G_CALLBACK(Connect), NULL);
+ w=GTK_WIDGET(gtk_builder_get_object(builder,"INFO_T"));
+ gtk_widget_set_tooltip_text(w,strings[I_Info]);//"Info"
+ g_signal_connect(w,"clicked",G_CALLBACK(info), NULL);
+ w=GTK_WIDGET(gtk_builder_get_object(builder,"QUIT_T"));
+ gtk_widget_set_tooltip_text(w,strings[I_QUIT]);//"Quit"
+ g_signal_connect(w,"clicked",G_CALLBACK(Quit), NULL);
+//------data tab-------------
+ gtk_label_set_text(GTK_LABEL(GTK_WIDGET(gtk_builder_get_object(builder,"DATA_T_L"))),strings[I_Data]); //"Data"
+ data=GTK_WIDGET(gtk_builder_get_object(builder,"DATA"));
+ dataBuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(data));
+//------device tab-------------
+ gtk_label_set_text(GTK_LABEL(GTK_WIDGET(gtk_builder_get_object(builder,"DEVICE_L"))),strings[I_Dev]); //"Device"
+ gtk_label_set_text(GTK_LABEL(GTK_WIDGET(gtk_builder_get_object(builder,"TYPE_L"))),strings[I_Type]); //"Type"
+ devTypeCombo=GTK_WIDGET(gtk_builder_get_object(builder,"TYPE_C"));
+ g_signal_connect(G_OBJECT(devTypeCombo),"changed",G_CALLBACK(FilterDevType),NULL);
+ devFiltEntry=GTK_WIDGET(gtk_builder_get_object(builder,"DEV_SRC_E"));
+ g_signal_connect(G_OBJECT(devFiltEntry),"changed",G_CALLBACK(FilterDevType),NULL);
+ devTree = GTK_WIDGET(gtk_builder_get_object(builder,"DEV_TREE"));
+ gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(devTree),
+ -1, strings[I_Dev], gtk_cell_renderer_text_new(), "text", DEVICE_NAME_COLUMN, NULL);
+ gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(devTree),
+ -1, strings[I_Type], gtk_cell_renderer_text_new(), "text", DEVICE_GROUP_COLUMN, NULL);
+ // AddDevices() gets called when an entry in devTypeCombo is selected during init
+ devFrame = GTK_WIDGET(gtk_builder_get_object(builder,"DEVICE_NAME"));
+ devinfo = GTK_WIDGET(gtk_builder_get_object(builder,"DEV_INFO"));
+ EEPROM_RW = GTK_WIDGET(gtk_builder_get_object(builder,"EE_RW"));
+ gtk_button_set_label(GTK_BUTTON(EEPROM_RW),strings[I_EE]); //"Read and write EEPROM"
+ ReadReserved = GTK_WIDGET(gtk_builder_get_object(builder,"RES_READ"));
+ gtk_button_set_label(GTK_BUTTON(ReadReserved),strings[I_ReadRes]); //"Read reserved area"
+ Write_ID_BKCal = GTK_WIDGET(gtk_builder_get_object(builder,"PROG_ID"));
+ gtk_button_set_label(GTK_BUTTON(Write_ID_BKCal),strings[I_ID_BKo_W]); //"Write ID and BKOscCal"
+ WriteCalib12 = GTK_WIDGET(gtk_builder_get_object(builder,"PROG_CAL12"));
+ gtk_button_set_label(GTK_BUTTON(WriteCalib12),strings[I_CalW]); //"Write Calib 1 and 2"
+ gtk_label_set_text(GTK_LABEL(GTK_WIDGET(gtk_builder_get_object(builder,"OSCCAL_L"))),strings[I_OSCW]); //"Write OscCal"
+ UseOSCCAL = GTK_WIDGET(gtk_builder_get_object(builder,"OSCCAL"));
+ gtk_button_set_label(GTK_BUTTON(UseOSCCAL),strings[I_OSC]); //"OSCCal"
+ UseBKOSCCAL = GTK_WIDGET(gtk_builder_get_object(builder,"BKOSCCAL"));
+ gtk_button_set_label(GTK_BUTTON(UseBKOSCCAL),strings[I_BKOSC]); //"Backup OSCCal"
+ UseFileCal = GTK_WIDGET(gtk_builder_get_object(builder,"FILECAL"));
+ gtk_button_set_label(GTK_BUTTON(UseFileCal),strings[I_OSCF]); //"From file"
+ ICD_check = GTK_WIDGET(gtk_builder_get_object(builder,"ICD"));
+ gtk_button_set_label(GTK_BUTTON(ICD_check),strings[I_ICD_ENABLE]); //"Enable ICD"
+ gtk_label_set_text(GTK_LABEL(GTK_WIDGET(gtk_builder_get_object(builder,"ICD_ADDR_L"))),strings[I_ICD_ADDRESS]); //"ICD routine address"
+ ICD_addr_entry = GTK_WIDGET(gtk_builder_get_object(builder,"ICD_ADDR"));
+ ConfigForce = GTK_WIDGET(gtk_builder_get_object(builder,"FORCE_CW"));
+ gtk_button_set_label(GTK_BUTTON(ConfigForce),strings[I_PIC_FORCECW]); //"force config word"
+ CW1_entry = GTK_WIDGET(gtk_builder_get_object(builder,"CW1"));
+ CW2_entry = GTK_WIDGET(gtk_builder_get_object(builder,"CW2"));
+ CW3_entry = GTK_WIDGET(gtk_builder_get_object(builder,"CW3"));
+ CW4_entry = GTK_WIDGET(gtk_builder_get_object(builder,"CW4"));
+ CW5_entry = GTK_WIDGET(gtk_builder_get_object(builder,"CW5"));
+ CW6_entry = GTK_WIDGET(gtk_builder_get_object(builder,"CW6"));
+ CW7_entry = GTK_WIDGET(gtk_builder_get_object(builder,"CW7"));
+ AVR_FuseLow = GTK_WIDGET(gtk_builder_get_object(builder,"FUSEL"));
+ AVR_FuseLowWrite = GTK_WIDGET(gtk_builder_get_object(builder,"FUSEL_C"));
+ gtk_button_set_label(GTK_BUTTON(AVR_FuseLowWrite),strings[I_AT_FUSE]); //"Write Fuse Low"
+ AVR_FuseHigh = GTK_WIDGET(gtk_builder_get_object(builder,"FUSEH"));
+ AVR_FuseHighWrite = GTK_WIDGET(gtk_builder_get_object(builder,"FUSEH_C"));
+ gtk_button_set_label(GTK_BUTTON(AVR_FuseHighWrite),strings[I_AT_FUSEH]); //"Write Fuse High"
+ AVR_FuseExt = GTK_WIDGET(gtk_builder_get_object(builder,"FUSEX"));
+ AVR_FuseExtWrite = GTK_WIDGET(gtk_builder_get_object(builder,"FUSEX_C"));
+ gtk_button_set_label(GTK_BUTTON(AVR_FuseExtWrite),strings[I_AT_FUSEX]); //"Write Extended Fuse"
+ AVR_Lock = GTK_WIDGET(gtk_builder_get_object(builder,"FUSELCK"));
+ AVR_LockWrite = GTK_WIDGET(gtk_builder_get_object(builder,"FUSELCK_C"));
+ gtk_button_set_label(GTK_BUTTON(AVR_LockWrite),strings[I_AT_LOCK]); //"Write Lock"
+ b_WfuseLF = GTK_WIDGET(gtk_builder_get_object(builder,"FUSEL_W3K"));
+ gtk_button_set_label(GTK_BUTTON(b_WfuseLF),strings[I_AT_FUSELF]); //"Write Fuse Low @3kHz"
+ g_signal_connect(G_OBJECT(b_WfuseLF),"clicked",G_CALLBACK(WriteATfuseLowLF),window);
+ devFramePIC = GTK_WIDGET(gtk_builder_get_object(builder,"PIC_OPT"));
+ devFrameAVR = GTK_WIDGET(gtk_builder_get_object(builder,"AVR_OPT"));
+ devFrameConfigW = GTK_WIDGET(gtk_builder_get_object(builder,"CW_OPT"));
+ devFrameICD = GTK_WIDGET(gtk_builder_get_object(builder,"ICD_OPT"));
+ devFrameOsc = GTK_WIDGET(gtk_builder_get_object(builder,"OSC_OPT"));
+ devPIC_CW1 = GTK_WIDGET(gtk_builder_get_object(builder,"CW1_OPT"));
+ devPIC_CW2 = GTK_WIDGET(gtk_builder_get_object(builder,"CW2_OPT"));
+ devPIC_CW3 = GTK_WIDGET(gtk_builder_get_object(builder,"CW3_OPT"));
+ devPIC_CW4 = GTK_WIDGET(gtk_builder_get_object(builder,"CW4_OPT"));
+ devPIC_CW5 = GTK_WIDGET(gtk_builder_get_object(builder,"CW5_OPT"));
+ devPIC_CW6 = GTK_WIDGET(gtk_builder_get_object(builder,"CW6_OPT"));
+ devPIC_CW7 = GTK_WIDGET(gtk_builder_get_object(builder,"CW7_OPT"));
+ devPIC_CW8 = GTK_WIDGET(gtk_builder_get_object(builder,"CW8_OPT"));
+ gtk_widget_hide(GTK_WIDGET(devFrameAVR));
+ gtk_widget_hide(GTK_WIDGET(devFramePIC));
+//------options tab-------------
+ gtk_label_set_text(GTK_LABEL(GTK_WIDGET(gtk_builder_get_object(builder,"OPTIONS_L"))),strings[I_Opt]); //"Options"
+ VID_entry=GTK_WIDGET(gtk_builder_get_object(builder,"VID"));
+ PID_entry=GTK_WIDGET(gtk_builder_get_object(builder,"PID"));
+ Errors_entry=GTK_WIDGET(gtk_builder_get_object(builder,"MAXERR"));
+ b_connect = GTK_WIDGET(gtk_builder_get_object(builder,"CONNECT"));
+ gtk_button_set_label(GTK_BUTTON(b_connect),strings[I_CONN]); //"Reconnect"
+ g_signal_connect(G_OBJECT(b_connect),"clicked",G_CALLBACK(Connect),window);
+ b_testhw = GTK_WIDGET(gtk_builder_get_object(builder,"TEST"));
+ gtk_button_set_label(GTK_BUTTON(b_testhw),strings[I_TestHWB]); //"Hardware test"
+ g_signal_connect(G_OBJECT(b_testhw),"clicked",G_CALLBACK(TestHw),window);
+ b_log = GTK_WIDGET(gtk_builder_get_object(builder,"LOG"));
+ gtk_button_set_label(GTK_BUTTON(b_log),strings[I_LOG]); //"Log activity"
+ b_V33check = GTK_WIDGET(gtk_builder_get_object(builder,"3VCHECK"));
+ gtk_button_set_label(GTK_BUTTON(b_V33check),strings[I_CK_V33]); //"Don't check for 3.3V regulator"
+ b_WaitS1 = GTK_WIDGET(gtk_builder_get_object(builder,"S1"));
+ gtk_button_set_label(GTK_BUTTON(b_WaitS1),strings[I_WAITS1]); //"Wait for S1 before read/write"
+ gtk_label_set_text(GTK_LABEL(GTK_WIDGET(gtk_builder_get_object(builder,"MAXERR_L"))),strings[I_MAXERR]); //"Max errors"
+//------I2C tab-------------
+ gtk_label_set_text(GTK_LABEL(GTK_WIDGET(gtk_builder_get_object(builder,"I2CMODE"))),strings[I_I2CMode]); //"Mode"
+ I2C8bit = GTK_WIDGET(gtk_builder_get_object(builder,"I2C8BIT"));
+ I2C16bit = GTK_WIDGET(gtk_builder_get_object(builder,"I2C16BIT"));
+ SPI00 = GTK_WIDGET(gtk_builder_get_object(builder,"SPI00"));
+ SPI01 = GTK_WIDGET(gtk_builder_get_object(builder,"SPI01"));
+ SPI10 = GTK_WIDGET(gtk_builder_get_object(builder,"SPI10"));
+ SPI11 = GTK_WIDGET(gtk_builder_get_object(builder,"SPI11"));
+ gtk_label_set_text(GTK_LABEL(GTK_WIDGET(gtk_builder_get_object(builder,"DATASEND_L"))),strings[I_I2CDATAOUT]); //"Data to send"
+ I2CDataSend = GTK_WIDGET(gtk_builder_get_object(builder,"DATASEND"));
+ gtk_label_set_text(GTK_LABEL(GTK_WIDGET(gtk_builder_get_object(builder,"DATATR_L"))),strings[I_I2CDATATR]); //"Data transferred"
+ I2CDataReceive = GTK_WIDGET(gtk_builder_get_object(builder,"DATATR"));
+ gtk_label_set_text(GTK_LABEL(GTK_WIDGET(gtk_builder_get_object(builder,"NBYTE_L"))),strings[I_I2C_NB]); //"Byes to read/write"
+ I2CNbyte = GTK_WIDGET(gtk_builder_get_object(builder,"NBYTE_S"));
+ gtk_label_set_text(GTK_LABEL(GTK_WIDGET(gtk_builder_get_object(builder,"SPEED_L"))),strings[I_Speed]); //"Speed"
+ I2CSpeed = GTK_WIDGET(gtk_builder_get_object(builder,"SPEED_C"));
+ I2CSendBtn = GTK_WIDGET(gtk_builder_get_object(builder,"SEND_B"));
+ gtk_button_set_label(GTK_BUTTON(I2CSendBtn),strings[I_I2CSend]); //"Send"
+ g_signal_connect(G_OBJECT(I2CSendBtn),"clicked",G_CALLBACK(I2cspiS),window);
+ I2CReceiveBtn = GTK_WIDGET(gtk_builder_get_object(builder,"RECEIVE_B"));
+ gtk_button_set_label(GTK_BUTTON(I2CReceiveBtn),strings[I_I2CReceive]); //"Receive"
+ g_signal_connect(G_OBJECT(I2CReceiveBtn),"clicked",G_CALLBACK(I2cspiR),window);
+//------ICD tab-------------
+ GtkWidget* loadCoffBtn = GTK_WIDGET(gtk_builder_get_object(builder,"LOADCOFF_B"));
+ gtk_tool_button_set_label(GTK_TOOL_BUTTON(loadCoffBtn),strings[I_LOAD_COFF]); //"load COFF file..."
+ g_signal_connect(G_OBJECT(loadCoffBtn),"clicked",G_CALLBACK(loadCoff),window);
+ g_signal_connect(GTK_WIDGET(gtk_builder_get_object(builder,"ICD_TAB")),"key_press_event",G_CALLBACK(icd_key_event),NULL);
+ //menu
+ gtk_menu_item_set_label(GTK_MENU_ITEM(gtk_builder_get_object(builder,"OPTIONS_M")),strings[I_Opt]); //"Options";
+ icdMenuPC = GTK_WIDGET(gtk_builder_get_object(builder,"PCOUNT_M"));
+ gtk_menu_item_set_label(GTK_MENU_ITEM(icdMenuPC),strings[I_SHOW_PC]); //"show Program Counter"
+ icdMenuSTAT = GTK_WIDGET(gtk_builder_get_object(builder,"STATUS_M"));
+ gtk_menu_item_set_label(GTK_MENU_ITEM(icdMenuSTAT),strings[I_SHOW_STATUS]); //"show status registers"
+ icdMenuBank0 = GTK_WIDGET(gtk_builder_get_object(builder,"BANK0_M"));
+ gtk_menu_item_set_label(GTK_MENU_ITEM(icdMenuBank0),strings[I_SHOW_BANK0]); //"show memory bank 0"
+ icdMenuBank1 = GTK_WIDGET(gtk_builder_get_object(builder,"BANK1_M"));
+ gtk_menu_item_set_label(GTK_MENU_ITEM(icdMenuBank1),strings[I_SHOW_BANK1]); //"show memory bank 1"
+ icdMenuBank2 = GTK_WIDGET(gtk_builder_get_object(builder,"BANK2_M"));
+ gtk_menu_item_set_label(GTK_MENU_ITEM(icdMenuBank2),strings[I_SHOW_BANK2]); //"show memory bank 2"
+ icdMenuBank3 = GTK_WIDGET(gtk_builder_get_object(builder,"BANK3_M"));
+ gtk_menu_item_set_label(GTK_MENU_ITEM(icdMenuBank3),strings[I_SHOW_BANK3]); //"show memory bank 3"
+ icdMenuEE = GTK_WIDGET(gtk_builder_get_object(builder,"EE_M"));
+ gtk_menu_item_set_label(GTK_MENU_ITEM(icdMenuEE),strings[I_SHOW_EE]); //"show EEPROM"
+ //toolbar
+ w=GTK_WIDGET(gtk_builder_get_object(builder,"ICD_RUN"));
+ gtk_widget_set_tooltip_text(w,strings[I_ICD_RUN]);
+ g_signal_connect(w,"clicked",G_CALLBACK(icdRun), NULL);
+ w=GTK_WIDGET(gtk_builder_get_object(builder,"ICD_HALT"));
+ gtk_widget_set_tooltip_text(w,strings[I_ICD_HALT]);
+ g_signal_connect(w,"clicked",G_CALLBACK(icdHalt), NULL);
+ w=GTK_WIDGET(gtk_builder_get_object(builder,"ICD_STEP"));
+ gtk_widget_set_tooltip_text(w,strings[I_ICD_STEP]);
+ g_signal_connect(w,"clicked",G_CALLBACK(icdStep), NULL);
+ w=GTK_WIDGET(gtk_builder_get_object(builder,"ICD_STEPOVER"));
+ gtk_widget_set_tooltip_text(w,strings[I_ICD_STEPOVER]);
+ g_signal_connect(w,"clicked",G_CALLBACK(icdStepOver), NULL);
+ w=GTK_WIDGET(gtk_builder_get_object(builder,"ICD_STOP"));
+ gtk_widget_set_tooltip_text(w,strings[I_ICD_STOP]);
+ g_signal_connect(w,"clicked",G_CALLBACK(icdStop), NULL);
+ w=GTK_WIDGET(gtk_builder_get_object(builder,"ICD_REFRESH"));
+ gtk_widget_set_tooltip_text(w,strings[I_ICD_REFRESH]);//"refresh"
+ g_signal_connect(w,"clicked",G_CALLBACK(icdRefresh), NULL);
+ icdCommand = GTK_WIDGET(gtk_builder_get_object(builder,"ICD_CMD_E"));
+ gtk_widget_set_tooltip_text(icdCommand,strings[I_ICD_CMD]);//"command-line"
+ g_signal_connect(G_OBJECT(icdCommand),"key_press_event",G_CALLBACK(icdCommand_key_event),NULL);
+ w=GTK_WIDGET(gtk_builder_get_object(builder,"ICD_HELP"));
+ gtk_widget_set_tooltip_text(w,strings[I_ICD_HELP]);//"help"
+ g_signal_connect(w,"clicked",G_CALLBACK(ICDHelp), NULL);
+ //source
+ gtk_label_set_text(GTK_LABEL(GTK_WIDGET(gtk_builder_get_object(builder,"ICD_SOURCE_L"))),strings[I_ICD_SOURCE]); //"Source"
+ sourceTxt = GTK_WIDGET(gtk_builder_get_object(builder,"ICD_SOURCE"));
+ sourceBuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(sourceTxt));
+ g_signal_connect(G_OBJECT(sourceTxt),"button_press_event",G_CALLBACK(source_mouse_event),NULL);
+ //status
+ gtk_label_set_text(GTK_LABEL(GTK_WIDGET(gtk_builder_get_object(builder,"ICD_STAT_L"))),strings[I_ICD_STATUS]); //"Status"
+ statusTxt = GTK_WIDGET(gtk_builder_get_object(builder,"ICD_STATUS"));
+ statusBuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(statusTxt));
+ g_signal_connect(G_OBJECT(statusTxt),"button_press_event",G_CALLBACK(icdStatus_mouse_event),NULL);
+//------IO tab-------------
+ b_io_active = GTK_WIDGET(gtk_builder_get_object(builder,"IOEN"));
+ gtk_button_set_label(GTK_BUTTON(b_io_active),strings[I_IO_Enable]); //"Enable IO"
+ g_signal_connect(G_OBJECT(b_io_active),"toggled",G_CALLBACK(IOactive),NULL);
+ ioButtons[0].r_0 = GTK_WIDGET(gtk_builder_get_object(builder,"RB0_0"));
+ ioButtons[0].r_1 = GTK_WIDGET(gtk_builder_get_object(builder,"RB0_1"));
+ ioButtons[0].r_I = GTK_WIDGET(gtk_builder_get_object(builder,"RB0_I"));
+ ioButtons[0].e_I = GTK_WIDGET(gtk_builder_get_object(builder,"RB0_L"));
+ ioButtons[1].r_0 = GTK_WIDGET(gtk_builder_get_object(builder,"RB1_0"));
+ ioButtons[1].r_1 = GTK_WIDGET(gtk_builder_get_object(builder,"RB1_1"));
+ ioButtons[1].r_I = GTK_WIDGET(gtk_builder_get_object(builder,"RB1_I"));
+ ioButtons[1].e_I = GTK_WIDGET(gtk_builder_get_object(builder,"RB1_L"));
+ ioButtons[2].r_0 = GTK_WIDGET(gtk_builder_get_object(builder,"RB2_0"));
+ ioButtons[2].r_1 = GTK_WIDGET(gtk_builder_get_object(builder,"RB2_1"));
+ ioButtons[2].r_I = GTK_WIDGET(gtk_builder_get_object(builder,"RB2_I"));
+ ioButtons[2].e_I = GTK_WIDGET(gtk_builder_get_object(builder,"RB2_L"));
+ ioButtons[3].r_0 = GTK_WIDGET(gtk_builder_get_object(builder,"RB3_0"));
+ ioButtons[3].r_1 = GTK_WIDGET(gtk_builder_get_object(builder,"RB3_1"));
+ ioButtons[3].r_I = GTK_WIDGET(gtk_builder_get_object(builder,"RB3_I"));
+ ioButtons[3].e_I = GTK_WIDGET(gtk_builder_get_object(builder,"RB3_L"));
+ ioButtons[4].r_0 = GTK_WIDGET(gtk_builder_get_object(builder,"RB4_0"));
+ ioButtons[4].r_1 = GTK_WIDGET(gtk_builder_get_object(builder,"RB4_1"));
+ ioButtons[4].r_I = GTK_WIDGET(gtk_builder_get_object(builder,"RB4_I"));
+ ioButtons[4].e_I = GTK_WIDGET(gtk_builder_get_object(builder,"RB4_L"));
+ ioButtons[5].r_0 = GTK_WIDGET(gtk_builder_get_object(builder,"RB5_0"));
+ ioButtons[5].r_1 = GTK_WIDGET(gtk_builder_get_object(builder,"RB5_1"));
+ ioButtons[5].r_I = GTK_WIDGET(gtk_builder_get_object(builder,"RB5_I"));
+ ioButtons[5].e_I = GTK_WIDGET(gtk_builder_get_object(builder,"RB5_L"));
+ ioButtons[6].r_0 = GTK_WIDGET(gtk_builder_get_object(builder,"RB6_0"));
+ ioButtons[6].r_1 = GTK_WIDGET(gtk_builder_get_object(builder,"RB6_1"));
+ ioButtons[6].r_I = GTK_WIDGET(gtk_builder_get_object(builder,"RB6_I"));
+ ioButtons[6].e_I = GTK_WIDGET(gtk_builder_get_object(builder,"RB6_L"));
+ ioButtons[7].r_0 = GTK_WIDGET(gtk_builder_get_object(builder,"RB7_0"));
+ ioButtons[7].r_1 = GTK_WIDGET(gtk_builder_get_object(builder,"RB7_1"));
+ ioButtons[7].r_I = GTK_WIDGET(gtk_builder_get_object(builder,"RB7_I"));
+ ioButtons[7].e_I = GTK_WIDGET(gtk_builder_get_object(builder,"RB7_L"));
+ ioButtons[8].r_0 = GTK_WIDGET(gtk_builder_get_object(builder,"RC7_0"));
+ ioButtons[8].r_1 = GTK_WIDGET(gtk_builder_get_object(builder,"RC7_1"));
+ ioButtons[8].r_I = GTK_WIDGET(gtk_builder_get_object(builder,"RC7_I"));
+ ioButtons[8].e_I = GTK_WIDGET(gtk_builder_get_object(builder,"RC7_L"));
+ ioButtons[9].r_0 = GTK_WIDGET(gtk_builder_get_object(builder,"RC6_0"));
+ ioButtons[9].r_1 = GTK_WIDGET(gtk_builder_get_object(builder,"RC6_1"));
+ ioButtons[9].r_I = GTK_WIDGET(gtk_builder_get_object(builder,"RC6_I"));
+ ioButtons[9].e_I = GTK_WIDGET(gtk_builder_get_object(builder,"RC6_L"));
+ ioButtons[10].r_0 = GTK_WIDGET(gtk_builder_get_object(builder,"RA5_0"));
+ ioButtons[10].r_1 = GTK_WIDGET(gtk_builder_get_object(builder,"RA5_1"));
+ ioButtons[10].r_I = GTK_WIDGET(gtk_builder_get_object(builder,"RA5_I"));
+ ioButtons[10].e_I = GTK_WIDGET(gtk_builder_get_object(builder,"RA5_L"));
+ ioButtons[11].r_0 = GTK_WIDGET(gtk_builder_get_object(builder,"RA4_0"));
+ ioButtons[11].r_1 = GTK_WIDGET(gtk_builder_get_object(builder,"RA4_1"));
+ ioButtons[11].r_I = GTK_WIDGET(gtk_builder_get_object(builder,"RA4_I"));
+ ioButtons[11].e_I = GTK_WIDGET(gtk_builder_get_object(builder,"RA4_L"));
+ ioButtons[12].r_0 = GTK_WIDGET(gtk_builder_get_object(builder,"RA3_0"));
+ ioButtons[12].r_1 = GTK_WIDGET(gtk_builder_get_object(builder,"RA3_1"));
+ ioButtons[12].r_I = GTK_WIDGET(gtk_builder_get_object(builder,"RA3_I"));
+ ioButtons[12].e_I = GTK_WIDGET(gtk_builder_get_object(builder,"RA3_L"));
+ for(int ii=0;ii<sizeof(ioButtons)/sizeof(ioButtons[0]);ii++){
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ioButtons[ii].r_I),TRUE);
+ g_signal_connect(G_OBJECT(ioButtons[ii].r_0),"toggled",G_CALLBACK(IOchanged),NULL);
+ g_signal_connect(G_OBJECT(ioButtons[ii].r_1),"toggled",G_CALLBACK(IOchanged),NULL);
+ g_signal_connect(G_OBJECT(ioButtons[ii].r_I),"toggled",G_CALLBACK(IOchanged),NULL);
+ }
+ VDD_ON = GTK_WIDGET(gtk_builder_get_object(builder,"VDDUEN"));
+ VPP_ON = GTK_WIDGET(gtk_builder_get_object(builder,"VPPUEN"));
+ DCDC_ON = GTK_WIDGET(gtk_builder_get_object(builder,"DCDCEN"));
+ DCDC_voltage = GTK_WIDGET(gtk_builder_get_object(builder,"DCDC_S"));
+ gtk_label_set_text(GTK_LABEL(GTK_WIDGET(gtk_builder_get_object(builder,"CMD_L"))),strings[I_IO_Commands]); //"Manual commands"
+ gtk_label_set_text(GTK_LABEL(GTK_WIDGET(gtk_builder_get_object(builder,"CMDSEND_L"))),strings[I_I2CDATAOUT]); //"Data to send"
+ commandSend = GTK_WIDGET(gtk_builder_get_object(builder,"CMDSEND"));
+ gtk_label_set_text(GTK_LABEL(GTK_WIDGET(gtk_builder_get_object(builder,"CMDTR_L"))),strings[I_I2CDATATR]); //"Data transferred"
+ commandTransfer = GTK_WIDGET(gtk_builder_get_object(builder,"CMDTR"));
+ w = GTK_WIDGET(gtk_builder_get_object(builder,"CMDTR_B"));
+ gtk_button_set_label(GTK_BUTTON(w),strings[I_I2CSend]); //"Send"
+ g_signal_connect(w,"clicked",G_CALLBACK(CommandIO),window);
+ g_signal_connect(G_OBJECT(VDD_ON),"toggled",G_CALLBACK(VPPVDDactive),NULL);
+ g_signal_connect(G_OBJECT(VPP_ON),"toggled",G_CALLBACK(VPPVDDactive),NULL);
+ g_signal_connect(G_OBJECT(DCDC_ON),"toggled",G_CALLBACK(DCDCactive),NULL);
+ g_signal_connect(G_OBJECT(DCDC_voltage),"value_changed",G_CALLBACK(DCDCactive),NULL);
+//------Utility tab-------------
+ Hex_entry = GTK_WIDGET(gtk_builder_get_object(builder,"HEXIN"));
+ Hex_data = GTK_WIDGET(gtk_builder_get_object(builder,"DATAOUT"));
+ Address_entry = GTK_WIDGET(gtk_builder_get_object(builder,"ADDRIN"));
+ Data_entry = GTK_WIDGET(gtk_builder_get_object(builder,"DATAIN"));
+ Hex_data2 = GTK_WIDGET(gtk_builder_get_object(builder,"HEXOUT"));
+ w = GTK_WIDGET(gtk_builder_get_object(builder,"HEXSAVE"));
+ gtk_button_set_label(GTK_BUTTON(w),strings[I_Fsave]);
+ g_signal_connect(w,"clicked",G_CALLBACK(HexSave),window);
+ g_signal_connect(G_OBJECT(Hex_entry),"changed",G_CALLBACK(HexConvert),NULL);
+ g_signal_connect(G_OBJECT(Address_entry),"changed",G_CALLBACK(DataToHexConvert),NULL);
+ g_signal_connect(G_OBJECT(Data_entry),"changed",G_CALLBACK(DataToHexConvert),NULL);
+//------status bar-------------
+ status_bar = GTK_WIDGET(gtk_builder_get_object(builder,"STATUS_B"));
+ statusID=gtk_statusbar_get_context_id(GTK_STATUSBAR(status_bar),"ID");
+ //printf("load time: %dms\n",GetTickCount()-t0);fflush(stdout);
+ gtk_widget_show_all(window);
+
+//********Init*************
+ char text[16];
+ sprintf(text,"%04X",vid);
+ gtk_entry_set_text(GTK_ENTRY(VID_entry),text);
+ sprintf(text,"%04X",pid);
+ gtk_entry_set_text(GTK_ENTRY(PID_entry),text);
+ sprintf(text,"%d",max_err);
+ gtk_entry_set_text(GTK_ENTRY(Errors_entry),text);
+ sizeW=0x8400;
+ memCODE_W=malloc(sizeW*sizeof(WORD));
+ initVar();
+ for(i=0;i<0x8400;i++) memCODE_W[i]=0x3fff;
+ strncpy(LogFileName,strings[S_LogFile],sizeof(LogFileName));
+ gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(devTypeCombo), GROUP_ALL, GROUP_ALL);
+ for (int i=0;i<NUM_GROUPS;i++)
+ gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(devTypeCombo), groupNames[i], groupNames[i]);
+ // These will trigger AddDevices to populate the device tree
+ if (strlen(dev)>0) {
+ struct DevInfo info = GetDevInfo(dev);
+ gtk_combo_box_set_active_id(GTK_COMBO_BOX(devTypeCombo), groupNames[info.group]);
+ }
+ else {
+ gtk_combo_box_set_active_id(GTK_COMBO_BOX(devTypeCombo), GROUP_ALL);
+ }
+ DeviceDetected=FindDevice(vid,pid); //connect to USB programmer
+ if(!DeviceDetected){
+ DeviceDetected=FindDevice(new_vid,new_pid); //try default
+ if(DeviceDetected){
+ vid=new_vid;
+ pid=new_pid;
+ }
+ }
+ if(!DeviceDetected) DeviceDetected=FindDevice(old_vid,old_pid); //try old one
+ ProgID(); //get firmware version and reset
+ gtk_main();
+// printf(ListDevices());
+//******Save ini file******
+// only if parameters are changed
+ if(strcmp(dev_ini,dev)||vid_ini!=vid||pid_ini!=pid||max_err_ini!=max_err){
+ if(homedir){
+ f=fopen(fname,"w");
+ if(f){
+ fprintf(f,"device %s\n",dev);
+ fprintf(f,"maxerr %d\n",max_err);
+ fprintf(f,"vid %X\n",vid);
+ fprintf(f,"pid %X\n",pid);
+ }
+ fclose(f);
+ }
+ }
+ return 0;
+}
+
+///
+///Find the USB peripheral with proper vid&pid code
+/// return 0 if not found
+int FindDevice(int vid,int pid){
+ int MyDeviceDetected = FALSE;
+#if !defined _WIN32 && !defined __CYGWIN__ //Linux
+ #ifndef hiddevIO //use raw USB device
+ struct hidraw_devinfo device_info;
+ int i=-1;
+ if(path[0]==0){ //search all devices
+ if((fd = open("/dev/openprogrammer", O_RDWR|O_NONBLOCK))>0){ //try with this first
+ sprintf(path,"/dev/openprogrammer");
+ ioctl(fd, HIDIOCGRAWINFO, &device_info);
+ if(device_info.vendor==vid&&device_info.product==pid) i=0;
+ else{
+ close(fd);
+ i=-1;
+ }
+ }
+ if(i){
+ for(i=0;i<16;i++){
+ sprintf(path,"/dev/hidraw%d",i);
+ if((fd = open(path, O_RDWR|O_NONBLOCK))>0){
+ ioctl(fd, HIDIOCGRAWINFO, &device_info);
+ if(device_info.vendor==vid&&device_info.product==pid) break;
+ else close(fd);
+ }
+ }
+ }
+ if(i==16){
+ PrintMessage(strings[S_noprog]);
+ path[0]=0;
+ return 0;
+ }
+ }
+ else{ //user supplied path
+ if((fd = open(path, O_RDWR|O_NONBLOCK)) < 0) {
+ PrintMessage1(strings[S_DevPermission],path); //"cannot open %s, make sure you have read permission on it",path);
+ return 0;
+ }
+ ioctl(fd, HIDIOCGRAWINFO, &device_info);
+ if(device_info.vendor!=vid||device_info.product!=pid){
+ PrintMessage(strings[S_noprog]);
+ return 0;
+ }
+ }
+ printf(strings[S_progDev],path);
+ return 1;
+ #else //use hiddev device (old method)
+ struct hiddev_devinfo device_info;
+ int i=-1;
+ if(path[0]==0){ //search all devices
+ if((fd = open("/dev/openprogrammer", O_RDONLY ))>0){ //try with this first
+ ioctl(fd, HIDIOCGDEVINFO, &device_info);
+ if(device_info.vendor==vid&&device_info.product==pid) i=0;
+ else{
+ close(fd);
+ i=-1;
+ }
+ }
+ if(i){
+ for(i=0;i<16;i++){
+ sprintf(path,"/dev/usb/hiddev%d",i);
+ if((fd = open(path, O_RDONLY ))>0){
+ ioctl(fd, HIDIOCGDEVINFO, &device_info);
+ if(device_info.vendor==vid&&device_info.product==pid) break;
+ else close(fd);
+ }
+ }
+ }
+ if(i==16){
+ PrintMessage(strings[S_noprog]);
+ path[0]=0;
+ return 0;
+ }
+ }
+ else{ //user supplied path
+ if ((fd = open(path, O_RDONLY )) < 0) {
+ PrintMessage1(strings[S_DevPermission],path); //"cannot open %s, make sure you have read permission on it",path);
+ return 0;
+ }
+ ioctl(fd, HIDIOCGDEVINFO, &device_info);
+ if(device_info.vendor!=vid||device_info.product!=pid){
+ PrintMessage(strings[S_noprog]);
+ return 0;
+ }
+ }
+ MyDeviceDetected = TRUE;
+ rep_info_u.report_type=HID_REPORT_TYPE_OUTPUT;
+ rep_info_i.report_type=HID_REPORT_TYPE_INPUT;
+ rep_info_u.report_id=rep_info_i.report_id=HID_REPORT_ID_FIRST;
+ rep_info_u.num_fields=rep_info_i.num_fields=1;
+ ref_multi_u.uref.report_type=HID_REPORT_TYPE_OUTPUT;
+ ref_multi_i.uref.report_type=HID_REPORT_TYPE_INPUT;
+ ref_multi_u.uref.report_id=ref_multi_i.uref.report_id=HID_REPORT_ID_FIRST;
+ ref_multi_u.uref.field_index=ref_multi_i.uref.field_index=0;
+ ref_multi_u.uref.usage_index=ref_multi_i.uref.usage_index=0;
+ ref_multi_u.num_values=ref_multi_i.num_values=DIMBUF;
+ #endif
+#else //Windows
+ PSP_DEVICE_INTERFACE_DETAIL_DATA detailData;
+ HANDLE DeviceHandle;
+ HANDLE hDevInfo;
+ GUID HidGuid;
+ char MyDevicePathName[1024];
+ ULONG Length;
+ ULONG Required;
+ typedef struct _HIDD_ATTRIBUTES {
+ ULONG Size;
+ USHORT VendorID;
+ USHORT ProductID;
+ USHORT VersionNumber;
+ } HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES;
+ typedef void (__stdcall*GETHIDGUID) (OUT LPGUID HidGuid);
+ typedef BOOLEAN (__stdcall*GETATTRIBUTES)(IN HANDLE HidDeviceObject,OUT PHIDD_ATTRIBUTES Attributes);
+ typedef BOOLEAN (__stdcall*SETNUMINPUTBUFFERS)(IN HANDLE HidDeviceObject,OUT ULONG NumberBuffers);
+ typedef BOOLEAN (__stdcall*GETNUMINPUTBUFFERS)(IN HANDLE HidDeviceObject,OUT PULONG NumberBuffers);
+ typedef BOOLEAN (__stdcall*GETFEATURE) (IN HANDLE HidDeviceObject, OUT PVOID ReportBuffer, IN ULONG ReportBufferLength);
+ typedef BOOLEAN (__stdcall*SETFEATURE) (IN HANDLE HidDeviceObject, IN PVOID ReportBuffer, IN ULONG ReportBufferLength);
+ typedef BOOLEAN (__stdcall*GETREPORT) (IN HANDLE HidDeviceObject, OUT PVOID ReportBuffer, IN ULONG ReportBufferLength);
+ typedef BOOLEAN (__stdcall*SETREPORT) (IN HANDLE HidDeviceObject, IN PVOID ReportBuffer, IN ULONG ReportBufferLength);
+ typedef BOOLEAN (__stdcall*GETMANUFACTURERSTRING) (IN HANDLE HidDeviceObject, OUT PVOID ReportBuffer, IN ULONG ReportBufferLength);
+ typedef BOOLEAN (__stdcall*GETPRODUCTSTRING) (IN HANDLE HidDeviceObject, OUT PVOID ReportBuffer, IN ULONG ReportBufferLength);
+ typedef BOOLEAN (__stdcall*GETINDEXEDSTRING) (IN HANDLE HidDeviceObject, IN ULONG StringIndex, OUT PVOID ReportBuffer, IN ULONG ReportBufferLength);
+ HIDD_ATTRIBUTES Attributes;
+ SP_DEVICE_INTERFACE_DATA devInfoData;
+ int LastDevice = FALSE;
+ int MemberIndex = 0;
+ LONG Result;
+ Length=0;
+ detailData=NULL;
+ DeviceHandle=NULL;
+ HMODULE hHID=0;
+ GETHIDGUID HidD_GetHidGuid=0;
+ GETATTRIBUTES HidD_GetAttributes=0;
+ SETNUMINPUTBUFFERS HidD_SetNumInputBuffers=0;
+ GETNUMINPUTBUFFERS HidD_GetNumInputBuffers=0;
+ GETFEATURE HidD_GetFeature=0;
+ SETFEATURE HidD_SetFeature=0;
+ GETREPORT HidD_GetInputReport=0;
+ SETREPORT HidD_SetOutputReport=0;
+ GETMANUFACTURERSTRING HidD_GetManufacturerString=0;
+ GETPRODUCTSTRING HidD_GetProductString=0;
+ hHID = LoadLibrary("hid.dll");
+ if(!hHID){
+ PrintMessage("Can't find hid.dll");
+ return 0;
+ }
+ HidD_GetHidGuid=(GETHIDGUID)GetProcAddress(hHID,"HidD_GetHidGuid");
+ HidD_GetAttributes=(GETATTRIBUTES)GetProcAddress(hHID,"HidD_GetAttributes");
+ HidD_SetNumInputBuffers=(SETNUMINPUTBUFFERS)GetProcAddress(hHID,"HidD_SetNumInputBuffers");
+ HidD_GetNumInputBuffers=(GETNUMINPUTBUFFERS)GetProcAddress(hHID,"HidD_GetNumInputBuffers");
+ HidD_GetFeature=(GETFEATURE)GetProcAddress(hHID,"HidD_GetFeature");
+ HidD_SetFeature=(SETFEATURE)GetProcAddress(hHID,"HidD_SetFeature");
+ HidD_GetInputReport=(GETREPORT)GetProcAddress(hHID,"HidD_GetInputReport");
+ HidD_SetOutputReport=(SETREPORT)GetProcAddress(hHID,"HidD_SetOutputReport");
+ HidD_GetManufacturerString=(GETMANUFACTURERSTRING)GetProcAddress(hHID,"HidD_GetManufacturerString");
+ HidD_GetProductString=(GETPRODUCTSTRING)GetProcAddress(hHID,"HidD_GetProductString");
+ if(HidD_GetHidGuid==NULL\
+ ||HidD_GetAttributes==NULL\
+ ||HidD_GetFeature==NULL\
+ ||HidD_SetFeature==NULL\
+ ||HidD_GetInputReport==NULL\
+ ||HidD_SetOutputReport==NULL\
+ ||HidD_GetManufacturerString==NULL\
+ ||HidD_GetProductString==NULL\
+ ||HidD_SetNumInputBuffers==NULL\
+ ||HidD_GetNumInputBuffers==NULL) return 0;
+ HMODULE hSAPI=0;
+ hSAPI = LoadLibrary("setupapi.dll");
+ if(!hSAPI){
+ PrintMessage("Can't find setupapi.dll");
+ return 0;
+ }
+ typedef HDEVINFO (WINAPI* SETUPDIGETCLASSDEVS) (CONST GUID*,PCSTR,HWND,DWORD);
+ typedef BOOL (WINAPI* SETUPDIENUMDEVICEINTERFACES) (HDEVINFO,PSP_DEVINFO_DATA,CONST GUID*,DWORD,PSP_DEVICE_INTERFACE_DATA);
+ typedef BOOL (WINAPI* SETUPDIGETDEVICEINTERFACEDETAIL) (HDEVINFO,PSP_DEVICE_INTERFACE_DATA,PSP_DEVICE_INTERFACE_DETAIL_DATA_A,DWORD,PDWORD,PSP_DEVINFO_DATA);
+ typedef BOOL (WINAPI* SETUPDIDESTROYDEVICEINFOLIST) (HDEVINFO);
+ SETUPDIGETCLASSDEVS SetupDiGetClassDevsA=0;
+ SETUPDIENUMDEVICEINTERFACES SetupDiEnumDeviceInterfaces=0;
+ SETUPDIGETDEVICEINTERFACEDETAIL SetupDiGetDeviceInterfaceDetailA=0;
+ SETUPDIDESTROYDEVICEINFOLIST SetupDiDestroyDeviceInfoList=0;
+ SetupDiGetClassDevsA=(SETUPDIGETCLASSDEVS) GetProcAddress(hSAPI,"SetupDiGetClassDevsA");
+ SetupDiEnumDeviceInterfaces=(SETUPDIENUMDEVICEINTERFACES) GetProcAddress(hSAPI,"SetupDiEnumDeviceInterfaces");
+ SetupDiGetDeviceInterfaceDetailA=(SETUPDIGETDEVICEINTERFACEDETAIL) GetProcAddress(hSAPI,"SetupDiGetDeviceInterfaceDetailA");
+ SetupDiDestroyDeviceInfoList=(SETUPDIDESTROYDEVICEINFOLIST) GetProcAddress(hSAPI,"SetupDiDestroyDeviceInfoList");
+ if(SetupDiGetClassDevsA==NULL\
+ ||SetupDiEnumDeviceInterfaces==NULL\
+ ||SetupDiDestroyDeviceInfoList==NULL\
+ ||SetupDiGetDeviceInterfaceDetailA==NULL) return 0;
+ /*
+ The following code is adapted from Usbhidio_vc6 application example by Jan Axelson
+ for more information see see http://www.lvr.com/hidpage.htm
+ */
+ /*
+ API function: HidD_GetHidGuid
+ Get the GUID for all system HIDs.
+ Returns: the GUID in HidGuid.
+ */
+ HidD_GetHidGuid(&HidGuid);
+ /*
+ API function: SetupDiGetClassDevs
+ Returns: a handle to a device information set for all installed devices.
+ Requires: the GUID returned by GetHidGuid.
+ */
+ hDevInfo=SetupDiGetClassDevs(&HidGuid,NULL,NULL,DIGCF_PRESENT|DIGCF_INTERFACEDEVICE);
+ devInfoData.cbSize = sizeof(devInfoData);
+ //Step through the available devices looking for the one we want.
+ //Quit on detecting the desired device or checking all available devices without success.
+ MemberIndex = 0;
+ LastDevice = FALSE;
+ do
+ {
+ /*
+ API function: SetupDiEnumDeviceInterfaces
+ On return, MyDeviceInterfaceData contains the handle to a
+ SP_DEVICE_INTERFACE_DATA structure for a detected device.
+ Requires:
+ The DeviceInfoSet returned in SetupDiGetClassDevs.
+ The HidGuid returned in GetHidGuid.
+ An index to specify a device.
+ */
+ Result=SetupDiEnumDeviceInterfaces (hDevInfo, 0, &HidGuid, MemberIndex, &devInfoData);
+ if (Result != 0)
+ {
+ //A device has been detected, so get more information about it.
+ /*
+ API function: SetupDiGetDeviceInterfaceDetail
+ Returns: an SP_DEVICE_INTERFACE_DETAIL_DATA structure
+ containing information about a device.
+ To retrieve the information, call this function twice.
+ The first time returns the size of the structure in Length.
+ The second time returns a pointer to the data in DeviceInfoSet.
+ Requires:
+ A DeviceInfoSet returned by SetupDiGetClassDevs
+ The SP_DEVICE_INTERFACE_DATA structure returned by SetupDiEnumDeviceInterfaces.
+ The final parameter is an optional pointer to an SP_DEV_INFO_DATA structure.
+ This application doesn't retrieve or use the structure.
+ If retrieving the structure, set
+ MyDeviceInfoData.cbSize = length of MyDeviceInfoData.
+ and pass the structure's address.
+ */
+ //Get the Length value.
+ //The call will return with a "buffer too small" error which can be ignored.
+ Result = SetupDiGetDeviceInterfaceDetail(hDevInfo, &devInfoData, NULL, 0, &Length, NULL);
+ //Allocate memory for the hDevInfo structure, using the returned Length.
+ detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(Length);
+ //Set cbSize in the detailData structure.
+ detailData -> cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
+ //Call the function again, this time passing it the returned buffer size.
+ Result = SetupDiGetDeviceInterfaceDetail(hDevInfo, &devInfoData, detailData, Length,&Required, NULL);
+ // Open a handle to the device.
+ // To enable retrieving information about a system mouse or keyboard,
+ // don't request Read or Write access for this handle.
+ /*
+ API function: CreateFile
+ Returns: a handle that enables reading and writing to the device.
+ Requires:
+ The DevicePath in the detailData structure
+ returned by SetupDiGetDeviceInterfaceDetail.
+ */
+ DeviceHandle=CreateFile(detailData->DevicePath,
+ 0, FILE_SHARE_READ|FILE_SHARE_WRITE,
+ (LPSECURITY_ATTRIBUTES)NULL,OPEN_EXISTING, 0, NULL);
+ /*
+ API function: HidD_GetAttributes
+ Requests information from the device.
+ Requires: the handle returned by CreateFile.
+ Returns: a HIDD_ATTRIBUTES structure containing
+ the Vendor ID, Product ID, and Product Version Number.
+ Use this information to decide if the detected device is
+ the one we're looking for.
+ */
+ //Set the Size to the number of bytes in the structure.
+ Attributes.Size = sizeof(Attributes);
+ Result = HidD_GetAttributes(DeviceHandle,&Attributes);
+ //Is it the desired device?
+ MyDeviceDetected = FALSE;
+ if (Attributes.VendorID == vid)
+ {
+ if (Attributes.ProductID == pid)
+ {
+ //Both the Vendor ID and Product ID match.
+ MyDeviceDetected = TRUE;
+ strcpy(MyDevicePathName,detailData->DevicePath);
+ // Get a handle for writing Output reports.
+ WriteHandle=CreateFile(detailData->DevicePath,
+ GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,
+ (LPSECURITY_ATTRIBUTES)NULL,OPEN_EXISTING,0,NULL);
+ //Get a handle to the device for the overlapped ReadFiles.
+ ReadHandle=CreateFile(detailData->DevicePath,
+ GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,(LPSECURITY_ATTRIBUTES)NULL,
+ OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
+ if (hEventObject) CloseHandle(hEventObject);
+ hEventObject = CreateEvent(NULL,TRUE,TRUE,"");
+ //Set the members of the overlapped structure.
+ HIDOverlapped.hEvent = hEventObject;
+ HIDOverlapped.Offset = 0;
+ HIDOverlapped.OffsetHigh = 0;
+ Result=HidD_SetNumInputBuffers(DeviceHandle,64);
+ }
+ else
+ //The Product ID doesn't match.
+ CloseHandle(DeviceHandle);
+ }
+ else
+ //The Vendor ID doesn't match.
+ CloseHandle(DeviceHandle);
+ //Free the memory used by the detailData structure (no longer needed).
+ free(detailData);
+ }
+ else
+ //SetupDiEnumDeviceInterfaces returned 0, so there are no more devices to check.
+ LastDevice=TRUE;
+ //If we haven't found the device yet, and haven't tried every available device,
+ //try the next one.
+ MemberIndex = MemberIndex + 1;
+ } //do
+ while ((LastDevice == FALSE) && (MyDeviceDetected == FALSE));
+ //Free the memory reserved for hDevInfo by SetupDiClassDevs.
+ SetupDiDestroyDeviceInfoList(hDevInfo);
+/* if(info){
+ PrintMessage3("Device detected: vid=0x%04X pid=0x%04X\nPath: %s\n",vid,pid,MyDevicePathName);
+ if(HidD_GetManufacturerString(DeviceHandle,string,sizeof(string))==TRUE) wprintf(L"Manufacturer string: %s\n",string);
+ if(HidD_GetProductString(DeviceHandle,string,sizeof(string))==TRUE) wprintf(L"Product string: %s\n",string);
+ }*/
+#endif
+ if (MyDeviceDetected == FALSE){
+ PrintMessage(strings[S_noprog]); //"Programmer not detected\r\n"
+ //gtk_statusbar_push(status_bar,statusID,strings[S_noprog]);
+ }
+ else{
+ PrintMessage(strings[S_prog]); //"Programmer detected\r\n");
+ PrintMessage2("VID=0x%04X PID=0x%04X\r\n",vid,pid);
+ //gtk_statusbar_push(status_bar,statusID,strings[S_prog]);
+ }
+ return MyDeviceDetected;
+}
diff --git a/opgui.glade b/opgui.glade
new file mode 100644
index 0000000..60b9c1a
--- /dev/null
+++ b/opgui.glade
@@ -0,0 +1,3797 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.38.2 -->
+<interface>
+ <requires lib="gtk+" version="3.12"/>
+ <object class="GtkAdjustment" id="I2C_adj">
+ <property name="upper">100</property>
+ <property name="value">1</property>
+ <property name="step-increment">1</property>
+ <property name="page-increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="VPP_adj">
+ <property name="lower">5</property>
+ <property name="upper">15</property>
+ <property name="value">5</property>
+ <property name="step-increment">1</property>
+ <property name="page-increment">10</property>
+ </object>
+ <object class="GtkImage" id="imageRead">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="resource">/res/read.png</property>
+ </object>
+ <object class="GtkImage" id="imageWrite">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="resource">/res/write.png</property>
+ </object>
+ <object class="GtkWindow" id="window">
+ <property name="can-focus">False</property>
+ <property name="window-position">center</property>
+ <property name="default-width">850</property>
+ <property name="default-height">250</property>
+ <signal name="destroy" handler="G_CALLBACK(Xclose)" swapped="no"/>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkStatusbar" id="STATUS_B">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">10</property>
+ <property name="margin-end">10</property>
+ <property name="margin-top">6</property>
+ <property name="margin-bottom">6</property>
+ <property name="spacing">2</property>
+ <property name="baseline-position">bottom</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack-type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolbar">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkToolButton" id="OPEN_T">
+ <property name="name">OPEN_T</property>
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="use-underline">True</property>
+ <property name="icon-name">document-open-symbolic</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolButton" id="SAVE_T">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="use-underline">True</property>
+ <property name="icon-name">document-save-symbolic</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSeparatorToolItem">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolButton" id="READ_T">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="use-underline">True</property>
+ <property name="icon-widget">imageRead</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolButton" id="WRITE_T">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="use-underline">True</property>
+ <property name="icon-widget">imageWrite</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSeparatorToolItem">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolButton" id="STOP_T">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">stop</property>
+ <property name="use-underline">True</property>
+ <property name="icon-name">media-playback-stop-symbolic</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolButton" id="CONNECT_T">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">reconn</property>
+ <property name="use-underline">True</property>
+ <property name="icon-name">gtk-connect</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolButton" id="INFO_T">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">info</property>
+ <property name="use-underline">True</property>
+ <property name="icon-name">help-browser-symbolic</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolButton" id="QUIT_T">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">quit</property>
+ <property name="use-underline">True</property>
+ <property name="icon-name">application-exit-symbolic</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkNotebook" id="NOTEBOOK">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkTextView" id="DATA">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="margin-start">5</property>
+ <property name="margin-top">5</property>
+ <style>
+ <class name="mono"/>
+ </style>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="DATA_T_L">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">dati</property>
+ </object>
+ <packing>
+ <property name="tab-fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="DEVICE_TAB">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">5</property>
+ <property name="margin-top">5</property>
+ <property name="spacing">5</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">5</property>
+ <child>
+ <object class="GtkLabel" id="TYPE_L">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">_tipo</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="TYPE_C">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkLabel" id="DEV_SRC_L">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">label</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="DEV_SRC_E">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkTreeView" id="DEV_TREE">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="halign">start</property>
+ <property name="valign">start</property>
+ <property name="fixed-height-mode">True</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection"/>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="valign">start</property>
+ <property name="margin-start">8</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">6</property>
+ <property name="margin-end">6</property>
+ <property name="margin-top">3</property>
+ <property name="margin-bottom">6</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkLabel" id="DEV_INFO">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="EE_RW">
+ <property name="label" translatable="yes">ee</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">start</property>
+ <property name="margin-start">5</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="PIC_OPT">
+ <property name="can-focus">False</property>
+ <property name="margin-start">5</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">1</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">5</property>
+ <child>
+ <object class="GtkCheckButton" id="RES_READ">
+ <property name="label" translatable="yes">_reserved</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="PROG_ID">
+ <property name="label" translatable="yes">_progID</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="PROG_CAL12">
+ <property name="label" translatable="yes">_progCal</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="OSC_OPT">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">5</property>
+ <property name="margin-end">5</property>
+ <property name="margin-bottom">5</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkRadioButton" id="OSCCAL">
+ <property name="label" translatable="yes">_osccal</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">FILECAL</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="BKOSCCAL">
+ <property name="label" translatable="yes">_bkosccal</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">FILECAL</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="FILECAL">
+ <property name="label" translatable="yes">_file</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">OSCCAL</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="OSCCAL_L">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">__osccal</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="CW_OPT">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">6</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">5</property>
+ <property name="margin-end">5</property>
+ <property name="margin-bottom">5</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">5</property>
+ <child>
+ <object class="GtkCheckButton" id="FORCE_CW">
+ <property name="label" translatable="yes">_forcecw</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkBox" id="CW1_OPT">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">CW1</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="CW1">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="width-chars">4</property>
+ <property name="max-width-chars">4</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="CW2_OPT">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">CW2</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="CW2">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="width-chars">4</property>
+ <property name="max-width-chars">4</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="CW3_OPT">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">CW3</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="CW3">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="width-chars">4</property>
+ <property name="max-width-chars">4</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="CW4_OPT">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">CW4</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="CW4">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="width-chars">4</property>
+ <property name="max-width-chars">4</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkBox" id="CW5_OPT">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">CW5</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="CW5">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="width-chars">4</property>
+ <property name="max-width-chars">4</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="CW6_OPT">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">CW6</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="CW6">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="width-chars">4</property>
+ <property name="max-width-chars">4</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="CW7_OPT">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">CW7</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="CW7">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="width-chars">4</property>
+ <property name="max-width-chars">4</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="CW8_OPT">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">CW8</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="CW8">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="width-chars">4</property>
+ <property name="max-width-chars">4</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">Config Word</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="padding">5</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="ICD_OPT">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">5</property>
+ <property name="margin-end">5</property>
+ <property name="margin-bottom">5</property>
+ <property name="spacing">48</property>
+ <child>
+ <object class="GtkCheckButton" id="ICD">
+ <property name="label" translatable="yes">_icd</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkLabel" id="ICD_ADDR_L">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">_address</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="ICD_ADDR">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="width-chars">5</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">ICD</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="padding">5</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="AVR_OPT">
+ <property name="can-focus">False</property>
+ <property name="margin-start">5</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">5</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkEntry" id="FUSEL">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="width-chars">2</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="FUSEL_C">
+ <property name="label" translatable="yes">_fuselow</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkEntry" id="FUSEH">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="width-chars">2</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="FUSEH_C">
+ <property name="label" translatable="yes">_fusehigh</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkEntry" id="FUSEX">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="width-chars">2</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="FUSEX_C">
+ <property name="label" translatable="yes">_fuseext</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkEntry" id="FUSELCK">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="width-chars">2</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="FUSELCK_C">
+ <property name="label" translatable="yes">_fuselock</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="FUSEL_W3K">
+ <property name="label" translatable="yes">_writefuselow3k</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="halign">start</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="DEVICE_NAME">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">_dev</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="DEVICE_L">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">_dev</property>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ <property name="tab-fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="OPTIONS_TAB">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">5</property>
+ <property name="margin-top">5</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">5</property>
+ <child>
+ <object class="GtkButton" id="CONNECT">
+ <property name="label" translatable="yes">_connect</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="halign">start</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">VID</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="VID">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="width-chars">4</property>
+ <property name="max-width-chars">4</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">PID</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="PID">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="width-chars">4</property>
+ <property name="max-width-chars">4</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="padding">20</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="TEST">
+ <property name="label" translatable="yes">_test</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="halign">start</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="LOG">
+ <property name="label" translatable="yes">_log</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">start</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="3VCHECK">
+ <property name="label" translatable="yes">3v3nocheck</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">start</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="S1">
+ <property name="label" translatable="yes">_s1</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">start</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkLabel" id="MAXERR_L">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">_maxerr</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="MAXERR">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="width-chars">4</property>
+ <property name="max-width-chars">4</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">6</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="OPTIONS_L">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">_options</property>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ <property name="tab-fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="I2CSPI_TAB">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">10</property>
+ <property name="margin-top">5</property>
+ <property name="spacing">15</property>
+ <child>
+ <object class="GtkFrame">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="valign">start</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">5</property>
+ <child>
+ <object class="GtkRadioButton" id="I2C8BIT">
+ <property name="label" translatable="yes">I2C 8 Bit</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="I2C16BIT">
+ <property name="label" translatable="yes">I2C 16 Bit</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">I2C8BIT</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSeparator">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="SPI00">
+ <property name="label" translatable="yes">SPI(00)</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">I2C8BIT</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="SPI01">
+ <property name="label" translatable="yes">SPI(01)</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">I2C8BIT</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="SPI10">
+ <property name="label" translatable="yes">SPI(10)</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">I2C8BIT</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="SPI11">
+ <property name="label" translatable="yes">SPI(11)</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">I2C8BIT</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">6</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="I2CMODE">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">_mode</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">5</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="spacing">5</property>
+ <child>
+ <object class="GtkLabel" id="NBYTE_L">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">_byte</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="NBYTE_S">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="max-length">3</property>
+ <property name="input-purpose">number</property>
+ <property name="adjustment">I2C_adj</property>
+ <property name="climb-rate">1</property>
+ <property name="numeric">True</property>
+ <property name="value">1</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="spacing">5</property>
+ <child>
+ <object class="GtkLabel" id="SPEED_L">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">_speed</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="SPEED_C">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="active">0</property>
+ <items>
+ <item translatable="yes">100 kbps</item>
+ <item translatable="yes">200 kbps</item>
+ <item translatable="yes">300/400 kbps</item>
+ <item translatable="yes">500/800 kbps</item>
+ </items>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="spacing">5</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkButton" id="SEND_B">
+ <property name="label" translatable="yes">_send</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="RECEIVE_B">
+ <property name="label" translatable="yes">_receive</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="DATASEND_L">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">_datasend</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="DATASEND">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="DATATR_L">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">_datatransferred</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">out</property>
+ <child>
+ <object class="GtkTextView" id="DATATR">
+ <property name="width-request">250</property>
+ <property name="height-request">60</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="editable">False</property>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">6</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">I2C/SPI</property>
+ </object>
+ <packing>
+ <property name="position">3</property>
+ <property name="tab-fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="ICD_TAB">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">5</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkToolbar">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkToolButton" id="ICD_RUN">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="use-underline">True</property>
+ <property name="icon-name">go-next-symbolic</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolButton" id="ICD_HALT">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="use-underline">True</property>
+ <property name="icon-name">media-playback-pause-symbolic</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolButton" id="ICD_STEP">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="use-underline">True</property>
+ <property name="icon-name">go-last-symbolic</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolButton" id="ICD_STEPOVER">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="use-underline">True</property>
+ <property name="icon-name">media-seek-forward-symbolic</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSeparatorToolItem">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolButton" id="ICD_STOP">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="use-underline">True</property>
+ <property name="icon-name">media-playback-stop-symbolic</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSeparatorToolItem">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolButton" id="ICD_REFRESH">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="use-underline">True</property>
+ <property name="icon-name">media-playlist-repeat-symbolic</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSeparatorToolItem">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolButton" id="LOADCOFF_B">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">_loadcoff</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSeparatorToolItem">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolItem">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkEntry" id="ICD_CMD_E">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="width-chars">10</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSeparatorToolItem">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolButton" id="ICD_HELP">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">help</property>
+ <property name="use-underline">True</property>
+ <property name="icon-name">help-browser-symbolic</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkLabel" id="ICD_SOURCE_L">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">_source</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="padding">7</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkTextView" id="ICD_SOURCE">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="editable">False</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkLabel" id="ICD_STAT_L">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">_status</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuBar">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkMenuItem" id="OPTIONS_M">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">_opt</property>
+ <property name="use-underline">True</property>
+ <child type="submenu">
+ <object class="GtkMenu">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkCheckMenuItem" id="PCOUNT_M">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">_counter</property>
+ <property name="use-underline">True</property>
+ <property name="active">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkCheckMenuItem" id="STATUS_M">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">_status</property>
+ <property name="use-underline">True</property>
+ <property name="active">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkCheckMenuItem" id="BANK0_M">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">_b0</property>
+ <property name="use-underline">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkCheckMenuItem" id="BANK1_M">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">_b1</property>
+ <property name="use-underline">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkCheckMenuItem" id="BANK2_M">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">_b2</property>
+ <property name="use-underline">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkCheckMenuItem" id="BANK3_M">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">_b3</property>
+ <property name="use-underline">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkCheckMenuItem" id="EE_M">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">_ee</property>
+ <property name="use-underline">True</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkTextView" id="ICD_STATUS">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="editable">False</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">ICD</property>
+ </object>
+ <packing>
+ <property name="position">4</property>
+ <property name="tab-fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="IO_TAB">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">5</property>
+ <property name="margin-top">5</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">10</property>
+ <child>
+ <object class="GtkFrame">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkCheckButton" id="IOEN">
+ <property name="label" translatable="yes">_io</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">start</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">5</property>
+ <property name="margin-end">5</property>
+ <property name="margin-bottom">5</property>
+ <property name="spacing">30</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="spacing">4</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">RB7</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="RB7_0">
+ <property name="label" translatable="yes">0</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="RB7_1">
+ <property name="label" translatable="yes">1</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">RB7_0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="RB7_I">
+ <property name="label" translatable="yes">INPUT:</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">RB7_0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="RB7_L">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="width-chars">2</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="spacing">4</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">RB6</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="RB6_0">
+ <property name="label" translatable="yes">0</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="RB6_1">
+ <property name="label" translatable="yes">1</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">RB6_0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="RB6_I">
+ <property name="label" translatable="yes">INPUT:</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">RB6_0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="RB6_L">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="width-chars">2</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="spacing">4</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">RB5</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="RB5_0">
+ <property name="label" translatable="yes">0</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="RB5_1">
+ <property name="label" translatable="yes">1</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">RB5_0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="RB5_I">
+ <property name="label" translatable="yes">INPUT:</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">RB5_0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="RB5_L">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="width-chars">2</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="spacing">4</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">RB4</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="RB4_0">
+ <property name="label" translatable="yes">0</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="RB4_1">
+ <property name="label" translatable="yes">1</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">RB4_0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="RB4_I">
+ <property name="label" translatable="yes">INPUT:</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">RB4_0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="RB4_L">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="width-chars">2</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="spacing">4</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">RB3</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="RB3_0">
+ <property name="label" translatable="yes">0</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="RB3_1">
+ <property name="label" translatable="yes">1</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">RB3_0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="RB3_I">
+ <property name="label" translatable="yes">INPUT:</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">RB3_0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="RB3_L">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="width-chars">2</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="spacing">4</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">RB2</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="RB2_0">
+ <property name="label" translatable="yes">0</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="RB2_1">
+ <property name="label" translatable="yes">1</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">RB2_0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="RB2_I">
+ <property name="label" translatable="yes">INPUT:</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">RB2_0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="RB2_L">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="width-chars">2</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="spacing">4</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">RB1</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="RB1_0">
+ <property name="label" translatable="yes">0</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="RB1_1">
+ <property name="label" translatable="yes">1</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">RB1_0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="RB1_I">
+ <property name="label" translatable="yes">INPUT:</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">RB1_0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="RB1_L">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="width-chars">2</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="spacing">4</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">RB0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="RB0_0">
+ <property name="label" translatable="yes">0</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="RB0_1">
+ <property name="label" translatable="yes">1</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">RB0_0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="RB0_I">
+ <property name="label" translatable="yes">INPUT:</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">RB0_0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="RB0_L">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="width-chars">2</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">7</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="spacing">4</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">RC7</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="RC7_0">
+ <property name="label" translatable="yes">0</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="RC7_1">
+ <property name="label" translatable="yes">1</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">RC7_0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="RC7_I">
+ <property name="label" translatable="yes">INPUT:</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">RC7_0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="RC7_L">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="width-chars">2</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="spacing">4</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">RC6</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="RC6_0">
+ <property name="label" translatable="yes">0</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="RC6_1">
+ <property name="label" translatable="yes">1</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">RC6_0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="RC6_I">
+ <property name="label" translatable="yes">INPUT:</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">RC6_0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="RC6_L">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="width-chars">2</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="spacing">4</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">RA5</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="RA5_0">
+ <property name="label" translatable="yes">0</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="RA5_1">
+ <property name="label" translatable="yes">1</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">RA5_0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="RA5_I">
+ <property name="label" translatable="yes">INPUT:</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">RA5_0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="RA5_L">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="width-chars">2</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="spacing">4</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">RA4</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="RA4_0">
+ <property name="label" translatable="yes">0</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="RA4_1">
+ <property name="label" translatable="yes">1</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">RA4_0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="RA4_I">
+ <property name="label" translatable="yes">INPUT:</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">RA4_0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="RA4_L">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="width-chars">2</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="spacing">4</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">RA3</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="RA3_0">
+ <property name="label" translatable="yes">0</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="RA3_1">
+ <property name="label" translatable="yes">1</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">RA3_0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="RA3_I">
+ <property name="label" translatable="yes">INPUT:</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">RA3_0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="RA3_L">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="width-chars">2</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">I/O</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="spacing">10</property>
+ <child>
+ <object class="GtkCheckButton" id="VDDUEN">
+ <property name="label" translatable="yes">VDDU</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="VPPUEN">
+ <property name="label" translatable="yes">VPPU</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="DCDCEN">
+ <property name="label" translatable="yes">DCDC</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScale" id="DCDC_S">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">False</property>
+ <property name="adjustment">VPP_adj</property>
+ <property name="restrict-to-fill-level">False</property>
+ <property name="fill-level">0</property>
+ <property name="round-digits">1</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">5</property>
+ <property name="margin-end">5</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">5</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="spacing">5</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkLabel" id="CMDSEND_L">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">_datasend</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="CMDSEND">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="margin-start">5</property>
+ <property name="margin-top">10</property>
+ <property name="width-chars">35</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-end">5</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkLabel" id="CMDTR_L">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">_datatransferred</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">out</property>
+ <child>
+ <object class="GtkTextView" id="CMDTR">
+ <property name="width-request">200</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="editable">False</property>
+ <property name="input-purpose">number</property>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="CMDTR_B">
+ <property name="label" translatable="yes">_send</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="halign">start</property>
+ <property name="margin-start">5</property>
+ <property name="margin-bottom">5</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="CMD_L">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">_cmd</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">5</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">I/O</property>
+ </object>
+ <packing>
+ <property name="position">5</property>
+ <property name="tab-fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="UTILITY_TAB">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">5</property>
+ <property name="margin-top">5</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">10</property>
+ <child>
+ <object class="GtkFrame">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-end">5</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">5</property>
+ <property name="margin-end">5</property>
+ <property name="margin-bottom">5</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">5</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="spacing">10</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">Hex</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="HEXIN">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="DATAOUT">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="editable">False</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">HEX -&gt; DATA</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-end">5</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">5</property>
+ <property name="margin-end">5</property>
+ <property name="margin-bottom">5</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">5</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="spacing">10</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">_addr</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="ADDRIN">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="spacing">10</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">_data</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="DATAIN">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="spacing">10</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">Hex</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="HEXOUT">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="editable">False</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="HEXSAVE">
+ <property name="label" translatable="yes">_save</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="halign">start</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">DATA -&gt; HEX</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">6</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">Utility</property>
+ </object>
+ <packing>
+ <property name="position">6</property>
+ <property name="tab-fill">False</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/progAVR.c b/progAVR.c
new file mode 100644
index 0000000..47fdcc4
--- /dev/null
+++ b/progAVR.c
@@ -0,0 +1,2450 @@
+/*
+ * progAVR.c - algorithms to program the Atmel AVR family of microcontrollers
+ * Copyright (C) 2009-2021 Alberto Maccioni
+ *
+ * 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"
+
+#define LOCK 1
+#define FUSE 2
+#define FUSE_H 4
+#define FUSE_X 8
+#define CAL 16
+#define SLOW 256
+#define RST 0x40
+
+struct AVRID{
+ int id;
+ char *device;
+} AVRLIST[]={
+ //1K
+ {0x9001,"AT90S1200"},
+ {0x9004,"ATtiny11"},
+ {0x9005,"ATtiny12"},
+ {0x9007,"ATtiny13"},
+ //2K
+ {0x9101,"AT90S2313"},
+ {0x9109,"ATtiny26"},
+ {0x910A,"ATtiny2313"},
+ {0x910B,"ATtiny24"},
+ {0x910C,"ATtiny261"},
+ //4K
+ {0x9205,"ATmega48"},
+ {0x920A,"ATmega48PA"},
+ {0x9207,"ATtiny44"},
+ {0x9208,"ATtiny461"},
+ {0x9209,"ATtiny48"},
+ {0x920D,"ATtiny4313"},
+ //8K
+ {0x9301,"AT90S8515"},
+ {0x9303,"AT90S8535"},
+ {0x9306,"ATmega8515"},
+ {0x9307,"ATmega8"},
+ {0x9308,"ATmega8535"},
+ {0x930A,"ATmega88"},
+ {0x930C,"ATtiny84"},
+ {0x930D,"ATtiny861"},
+ {0x930F,"ATmega88PA"},
+ {0x9311,"ATtiny88"},
+ //16K
+ {0x9403,"ATmega16"},
+ {0x9406,"ATmega168"},
+ {0x940A,"ATmega164PA"},
+ {0x940B,"ATmega168PA"},
+ {0x940F,"ATmega164A"},
+ //32K
+ {0x950F,"ATmega328P"},
+ {0x9511,"ATmega324PA"},
+ {0x9514,"ATmega328"},
+ {0x9515,"ATmega324A"},
+ //64K
+ {0x9602,"ATmega64"},
+ {0x9609,"ATmega644A"},
+ {0x960A,"ATmega644PA"},
+ //128K
+ {0x9705,"ATmega1284P"},
+ {0x9706,"ATmega1284"},
+};
+
+void AtmelID(BYTE id[])
+{
+ char str[128]="";
+ int i,idw=(id[1]<<8)+id[2];
+ if(id[0]==0&&id[1]==1&&id[2]==2){
+ PrintMessage(strings[S_Protected]); //"Device protected"
+ return;
+ }
+ if(id[0]==0x1E) strcat(str,"Atmel ");
+ for(i=0;i<sizeof(AVRLIST)/sizeof(AVRLIST[0]);i++){
+ if(idw==AVRLIST[i].id){
+ strcat(str,AVRLIST[i].device);
+ i=1000;
+ }
+ }
+ switch(id[1]){
+ case 0x90:
+ strcat(str," 1KB Flash");
+ break;
+ case 0x91:
+ strcat(str," 2KB Flash");
+ break;
+ case 0x92:
+ strcat(str," 4KB Flash");
+ break;
+ case 0x93:
+ strcat(str," 8KB Flash");
+ break;
+ case 0x94:
+ strcat(str," 16KB Flash");
+ break;
+ case 0x95:
+ strcat(str," 32KB Flash");
+ break;
+ case 0x96:
+ strcat(str," 64KB Flash");
+ break;
+ case 0x97:
+ strcat(str," 128KB Flash");
+ break;
+ }
+ if(i!=1001) strcat(str,strings[S_nodev]); //"Unknown device\r\n");
+ else strcat(str,"\r\n");
+ PrintMessage(str);
+}
+
+void DisplayCODEAVR(int dim){
+// display AVR CODE memory
+ char s[256]="",t[256]="";
+ int valid=0,empty=1,i,j,lines=0;
+ char* aux=(char*)malloc((dim/COL+1)*(16+COL*6));
+ aux[0]=0;
+ s[0]=0;
+ for(i=0;i<dim&&i<size;i+=COL*2){
+ valid=0;
+ for(j=i;j<i+COL*2&&j<dim;j++){
+ sprintf(t,"%02X ",memCODE[j]);
+ strcat(s,t);
+ if(memCODE[j]<0xff) valid=1;
+ }
+ if(valid){
+ sprintf(t,"%04X: %s\r\n",i,s);
+ strcat(aux,t);
+ empty=0;
+ lines++;
+ if(lines>500){ //limit number of lines printed
+ strcat(aux,"(...)\r\n");
+ i=(dim<size?dim:size)-COL*4;
+ lines=490;
+ }
+ }
+ s[0]=0;
+ }
+ if(empty) PrintMessage(strings[S_Empty]); //empty
+ else PrintMessage(aux);
+ free(aux);
+}
+
+//Software SPI for very slow speed
+//RB1=CLK, RB0=MISO, RC7=MOSI, RC6=RESET
+//speed in bit/s min 10
+int SWSPI(int data, int speed){
+ int i,j,din=0;
+ double Tbit=1.0/speed*1e6; //Tbit in us
+ if(saveLog) fprintf(logfile,"SWSPI(0x%X,%d)\n",data,speed);
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=(int)(Tbit/2)>>8;
+ bufferU[j++]=(int)(Tbit/2)&0xff;
+ bufferU[j++]=SET_PORT_DIR;
+ bufferU[j++]=0xF5; //TRISB
+ bufferU[j++]=0x3F; //TRISA-C (RC7:RC6:RA5:RA4:RA3:X:X:X)
+ for(i=0;i<4;i++){ //first nibble
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0; //PORTB CLK=0
+ bufferU[j++]=data&0x80; //PORTA-C
+ bufferU[j++]=WAIT_T3; //half bit delay
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=2; //PORTB CLK=1
+ bufferU[j++]=data&0x80; //PORTA-C
+ bufferU[j++]=READ_B;
+ bufferU[j++]=WAIT_T3; //half bit delay
+ data<<=1;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(1+4*(Tbit/1000.0+0.5));
+ for(j=0;j<DIMBUF-1&&bufferI[j]!=READ_B;j++);
+ din+=bufferI[j+1]&1;
+ din<<=1;
+ for(j+=2;j<DIMBUF-1&&bufferI[j]!=READ_B;j++);
+ din+=bufferI[j+1]&1;
+ din<<=1;
+ for(j+=2;j<DIMBUF-1&&bufferI[j]!=READ_B;j++);
+ din+=bufferI[j+1]&1;
+ din<<=1;
+ for(j+=2;j<DIMBUF-1&&bufferI[j]!=READ_B;j++);
+ din+=bufferI[j+1]&1;
+ din<<=1;
+ j=0;
+ for(i=0;i<4;i++){ //second nibble
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0; //PORTB CLK=0
+ bufferU[j++]=data&0x80; //PORTA-C
+ bufferU[j++]=WAIT_T3; //half bit delay
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=2; //PORTB CLK=1
+ bufferU[j++]=data&0x80; //PORTA-C
+ bufferU[j++]=READ_B;
+ bufferU[j++]=WAIT_T3; //half bit delay
+ data<<=1;
+ }
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0; //PORTB CLK=0
+ bufferU[j++]=0; //PORTA-C
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(1+4*(Tbit/1000.0+0.5));
+ for(j=0;j<DIMBUF-1&&bufferI[j]!=READ_B;j++);
+ din+=bufferI[j+1]&1;
+ din<<=1;
+ for(j+=2;j<DIMBUF-1&&bufferI[j]!=READ_B;j++);
+ din+=bufferI[j+1]&1;
+ din<<=1;
+ for(j+=2;j<DIMBUF-1&&bufferI[j]!=READ_B;j++);
+ din+=bufferI[j+1]&1;
+ din<<=1;
+ for(j+=2;j<DIMBUF-1&&bufferI[j]!=READ_B;j++);
+ din+=bufferI[j+1]&1;
+ if(saveLog) fprintf(logfile,"Read 0x%X\n",din);
+ return din;
+}
+
+//Write fuse at low speed
+//speed in bit/s min 10
+void WriteATfuseSlow(int fuse){
+#define SPEED 3000
+ int j,d;
+ fuse&=0xFF;
+ if(FWVersion<0x900){
+ PrintMessage1(strings[S_FWver2old],"0.9.0"); //"This firmware is too old. Version %s is required\r\n"
+ return;
+ }
+ if(saveLog){
+ OpenLogFile(); //"Log.txt"
+ fprintf(logfile,"WriteATfuseSlow(0x%X)\n",fuse);
+ }
+ PrintMessage(strings[S_FuseAreaW]); //"Write Fuse ... "
+ j=0;
+ bufferU[j++]=VREG_DIS; //Disable HV reg
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x0;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=SET_PORT_DIR;
+ bufferU[j++]=0xF5; //TRISB
+ bufferU[j++]=0x3F; //TRISA-C (RC7:RC6:RA5:RA4:RA3:X:X:X)
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=CLOCK_GEN;
+ bufferU[j++]=1; //0=100k,200k,500k,1M,2M,3M
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ msDelay(20); //min 20ms from VDD
+ SWSPI(0xAC,SPEED);
+ SWSPI(0x53,SPEED);
+ d=SWSPI(0,SPEED);
+ SWSPI(0,SPEED);
+ if(d!=0x53){ //does not respond
+ j=0;
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x0;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ PrintMessage(strings[S_SyncErr]); //"Synchronization error\r\n"
+ if(saveLog) CloseLogFile();
+ return;
+ }
+ SWSPI(0xAC,SPEED); //Write fuse
+ SWSPI(0xA0,SPEED);
+ SWSPI(0x00,SPEED);
+ SWSPI(fuse,SPEED);
+ msDelay(9);
+ SWSPI(0x50,SPEED); //Read fuse
+ SWSPI(0x00,SPEED);
+ SWSPI(0x00,SPEED);
+ d=SWSPI(0,SPEED);
+ if(d!=fuse){
+ PrintMessage3(strings[S_WErr1],"fuse",fuse,d); //"Error writing %s: written %02X, read %02X" NL;
+ }
+ j=0;
+ bufferU[j++]=CLOCK_GEN;
+ bufferU[j++]=0xFF;
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ PrintMessage(strings[S_Compl]); //"completed\r\n"
+}
+
+//Find right SPI speed to enter
+//test mode and synchronize with AVR
+//return Tbyte or 0 when sync was not found
+double SyncSPI(){
+ int z=0,i,j;
+ double Tbyte; //byte delay in ms
+ j=0;
+ bufferU[j++]=SPI_INIT;
+ bufferU[j++]=2; //0~=100k, 1~=200k, 2~=300k but really is 200k
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ for(i=1;i<256;i++){ //increase T more than linearly; Tmin=1
+ if(i>10) i++;
+ if(i>20) i+=2;
+ if(i>40) i+=4;
+ if(i>80) i+=4;
+ if(i>160) i+=8;
+ Tbyte=(20+i*4)/1000.0; //from firmware simulation
+ j=0;
+ bufferU[j++]=CLOCK_GEN; //reset with clock at 0
+ bufferU[j++]=0xFF;
+ bufferU[j++]=EN_VPP_VCC; //VDD=0
+ bufferU[j++]=0x0;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T1T2;
+ bufferU[j++]=i; //force T
+ bufferU[j++]=0;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0;
+ bufferU[j++]=RST;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=CLOCK_GEN;
+ bufferU[j++]=5; //0=100k,200k,500k,1M,2M,3M
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(9);
+ msDelay(20); //min 20ms from reset
+ j=0;
+ bufferU[j++]=SPI_WRITE; //Programming enable
+ bufferU[j++]=2;
+ bufferU[j++]=0xAC;
+ bufferU[j++]=0x53;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=2;
+ bufferU[j++]=SPI_WRITE; //just to test communication
+ bufferU[j++]=11;
+ bufferU[j++]=0x55;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0xAA;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x55;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0xAA;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x30;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=1;
+ bufferU[j++]=SPI_WRITE;
+ bufferU[j++]=3;
+ bufferU[j++]=0x30;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=1;
+ bufferU[j++]=SPI_WRITE;
+ bufferU[j++]=3;
+ bufferU[j++]=0x30;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=1;
+ bufferU[j++]=SPI_WRITE;
+ bufferU[j++]=3;
+ bufferU[j++]=0x30;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=1;
+ bufferU[j++]=SPI_WRITE;
+ bufferU[j++]=3;
+ bufferU[j++]=0x30;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=1;
+ bufferU[j++]=SPI_WRITE; //Programming enable
+ bufferU[j++]=2;
+ bufferU[j++]=0xAC;
+ bufferU[j++]=0x53;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=2;
+ bufferU[j++]=SPI_WRITE;
+ bufferU[j++]=3;
+ bufferU[j++]=0x30;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=1;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(1.5+32*Tbyte*1.1);
+ int d0,d1,d2,d3,d4,d5,d6,d7;
+ for(z=0;z<DIMBUF-2&&bufferI[z]!=SPI_READ;z++);
+ //if(bufferI[z+2]==0x53) break;
+ d0=bufferI[z+2];
+ for(z+=bufferI[z+1]+1;z<DIMBUF-2&&bufferI[z]!=SPI_READ;z++);
+ d1=bufferI[z+2];
+ for(z+=bufferI[z+1]+1;z<DIMBUF-2&&bufferI[z]!=SPI_READ;z++);
+ d2=bufferI[z+2];
+ for(z+=bufferI[z+1]+1;z<DIMBUF-2&&bufferI[z]!=SPI_READ;z++);
+ d3=bufferI[z+2];
+ for(z+=bufferI[z+1]+1;z<DIMBUF-2&&bufferI[z]!=SPI_READ;z++);
+ d4=bufferI[z+2];
+ for(z+=bufferI[z+1]+1;z<DIMBUF-2&&bufferI[z]!=SPI_READ;z++);
+ d5=bufferI[z+2];
+ for(z+=bufferI[z+1]+1;z<DIMBUF-2&&bufferI[z]!=SPI_READ;z++);
+ d6=bufferI[z+2];
+ for(z+=bufferI[z+1]+1;z<DIMBUF-2&&bufferI[z]!=SPI_READ;z++);
+ d7=bufferI[z+2];
+ //verify that received data is correct
+ if(d0==0x53&&d6==0x53&&d1==d2&&d1==d3&&d1==d4&&d1==d5&&d1==d7) break;
+ }
+ if(i>256){
+ PrintMessage(strings[S_SyncErr]); //"Synchronization error\r\n"
+ if(saveLog) fprintf(logfile,strings[S_SyncErr]);
+ return 0;
+ }
+ //Add some margin
+ i++;
+ i+=i/10;
+ if(i>255) i=255;
+ Tbyte=(20+i*4)/1000.0; //from firmware simulation
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T1T2;
+ bufferU[j++]=i; //force T
+ bufferU[j++]=0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ sprintf(str,strings_it[I_AT_COMM],8/Tbyte); //"Communicating @ %.0f kbps\r\n"
+ PrintMessage(str);
+ if(saveLog) fprintf(logfile,str);
+ return Tbyte;
+}
+
+void ReadAT(int dim, int dim2, int options)
+// read ATMEL AVR
+// dim=FLASH size in bytes, dim2=EEPROM size
+// options: LOCK,FUSE,FUSE_H,FUSE_X,CAL
+{
+ int k=0,k2=0,z=0,i,j;
+ double Tbyte; //byte delay in ms
+ BYTE signature[]={0,0,0};
+ if(dim>0x20000||dim<0){
+ PrintMessage(strings[S_CodeLim]); //"Code size out of limits\r\n"
+ return;
+ }
+ if(dim2>0x1000||dim2<0){
+ PrintMessage(strings[S_EELim]); //"EEPROM size out of limits\r\n"
+ return;
+ }
+ if(saveLog){
+ OpenLogFile(); //"Log.txt"
+ fprintf(logfile,"ReadAT(0x%X,0x%X,0x%X)\n",dim,dim2,options);
+ }
+ size=dim;
+ sizeEE=dim2;
+ if(memCODE) free(memCODE);
+ memCODE=(unsigned char*)malloc(dim); //CODE
+ if(memEE) free(memEE);
+ memEE=(unsigned char*)malloc(dim2); //EEPROM
+ for(j=0;j<size;j++) memCODE[j]=0xFF;
+ for(j=0;j<sizeEE;j++) memEE[j]=0xFF;
+ unsigned int start=GetTickCount();
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2000>>8;
+ bufferU[j++]=2000&0xff;
+ bufferU[j++]=VREG_DIS; //Disable HV reg
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ Tbyte=SyncSPI();
+ if(Tbyte==0){
+ if(saveLog) CloseLogFile();
+ return;
+ }
+ j=0;
+ bufferU[j++]=SPI_WRITE; //Read signature bytes
+ bufferU[j++]=3;
+ bufferU[j++]=0x30;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=1;
+ bufferU[j++]=SPI_WRITE; //Read signature bytes
+ bufferU[j++]=3;
+ bufferU[j++]=0x30;
+ bufferU[j++]=0;
+ bufferU[j++]=1;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=1;
+ bufferU[j++]=SPI_WRITE; //Read signature bytes
+ bufferU[j++]=3;
+ bufferU[j++]=0x30;
+ bufferU[j++]=0;
+ bufferU[j++]=2;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=1;
+ if(options&LOCK){ //LOCK byte
+ bufferU[j++]=SPI_WRITE;
+ bufferU[j++]=3;
+ bufferU[j++]=0x58;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=1;
+ }
+ if(options&FUSE){ //FUSE byte
+ bufferU[j++]=SPI_WRITE;
+ bufferU[j++]=3;
+ bufferU[j++]=0x50;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=1;
+ }
+ if(options&FUSE_H){ //FUSE high byte
+ bufferU[j++]=SPI_WRITE;
+ bufferU[j++]=3;
+ bufferU[j++]=0x58;
+ bufferU[j++]=8;
+ bufferU[j++]=0;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=1;
+ }
+ if(options&FUSE_X){ //extended FUSE byte
+ bufferU[j++]=SPI_WRITE;
+ bufferU[j++]=3;
+ bufferU[j++]=0x50;
+ bufferU[j++]=8;
+ bufferU[j++]=0;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=1;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(1.5+7*4.5*Tbyte);
+ for(z=0;z<DIMBUF-2&&bufferI[z]!=SPI_READ;z++);
+ signature[0]=bufferI[z+2];
+ for(z+=3;z<DIMBUF-2&&bufferI[z]!=SPI_READ;z++);
+ signature[1]=bufferI[z+2];
+ for(z+=3;z<DIMBUF-2&&bufferI[z]!=SPI_READ;z++);
+ signature[2]=bufferI[z+2];
+ PrintMessage3("CHIP ID:%02X%02X%02X\r\n",signature[0],signature[1],signature[2]);
+ AtmelID(signature);
+ if(options&LOCK){ //LOCK byte
+ for(z+=3;z<DIMBUF-2&&bufferI[z]!=SPI_READ;z++);
+ PrintMessage1("LOCK bits:\t 0x%02X\r\n",bufferI[z+2]);
+ }
+ if(options&FUSE){ //FUSE byte
+ for(z+=3;z<DIMBUF-2&&bufferI[z]!=SPI_READ;z++);
+ PrintMessage1("FUSE bits:\t 0x%02X\r\n",bufferI[z+2]);
+ }
+ if(options&FUSE_H){ //FUSE high byte
+ for(z+=3;z<DIMBUF-2&&bufferI[z]!=SPI_READ;z++);
+ PrintMessage1("FUSE HIGH bits:\t 0x%02X\r\n",bufferI[z+2]);
+ }
+ if(options&FUSE_X){ //extended FUSE byte
+ for(z+=3;z<DIMBUF-2&&bufferI[z]!=SPI_READ;z++);
+ PrintMessage1("Extended FUSE bits: 0x%02X\r\n",bufferI[z+2]);
+ }
+ if(options&CAL){ //calibration byte
+ j=0;
+ bufferU[j++]=SPI_WRITE;
+ bufferU[j++]=3;
+ bufferU[j++]=0x38;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=1;
+ bufferU[j++]=SPI_WRITE;
+ bufferU[j++]=3;
+ bufferU[j++]=0x38;
+ bufferU[j++]=0;
+ bufferU[j++]=1;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=1;
+ bufferU[j++]=SPI_WRITE;
+ bufferU[j++]=3;
+ bufferU[j++]=0x38;
+ bufferU[j++]=0;
+ bufferU[j++]=2;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=1;
+ bufferU[j++]=SPI_WRITE;
+ bufferU[j++]=3;
+ bufferU[j++]=0x38;
+ bufferU[j++]=0;
+ bufferU[j++]=3;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=1;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(1.5+4.5*4*Tbyte);
+ for(z=0;z<DIMBUF-2&&bufferI[z]!=SPI_READ;z++);
+ PrintMessage1("Calibration bits:\t 0x%02X",bufferI[z+2]);
+ for(z+=3;z<DIMBUF-2&&bufferI[z]!=SPI_READ;z++);
+ PrintMessage1(",0x%02X",bufferI[z+2]);
+ for(z+=3;z<DIMBUF-2&&bufferI[z]!=SPI_READ;z++);
+ PrintMessage1(",0x%02X",bufferI[z+2]);
+ for(z+=3;z<DIMBUF-2&&bufferI[z]!=SPI_READ;z++);
+ PrintMessage1(",0x%02X\r\n",bufferI[z+2]);
+ }
+//****************** read code ********************
+ PrintMessage(strings[S_CodeReading1]); //read code ...
+ if(saveLog) fprintf(logfile,"%s\n",strings[S_CodeReading1]); //read code ...
+ PrintStatusSetup();
+ int c=(DIMBUF-5)/2;
+ for(i=0,j=0;i<dim;i+=c*2){
+ bufferU[j++]=AT_READ_DATA;
+ bufferU[j++]=i<(dim-2*c)?c:(dim-i)/2;
+ bufferU[j++]=i>>9;
+ bufferU[j++]=i>>1;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(1.5+240*Tbyte);
+ if(bufferI[0]==AT_READ_DATA){ //static references, verify!!
+ for(z=2;z<bufferI[1]*2+2&&z<DIMBUF;z++) memCODE[k++]=bufferI[z];
+ }
+ PrintStatus(strings[S_CodeReading],i*100/(dim+dim2),i); //"Reading: %3d%%, add. %03X"
+ if(RWstop) i=dim;
+ j=0;
+ if(saveLog) fprintf(logfile,strings[S_Log7],i,i,k,k); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ PrintStatusEnd();
+ if(k!=dim){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ReadCodeErr2],dim,k); //"Errore in lettura area programma, richiesti %d byte, letti %d\r\n"
+ }
+ else PrintMessage(strings[S_Compl]); //"completed\r\n"
+//****************** read eeprom ********************
+ if(dim2){
+ PrintMessage(strings[S_ReadEE]); //read EE ...
+ if(saveLog) fprintf(logfile,"%s\n",strings[S_ReadEE]); //Read EEPROM ...
+ PrintStatusSetup();
+ int n=0;
+ for(k2=0,i=0,j=0;i<dim2;i++){
+ bufferU[j++]=SPI_WRITE; //Read eeprom memory
+ bufferU[j++]=3;
+ bufferU[j++]=0xA0;
+ bufferU[j++]=i>>8;
+ bufferU[j++]=i;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=1;
+ n++;
+ if(j>DIMBUF-9||i==dim-1){
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(1.5+4*n*Tbyte*1.3);
+ for(z=0;z<DIMBUF-2;z++){
+ if(bufferI[z]==SPI_READ&&bufferI[z+1]==1){
+ memEE[k2++]=bufferI[z+2];
+ z+=3;
+ }
+ }
+ PrintStatus(strings[S_CodeReading],(i+dim)*100/(dim+dim2),i); //"Reading: %3d%%, add. %03X"
+ if(RWstop) i=dim2;
+ j=0;
+ n=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k2,k2); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ }
+ }
+ PrintStatusEnd();
+ if(k2!=dim2){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ReadEEErr],dim2,k2); //"Error reading EEPROM area, requested %d bytes, read %d\r\n"
+ }
+ else PrintMessage(strings[S_Compl]); //"completed\r\n"
+ }
+//****************** exit program mode ********************
+ bufferU[j++]=CLOCK_GEN;
+ bufferU[j++]=0xFF;
+ bufferU[j++]=SPI_WRITE;
+ bufferU[j++]=1;
+ bufferU[j++]=0;
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ unsigned int stop=GetTickCount();
+ PrintStatusClear();
+//****************** visualize ********************
+ PrintMessage(strings[S_CodeMem]); //"\r\nProgram memory\r\n"
+ DisplayCODEAVR(dim);
+ if(dim2){
+ DisplayEE(); //visualize EE
+ }
+ sprintf(str,strings[S_End],(stop-start)/1000.0); //"\r\nEnd (%.2f s)\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+}
+
+// function 18F ATtiny1x ATtiny84
+// SCI (I) RC6 PB3 PB0
+// SII (I) RB0 PB1 PA5
+// SDI (I) RC7 PB0 PA6
+// SDO (O) RB1 PB2 PA4
+#define SDI 0x10
+#define SII 0x1
+#define SDO 0x2
+#define SCI 0x8
+/// read ATMEL AVR using HV serial programming
+/// dim=FLASH size in bytes, dim2=EEPROM size
+/// options: LOCK,FUSE,FUSE_H,FUSE_X,CAL
+void ReadAT_HV(int dim, int dim2, int options)
+{
+ int k=0,z=0,i,j;
+ BYTE signature[]={0,0,0};
+ if(FWVersion<0x900){
+ PrintMessage1(strings[S_FWver2old],"0.9.0"); //"This firmware is too old. Version %s is required\r\n"
+ return;
+ }
+ if(dim>0x20000||dim<0){
+ PrintMessage(strings[S_CodeLim]); //"Code size out of limits\r\n"
+ return;
+ }
+ if(dim2>0x800||dim2<0){
+ PrintMessage(strings[S_EELim]); //"EEPROM size out of limits\r\n"
+ return;
+ }
+ if(saveLog){
+ OpenLogFile(); //"Log.txt"
+ fprintf(logfile,"ReadAT_HV(0x%X,0x%X,0x%X)\n",dim,dim2,options);
+ }
+ size=dim;
+ sizeEE=dim2;
+ if(memCODE) free(memCODE);
+ memCODE=(unsigned char*)malloc(dim); //CODE
+ if(memEE) free(memEE);
+ memEE=(unsigned char*)malloc(dim2); //EEPROM
+ for(j=0;j<size;j++) memCODE[j]=0xFF;
+ for(j=0;j<sizeEE;j++) memEE[j]=0xFF;
+ if(!StartHVReg(12)){
+ PrintMessage(strings[S_HVregErr]); //"HV regulator error\r\n"
+ return;
+ }
+ unsigned int start=GetTickCount();
+ j=0;
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x0;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=SET_PORT_DIR;
+ bufferU[j++]=0xFC;
+ bufferU[j++]=0x7;
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0;
+ bufferU[j++]=SCI;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0;
+ bufferU[j++]=SCI;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0;
+ bufferU[j++]=SCI;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0;
+ bufferU[j++]=SCI;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0;
+ bufferU[j++]=SCI;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0;
+ bufferU[j++]=SCI;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=EN_VPP_VCC; //VDD + VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=SET_PORT_DIR; //RELEASE SDO
+ bufferU[j++]=0xFE;
+ bufferU[j++]=0x7;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ j=0;
+ bufferU[j++]=AT_HV_RTX; //Read signature bytes
+ bufferU[j++]=4;
+ bufferU[j++]=0x4C;
+ bufferU[j++]=0x08;
+ bufferU[j++]=0x0C;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x68;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x6C;
+ bufferU[j++]=0x00;
+ bufferU[j++]=AT_HV_RTX; //Read signature bytes
+ bufferU[j++]=4;
+ bufferU[j++]=0x4C;
+ bufferU[j++]=0x08;
+ bufferU[j++]=0x0C;
+ bufferU[j++]=0x01;
+ bufferU[j++]=0x68;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x6C;
+ bufferU[j++]=0x00;
+ bufferU[j++]=AT_HV_RTX; //Read signature bytes
+ bufferU[j++]=4;
+ bufferU[j++]=0x4C;
+ bufferU[j++]=0x08;
+ bufferU[j++]=0x0C;
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x68;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x6C;
+ bufferU[j++]=0x00;
+ if(options&LOCK){ //LOCK byte
+ bufferU[j++]=AT_HV_RTX;
+ bufferU[j++]=3;
+ bufferU[j++]=0x4C;
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x78;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x7C;
+ bufferU[j++]=0x00;
+ }
+ if(options&FUSE){ //FUSE byte
+ bufferU[j++]=AT_HV_RTX;
+ bufferU[j++]=3;
+ bufferU[j++]=0x4C;
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x68;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x6C;
+ bufferU[j++]=0x00;
+ }
+ if(options&FUSE_H){ //FUSE high byte
+ bufferU[j++]=AT_HV_RTX;
+ bufferU[j++]=3;
+ bufferU[j++]=0x4C;
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x7A;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x7E;
+ bufferU[j++]=0x00;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ for(z=0;z<DIMBUF-1&&bufferI[z]!=AT_HV_RTX;z++);
+ signature[0]=bufferI[z+1];
+ for(z+=2;z<DIMBUF-1&&bufferI[z]!=AT_HV_RTX;z++);
+ signature[1]=bufferI[z+1];
+ for(z+=2;z<DIMBUF-1&&bufferI[z]!=AT_HV_RTX;z++);
+ signature[2]=bufferI[z+1];
+ PrintMessage3("CHIP ID:%02X%02X%02X\r\n",signature[0],signature[1],signature[2]);
+ AtmelID(signature);
+ if(options&LOCK){ //LOCK byte
+ for(z+=2;z<DIMBUF-1&&bufferI[z]!=AT_HV_RTX;z++);
+ PrintMessage1("LOCK byte:\t 0x%02X\r\n",bufferI[z+1]);
+ }
+ if(options&FUSE){ //FUSE byte
+ for(z+=2;z<DIMBUF-1&&bufferI[z]!=AT_HV_RTX;z++);
+ PrintMessage1("FUSE byte:\t 0x%02X\r\n",bufferI[z+1]);
+ }
+ if(options&FUSE_H){ //FUSE high byte
+ for(z+=2;z<DIMBUF-1&&bufferI[z]!=AT_HV_RTX;z++);
+ PrintMessage1("FUSE HIGH byte:\t 0x%02X\r\n",bufferI[z+1]);
+ }
+ if(options&FUSE_X){ //extended FUSE byte
+ bufferU[j++]=AT_HV_RTX;
+ bufferU[j++]=3;
+ bufferU[j++]=0x4C;
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x6A;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x6E;
+ bufferU[j++]=0x00;
+ }
+ if(options&CAL){ //calibration byte
+ bufferU[j++]=AT_HV_RTX;
+ bufferU[j++]=4;
+ bufferU[j++]=0x4C;
+ bufferU[j++]=0x08;
+ bufferU[j++]=0x0C;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x78;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x7C;
+ bufferU[j++]=0x00;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ j=0;
+ PacketIO(2);
+ z=0;
+ if(options&FUSE_X){ //extended FUSE byte
+ for(;z<DIMBUF-1&&bufferI[z]!=AT_HV_RTX;z++);
+ PrintMessage1("Extended FUSE byte: 0x%02X\r\n",bufferI[z+1]);
+ z+=2;
+ }
+ if(options&CAL){ //calibration byte
+ for(;z<DIMBUF-1&&bufferI[z]!=AT_HV_RTX;z++);
+ PrintMessage1("Calibration byte: 0x%02X\r\n",bufferI[z+1]);
+ }
+//****************** read code ********************
+ if(saveLog)fprintf(logfile,"READ CODE\n");
+ PrintMessage(strings[S_CodeReading1]); //read code ...
+ PrintStatusSetup();
+ j=0;
+ bufferU[j++]=AT_HV_RTX; //Read FLASH
+ bufferU[j++]=1;
+ bufferU[j++]=0x4C;
+ bufferU[j++]=0x02;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ for(i=0;i<dim;){
+ if((i&511)==0){ //change high address after 256 words
+ bufferU[j++]=AT_HV_RTX;
+ bufferU[j++]=1;
+ bufferU[j++]=0x1C;
+ bufferU[j++]=i>>9;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ }
+ bufferU[j++]=AT_HV_RTX;
+ bufferU[j++]=3;
+ bufferU[j++]=0x0C;
+ bufferU[j++]=(i>>1)&0xFF;
+ bufferU[j++]=0x68;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x6C;
+ bufferU[j++]=0x00;
+ bufferU[j++]=AT_HV_RTX;
+ bufferU[j++]=2;
+ bufferU[j++]=0x78;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x7C;
+ bufferU[j++]=0x00;
+ i+=2;
+ if(j>DIMBUF-14||i>=dim-2){
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ for(z=0;z<DIMBUF-1;z++){
+ if(bufferI[z]==AT_HV_RTX){
+ memCODE[k++]=bufferI[z+1];
+ z+=1;
+ }
+ }
+ PrintStatus(strings[S_CodeReading],i*100/(dim+dim2),i); //"Read: %d%%, addr. %03X"
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k,k); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ }
+ }
+ PrintStatusEnd();
+ if(k!=dim){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ReadCodeErr],dim,k); //"Error reading code area, requested %d words, read %d\r\n"
+ }
+ else PrintMessage(strings[S_Compl]);
+//****************** read eeprom ********************
+ if(dim2){
+ if(saveLog)fprintf(logfile,"READ EEPROM\n");
+ PrintMessage(strings[S_ReadEE]); //read EE ...
+ PrintStatusSetup();
+ j=0;
+ k=0;
+ bufferU[j++]=AT_HV_RTX; //Read EEPROM
+ bufferU[j++]=1;
+ bufferU[j++]=0x4C;
+ bufferU[j++]=0x03;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ for(i=0;i<dim2;i++){
+ if((i&255)==0){
+ bufferU[j++]=AT_HV_RTX;
+ bufferU[j++]=1;
+ bufferU[j++]=0x1C;
+ bufferU[j++]=i>>8;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ }
+ bufferU[j++]=AT_HV_RTX;
+ bufferU[j++]=3;
+ bufferU[j++]=0x0C;
+ bufferU[j++]=i&0xFF;
+ bufferU[j++]=0x68;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x6C;
+ bufferU[j++]=0x00;
+ if(j>DIMBUF-8||i>=dim2-2){
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ for(z=0;z<DIMBUF-1;z++){
+ if(bufferI[z]==AT_HV_RTX){
+ memEE[k++]=bufferI[z+1];
+ z+=1;
+ }
+ }
+ PrintStatus(strings[S_CodeReading],i*100/(dim+dim2),i); //"Read: %d%%, addr. %03X"
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k,k); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ }
+ }
+ PrintStatusEnd();
+ if(k!=dim2){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ReadEEErr],dim2,k); //"Error reading EEPROM area, requested %d bytes, read %d\r\n"
+ }
+ else PrintMessage(strings[S_Compl]);
+ }
+//****************** exit program mode ********************
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=SET_PORT_DIR; //All input
+ bufferU[j++]=0xFF;
+ bufferU[j++]=0xFF;
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ unsigned int stop=GetTickCount();
+ PrintStatusClear();
+//****************** visualize ********************
+ PrintMessage(strings[S_CodeMem]); //"\r\nProgram memory\r\n"
+ DisplayCODEAVR(dim);
+ if(dim2){
+ DisplayEE(); //visualize EE
+ }
+ sprintf(str,strings[S_End],(stop-start)/1000.0); //"\r\nEnd (%.2f s)\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+}
+
+void WriteAT(int dim, int dim2, int dummy1, int dummy2)
+// write ATMEL micro
+// dim=FLASH size in bytes, dim2=EEPROM size
+{
+ int k=0,z=0,i,j;
+ int err=0;//,Rtry=0,maxTry=0;
+ double Tbyte;
+ BYTE signature[]={0,0,0};
+ if(dim>0x8000||dim<0){
+ PrintMessage(strings[S_CodeLim]); //"Code size out of limits\r\n"
+ return;
+ }
+ if(dim2>0x800||dim2<0){
+ PrintMessage(strings[S_EELim]); //"EEPROM size out of limits\r\n"
+ return;
+ }
+ if(saveLog){
+ OpenLogFile(); //"Log.txt"
+ fprintf(logfile,"WriteAT(0x%X,0x%X)\n",dim,dim2);
+ }
+ if(dim>size) dim=size;
+ if(dim2>sizeEE) dim2=sizeEE;
+ if(dim<1){
+ PrintMessage(strings[S_NoCode]); //"Data area is empty\r\n"
+ return;
+ }
+ unsigned int start=GetTickCount();
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2000>>8;
+ bufferU[j++]=2000&0xff;
+ bufferU[j++]=VREG_DIS; //Disable HV reg
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ Tbyte=SyncSPI();
+ if(Tbyte==0){
+ if(saveLog) CloseLogFile();
+ return;
+ }
+ j=0;
+
+/* bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=20000>>8;
+ bufferU[j++]=20000&0xff;
+ bufferU[j++]=VREG_DIS; //Disable HV reg
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x0;
+ bufferU[j++]=SPI_INIT;
+ bufferU[j++]=1;
+ bufferU[j++]=CLOCK_GEN;
+ bufferU[j++]=5;
+ bufferU[j++]=CLOCK_GEN;
+ bufferU[j++]=0xFF;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=WAIT_T3; //20ms
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=WAIT_T3; //20ms
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ writeP();
+ msDelay(50);
+ readP();
+ if(saveLog)WriteLogIO();
+ for(i=0;i<32;i++){
+ j=0;
+ bufferU[j++]=CLOCK_GEN;
+ bufferU[j++]=0xFF;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0;
+ bufferU[j++]=RST;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=CLOCK_GEN;
+ bufferU[j++]=5;
+ bufferU[j++]=WAIT_T3; //20ms
+ bufferU[j++]=SPI_WRITE; //Programming enable
+ bufferU[j++]=2;
+ bufferU[j++]=0xAC;
+ bufferU[j++]=0x53;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=2;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ writeP();
+ msDelay(25);
+ readP();
+ if(saveLog)WriteLogIO();
+ for(z=0;z<DIMBUF-2&&bufferI[z]!=SPI_READ;z++);
+ //PrintMessage("i=%d z=%d rx:%02X%02X\r\n",i,z,bufferI[z+2],bufferI[z+3]);
+ if(bufferI[z+2]==0x53) i=32;
+ }
+ if(i<33){
+ j=0;
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x0;
+ bufferU[j++]=SPI_INIT;
+ bufferU[j++]=0xFF;
+ bufferU[j++]=CLOCK_GEN;
+ bufferU[j++]=0xFF;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ writeP();
+ msDelay(1);
+ readP();
+ if(saveLog)WriteLogIO();
+ PrintMessage(strings[S_SyncErr]); //"Synchronization error\r\n"
+ if(saveLog) CloseLogFile();
+ return;
+ }
+ j=0;*/
+ bufferU[j++]=SPI_WRITE; //Read signature bytes
+ bufferU[j++]=3;
+ bufferU[j++]=0x30;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=1;
+ bufferU[j++]=SPI_WRITE; //Read signature bytes
+ bufferU[j++]=3;
+ bufferU[j++]=0x30;
+ bufferU[j++]=0;
+ bufferU[j++]=1;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=1;
+ bufferU[j++]=SPI_WRITE; //Read signature bytes
+ bufferU[j++]=3;
+ bufferU[j++]=0x30;
+ bufferU[j++]=0;
+ bufferU[j++]=2;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=1;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(1+3*4*Tbyte);
+ for(z=0;z<DIMBUF-2&&bufferI[z]!=SPI_READ;z++);
+ signature[0]=bufferI[z+2];
+ for(z+=3;z<DIMBUF-2&&bufferI[z]!=SPI_READ;z++);
+ signature[1]=bufferI[z+2];
+ for(z+=3;z<DIMBUF-2&&bufferI[z]!=SPI_READ;z++);
+ signature[2]=bufferI[z+2];
+ PrintMessage3("CHIP ID:%02X%02X%02X\r\n",signature[0],signature[1],signature[2]);
+ AtmelID(signature);
+//****************** erase memory ********************
+ PrintMessage(strings[S_StartErase]); //"Erase ... "
+ if(saveLog) fprintf(logfile,"%s\n",strings[S_StartErase]);
+ j=0;
+ bufferU[j++]=SPI_WRITE; //Chip erase
+ bufferU[j++]=4;
+ bufferU[j++]=0xAC;
+ bufferU[j++]=0x80;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2000>>8;
+ bufferU[j++]=2000&0xff;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(1+4*Tbyte);
+ msDelay(25); //Erase time
+ PrintMessage(strings[S_Compl]); //"completed\r\n"
+//****************** write code ********************
+ PrintMessage(strings[S_StartCodeProg]); //"Write code ... "
+ if(saveLog) fprintf(logfile,"%s\n",strings[S_StartCodeProg]);
+ PrintStatusSetup();
+ for(i=0,j=0;i<dim;i++){
+ if(memCODE[i]!=0xFF){
+ bufferU[j++]=SPI_WRITE; //Write program memory
+ bufferU[j++]=4;
+ bufferU[j++]=0x40+(i&1?8:0);
+ bufferU[j++]=i>>9;
+ bufferU[j++]=i>>1;
+ bufferU[j++]=memCODE[i];
+ bufferU[j++]=WAIT_T3; //6ms
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=SPI_WRITE; //Read program memory
+ bufferU[j++]=3;
+ bufferU[j++]=0x20+(i&1?8:0);
+ bufferU[j++]=i>>9;
+ bufferU[j++]=i>>1;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=1;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ j=0;
+ PacketIO(7+2*4*Tbyte);
+ PrintStatus(strings[S_CodeWriting],i*100/dim,i); //"Write: %d%%, addr. %03X"
+ for(z=0;z<DIMBUF-2&&bufferI[z]!=SPI_READ;z++);
+ if(z==DIMBUF-2||memCODE[i]!=bufferI[z+2]){
+ err++;
+ }
+ if(max_err&&err>max_err){
+ PrintMessage1(strings[S_MaxErr],err); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ PrintMessage(strings[S_IntW]); //"Write interrupted"
+ i=dim;
+ }
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,err); //"i=%d, k=%d, err=%d\n"
+ }
+ }
+ }
+ PrintStatusEnd();
+ PrintMessage1(strings[S_ComplErr],err); //"completed, %d errors\r\n"
+//****************** write eeprom ********************
+ if(dim2){
+ PrintMessage(strings[S_EEAreaW]); //"Write EEPROM ... "
+ if(saveLog) fprintf(logfile,"%s\n",strings[S_EEAreaW]);
+ PrintStatusSetup();
+ int errEE=0;
+ for(i=0,j=0;i<dim2;i++){
+ if(memEE[i]!=0xFF){
+ bufferU[j++]=SPI_WRITE; //Write EEPROM memory
+ bufferU[j++]=4;
+ bufferU[j++]=0xC0;
+ bufferU[j++]=i>>8;
+ bufferU[j++]=i;
+ bufferU[j++]=memEE[i];
+ bufferU[j++]=WAIT_T3; //6ms
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=SPI_WRITE; //Read EEPROM memory
+ bufferU[j++]=3;
+ bufferU[j++]=0xA0;
+ bufferU[j++]=i>>8;
+ bufferU[j++]=i;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=1;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ j=0;
+ PacketIO(7+2*4*Tbyte);
+ PrintStatus(strings[S_CodeWriting],i*100/dim2,i); //"Write: %d%%, addr. %03X"
+ for(z=0;z<DIMBUF-2&&bufferI[z]!=SPI_READ;z++);
+ if(z==DIMBUF-2||memEE[i]!=bufferI[z+2]){
+ errEE++;
+ }
+ if(max_err&&err+errEE>max_err){
+ PrintMessage1(strings[S_MaxErr],err+errEE); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ PrintMessage(strings[S_IntW]); //"Write interrupted"
+ i=dim2;
+ }
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,errEE); //"i=%d, k=%d, err=%d\n"
+ }
+ }
+ }
+ PrintStatusEnd();
+ PrintMessage1(strings[S_ComplErr],errEE); //"completed, %d errors\r\n"
+ err+=errEE;
+ }
+// if(maxTry) PrintMessage1(strings[S_MaxRetry],maxTry); //"Max retries in writing: %d\r\n"
+//****************** write FUSE ********************
+ if(AVRlock<0x100){
+ PrintMessage(strings[S_FuseAreaW]); //"Write Fuse ... "
+ if(saveLog) fprintf(logfile,"%s\n",strings[S_FuseAreaW]);
+ bufferU[j++]=SPI_WRITE; //Write lock
+ bufferU[j++]=4;
+ bufferU[j++]=0xAC;
+ bufferU[j++]=0xF9+(AVRlock&0x06);
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=WAIT_T3; //9ms
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ j=0;
+ PacketIO(3+4*Tbyte);
+ msDelay(15);
+ PrintMessage(strings[S_Compl]); //"completed\r\n"
+ }
+//****************** exit program mode ********************
+ bufferU[j++]=CLOCK_GEN;
+ bufferU[j++]=0xFF;
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ unsigned int stop=GetTickCount();
+ sprintf(str,strings[S_EndErr],(stop-start)/1000.0,err,err!=1?strings[S_ErrPlur]:strings[S_ErrSing]); //"\r\nEnd (%.2f s) %d %s\r\n\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+ PrintStatusClear();
+}
+
+
+void WriteATmega(int dim, int dim2, int page, int options)
+// write ATMEL micro
+// dim=FLASH size in bytes, dim2=EEPROM, page=FLASH page size in bytes
+{
+ int k=0,z=0,i,j;
+ double Tbyte; //byte delay in ms
+ int err=0,Rtry=0,maxTry=0;
+ BYTE signature[]={0,0,0};
+ if(dim>0x20000||dim<0){
+ PrintMessage(strings[S_CodeLim]); //"Code size out of limits\r\n"
+ return;
+ }
+ if(dim2>0x1000||dim2<0){
+ PrintMessage(strings[S_EELim]); //"EEPROM size out of limits\r\n"
+ return;
+ }
+ if(saveLog){
+ OpenLogFile(); //"Log.txt"
+ fprintf(logfile,"WriteATmega(0x%X,0x%X,0x%X,0x%X)\n",dim,dim2,page,options);
+ }
+ if(dim>size) dim=size;
+ else{
+ size=dim;
+ memCODE=(unsigned char*)realloc(memCODE,dim);
+ }
+ if(size%(page*2)){ //grow to an integer number of pages
+ j=size;
+ dim=(j/(page*2)+1)*page*2;
+ memCODE=(unsigned char*)realloc(memCODE,dim);
+ for(;j<dim;j++) memCODE[j]=0xFF;
+ }
+ if(dim2>sizeEE) dim2=sizeEE;
+ if(dim<1){
+ PrintMessage(strings[S_NoCode]); //"Data area is empty\r\n"
+ return;
+ }
+ unsigned int start=GetTickCount();
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2000>>8;
+ bufferU[j++]=2000&0xff;
+ bufferU[j++]=VREG_DIS; //Disable HV reg
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ Tbyte=SyncSPI();
+ if(Tbyte==0){
+ if(saveLog) CloseLogFile();
+ return;
+ }
+ j=0;
+ bufferU[j++]=SPI_WRITE; //Read signature bytes
+ bufferU[j++]=3;
+ bufferU[j++]=0x30;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=1;
+ bufferU[j++]=SPI_WRITE; //Read signature bytes
+ bufferU[j++]=3;
+ bufferU[j++]=0x30;
+ bufferU[j++]=0;
+ bufferU[j++]=1;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=1;
+ bufferU[j++]=SPI_WRITE; //Read signature bytes
+ bufferU[j++]=3;
+ bufferU[j++]=0x30;
+ bufferU[j++]=0;
+ bufferU[j++]=2;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=1;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(1.5+3*4.5*Tbyte);
+ if(saveLog)WriteLogIO();
+ for(z=0;z<DIMBUF-2&&bufferI[z]!=SPI_READ;z++);
+ signature[0]=bufferI[z+2];
+ for(z+=3;z<DIMBUF-2&&bufferI[z]!=SPI_READ;z++);
+ signature[1]=bufferI[z+2];
+ for(z+=3;z<DIMBUF-2&&bufferI[z]!=SPI_READ;z++);
+ signature[2]=bufferI[z+2];
+ PrintMessage3("CHIP ID:%02X%02X%02X\r\n",signature[0],signature[1],signature[2]);
+ AtmelID(signature);
+//****************** erase memory ********************
+ PrintMessage(strings[S_StartErase]); //"Erase ... "
+ if(saveLog) fprintf(logfile,"%s\n",strings[S_StartErase]);
+ j=0;
+ bufferU[j++]=SPI_WRITE; //Chip erase
+ bufferU[j++]=4;
+ bufferU[j++]=0xAC;
+ bufferU[j++]=0x80;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=5000>>8;
+ bufferU[j++]=5000&0xff;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(1+4*Tbyte);
+ msDelay(15); //erase time 9ms min
+ PrintMessage(strings[S_Compl]); //"completed\r\n"
+//****************** write code ********************
+ PrintMessage(strings[S_StartCodeProg]); //"Write code ... "
+ if(saveLog) fprintf(logfile,"%s\n",strings[S_StartCodeProg]);
+ PrintStatusSetup();
+ int w=0,v,c;
+ for(i=0;i<dim;i+=page*2){
+ for(z=i,v=0;z<i+page*2;z++) if(memCODE[z]<0xFF)v=1;
+ if(v){
+ for(k=0,j=0,v=0;k<page;k+=w){
+ w=(page-k)<(DIMBUF-6)/2?(page-k):(DIMBUF-6)/2;
+ bufferU[j++]=AT_LOAD_DATA;
+ bufferU[j++]=w;
+ bufferU[j++]=k>>8;
+ bufferU[j++]=k;
+ for(z=0;z<w*2;z++) bufferU[j++]=memCODE[i+k*2+z];
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ j=0;
+ PacketIO(1.5+w*9*Tbyte);
+ }
+ bufferU[j++]=SPI_WRITE; //Write program memory page
+ bufferU[j++]=4;
+ bufferU[j++]=0x4C;
+ bufferU[j++]=i>>9;
+ bufferU[j++]=i>>1;
+ bufferU[j++]=0;
+ bufferU[j++]=WAIT_T3; //5ms
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ j=0;
+ PacketIO(6+4*Tbyte);
+ //msDelay(5);
+ PrintStatus(strings[S_CodeWriting],i*100/dim,i); //"Write: %d%%, addr. %03X"
+ if(RWstop) i=dim;
+ //write verification
+ c=(DIMBUF-5)/2;
+ for(k=0,j=0;k<page;k+=c){
+ for(Rtry=0;Rtry<5;Rtry++){ //Try to read a few times
+ bufferU[j++]=AT_READ_DATA;
+ bufferU[j++]=k<(page-c)?c:page-k;
+ bufferU[j++]=(i+k*2)>>9;
+ bufferU[j++]=(i+k*2)>>1;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(1.5+240*Tbyte);
+ if(bufferI[0]==AT_READ_DATA){ //Fixed reference!!
+ for(w=0,z=2;z<bufferI[1]*2+2&&z<DIMBUF;z++){
+ if(memCODE[i+k*2+w]!=bufferI[z]){
+ if(Rtry<4) z=DIMBUF;
+ else err++;
+ }
+ w++;
+ }
+ if(z<DIMBUF) Rtry=100;
+ }
+ j=0;
+ }
+ }
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,w,w,err); //"i=%d, k=%d, err=%d\n"
+ }
+ if(max_err&&err>max_err){
+ PrintMessage1(strings[S_MaxErr],err); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ PrintMessage(strings[S_IntW]); //"Write interrupted"
+ i=dim;
+ }
+ }
+ }
+ PrintStatusEnd();
+ PrintMessage1(strings[S_ComplErr],err); //"completed, %d errors\r\n"
+//****************** write eeprom ********************
+ if(dim2){
+ PrintMessage(strings[S_EEAreaW]); //"Write EEPROM ... "
+ if(saveLog) fprintf(logfile,"%s\n",strings[S_EEAreaW]);
+ PrintStatusSetup();
+ int errEE=0;
+ for(i=0,j=0;i<dim2;i++){
+ if(memEE[i]!=0xFF){
+ bufferU[j++]=SPI_WRITE; //Write EEPROM memory
+ bufferU[j++]=4;
+ bufferU[j++]=0xC0;
+ bufferU[j++]=i>>8;
+ bufferU[j++]=i;
+ bufferU[j++]=memEE[i];
+ bufferU[j++]=WAIT_T3; //5ms
+ bufferU[j++]=WAIT_T3; //5ms
+ bufferU[j++]=SPI_WRITE; //Read EEPROM memory
+ bufferU[j++]=3;
+ bufferU[j++]=0xA0;
+ bufferU[j++]=i>>8;
+ bufferU[j++]=i;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=1;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ j=0;
+ PacketIO(11+8.5*Tbyte);
+ PrintStatus(strings[S_CodeWriting],i*100/dim2,i); //"Write: %d%%, addr. %03X"
+ for(z=0;z<DIMBUF-2&&bufferI[z]!=SPI_READ;z++);
+ if(z==DIMBUF-2||memEE[i]!=bufferI[z+2]){
+ if(Rtry<4){
+ Rtry++;
+ if (Rtry>maxTry) maxTry=Rtry;
+ i--;
+ }
+ else{
+ errEE++;
+ Rtry=0;
+ }
+ }
+ if(max_err&&err+errEE>max_err){
+ PrintMessage1(strings[S_MaxErr],err+errEE); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ PrintMessage(strings[S_IntW]); //"Write interrupted"
+ i=dim2;
+ }
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,errEE); //"i=%d, k=%d, err=%d\n"
+ }
+ }
+ }
+ PrintStatusEnd();
+ PrintMessage1(strings[S_ComplErr],errEE); //"completed, %d errors\r\n"
+ err+=errEE;
+ }
+//****************** write FUSE ********************
+ int err_f=0;
+ if(AVRlock<0x100||AVRfuse<0x100||AVRfuse_h<0x100||AVRfuse_x<0x100){
+ PrintMessage(strings[S_FuseAreaW]); //"Write Fuse ... "
+ if(saveLog) fprintf(logfile,"%s\n",strings[S_FuseAreaW]);
+ }
+ if(AVRfuse<0x100){
+ bufferU[j++]=SPI_WRITE; //Write fuse
+ bufferU[j++]=4;
+ bufferU[j++]=0xAC;
+ bufferU[j++]=0xA0;
+ bufferU[j++]=0;
+ bufferU[j++]=AVRfuse;
+ bufferU[j++]=WAIT_T3; //5ms
+ bufferU[j++]=SPI_WRITE;
+ bufferU[j++]=3;
+ bufferU[j++]=0x50;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=1;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ j=0;
+ PacketIO(6+8.5*Tbyte);
+ for(z=0;z<DIMBUF-2&&bufferI[z]!=SPI_READ;z++);
+ if(z==DIMBUF-2||AVRfuse!=bufferI[z+2]) err_f++;
+ }
+ if(AVRfuse_h<0x100){
+ bufferU[j++]=SPI_WRITE; //Write fuse_h
+ bufferU[j++]=4;
+ bufferU[j++]=0xAC;
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0;
+ bufferU[j++]=AVRfuse_h;
+ bufferU[j++]=WAIT_T3; //5ms
+ bufferU[j++]=SPI_WRITE;
+ bufferU[j++]=3;
+ bufferU[j++]=0x58;
+ bufferU[j++]=8;
+ bufferU[j++]=0;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=1;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ j=0;
+ PacketIO(6+8.5*Tbyte);
+ for(z=0;z<DIMBUF-2&&bufferI[z]!=SPI_READ;z++);
+ if(z==DIMBUF-2||AVRfuse_h!=bufferI[z+2]) err_f++;
+ }
+ if(AVRfuse_x<0x100){
+ bufferU[j++]=SPI_WRITE; //Write ext fuse
+ bufferU[j++]=4;
+ bufferU[j++]=0xAC;
+ bufferU[j++]=0xA4;
+ bufferU[j++]=0;
+ bufferU[j++]=AVRfuse_x;
+ bufferU[j++]=WAIT_T3; //5ms
+ bufferU[j++]=SPI_WRITE;
+ bufferU[j++]=3;
+ bufferU[j++]=0x50;
+ bufferU[j++]=8;
+ bufferU[j++]=0;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=1;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ j=0;
+ PacketIO(6+8.5*Tbyte);
+ for(z=0;z<DIMBUF-2&&bufferI[z]!=SPI_READ;z++);
+ if(z==DIMBUF-2||AVRfuse_x!=bufferI[z+2]) err_f++;
+ }
+ if(AVRlock<0x100){
+ bufferU[j++]=SPI_WRITE; //Write lock
+ bufferU[j++]=4;
+ bufferU[j++]=0xAC;
+ bufferU[j++]=0xE0;
+ bufferU[j++]=0;
+ bufferU[j++]=AVRlock;
+ bufferU[j++]=WAIT_T3; //5ms
+ bufferU[j++]=SPI_WRITE;
+ bufferU[j++]=3;
+ bufferU[j++]=0x58;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=1;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ j=0;
+ PacketIO(6+8.5*Tbyte);
+ for(z=0;z<DIMBUF-2&&bufferI[z]!=SPI_READ;z++);
+ if(z==DIMBUF-2||AVRlock!=bufferI[z+2]) err_f++;
+ }
+ err+=err_f;
+ if(AVRlock<0x100||AVRfuse<0x100||AVRfuse_h<0x100||AVRfuse_x<0x100){
+ PrintMessage1(strings[S_ComplErr],err_f); //"completed, %d errors\r\n"
+ }
+// if(maxTry) PrintMessage(strings[S_MaxRetry],maxTry); //"Max retries in writing: %d\r\n"
+//****************** exit program mode ********************
+ bufferU[j++]=CLOCK_GEN;
+ bufferU[j++]=0xFF;
+ bufferU[j++]=SPI_WRITE;
+ bufferU[j++]=1;
+ bufferU[j++]=0;
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ unsigned int stop=GetTickCount();
+ sprintf(str,strings[S_EndErr],(stop-start)/1000.0,err,err!=1?strings[S_ErrPlur]:strings[S_ErrSing]); //"\r\nEnd (%.2f s) %d %s\r\n\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+ PrintStatusClear();
+}
+
+/// Write ATMEL AVR using HV serial programming
+/// dim=FLASH size in bytes, dim2=EEPROM, page=FLASH page size in words (0 if page write not supported)
+/// options: not used
+void WriteAT_HV(int dim, int dim2, int page, int options)
+{
+ int k=0,z=0,i,j,t,sdo,err=0;
+ BYTE signature[]={0,0,0};
+ if(FWVersion<0x900){
+ PrintMessage1(strings[S_FWver2old],"0.9.0"); //"This firmware is too old. Version %s is required\r\n"
+ return;
+ }
+ if(dim>0x10000||dim<0){
+ PrintMessage(strings[S_CodeLim]); //"Code size out of limits\r\n"
+ return;
+ }
+ if(dim2>0x800||dim2<0){
+ PrintMessage(strings[S_EELim]); //"EEPROM size out of limits\r\n"
+ return;
+ }
+ if(saveLog){
+ OpenLogFile(); //"Log.txt"
+ fprintf(logfile,"WriteAT_HV(0x%X,0x%X,0x%X,0x%X)\n",dim,dim2,page,options);
+ }
+ if(dim>size) dim=size;
+ else{
+ size=dim;
+ memCODE=(unsigned char*)realloc(memCODE,dim);
+ }
+ if(page&&(size%(page*2))){ //grow to an integer number of pages
+ j=size;
+ dim=(j/(page*2)+1)*page*2;
+ memCODE=(unsigned char*)realloc(memCODE,dim);
+ for(;j<dim;j++) memCODE[j]=0xFF;
+ }
+ if(dim2>sizeEE) dim2=sizeEE;
+ if(dim<1){
+ PrintMessage(strings[S_NoCode]); //"Data area is empty\r\n"
+ return;
+ }
+ if(!StartHVReg(12)){
+ PrintMessage(strings[S_HVregErr]); //"HV regulator error\r\n"
+ return;
+ }
+ unsigned int start=GetTickCount();
+ j=0;
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x0;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=SET_PORT_DIR;
+ bufferU[j++]=0xFC;
+ bufferU[j++]=0x7;
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0;
+ bufferU[j++]=SCI;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0;
+ bufferU[j++]=SCI;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0;
+ bufferU[j++]=SCI;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0;
+ bufferU[j++]=SCI;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0;
+ bufferU[j++]=SCI;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0;
+ bufferU[j++]=SCI;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=EN_VPP_VCC; //VDD + VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=SET_PORT_DIR; //RELEASE SDO
+ bufferU[j++]=0xFE;
+ bufferU[j++]=0x7;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ j=0;
+ bufferU[j++]=AT_HV_RTX; //Read signature bytes
+ bufferU[j++]=4;
+ bufferU[j++]=0x4C;
+ bufferU[j++]=0x08;
+ bufferU[j++]=0x0C;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x68;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x6C;
+ bufferU[j++]=0x00;
+ bufferU[j++]=AT_HV_RTX; //Read signature bytes
+ bufferU[j++]=4;
+ bufferU[j++]=0x4C;
+ bufferU[j++]=0x08;
+ bufferU[j++]=0x0C;
+ bufferU[j++]=0x01;
+ bufferU[j++]=0x68;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x6C;
+ bufferU[j++]=0x00;
+ bufferU[j++]=AT_HV_RTX; //Read signature bytes
+ bufferU[j++]=4;
+ bufferU[j++]=0x4C;
+ bufferU[j++]=0x08;
+ bufferU[j++]=0x0C;
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x68;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x6C;
+ bufferU[j++]=0x00;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(8);
+ for(z=0;z<DIMBUF-1&&bufferI[z]!=AT_HV_RTX;z++);
+ signature[0]=bufferI[z+1];
+ for(z+=2;z<DIMBUF-1&&bufferI[z]!=AT_HV_RTX;z++);
+ signature[1]=bufferI[z+1];
+ for(z+=2;z<DIMBUF-1&&bufferI[z]!=AT_HV_RTX;z++);
+ signature[2]=bufferI[z+1];
+ PrintMessage3("CHIP ID:%02X%02X%02X\r\n",signature[0],signature[1],signature[2]);
+ AtmelID(signature);
+//****************** erase memory ********************
+ if(saveLog)fprintf(logfile,"CHIP ERASE\n");
+ j=0;
+ bufferU[j++]=AT_HV_RTX; //Chip erase
+ bufferU[j++]=3;
+ bufferU[j++]=0x4C;
+ bufferU[j++]=0x80;
+ bufferU[j++]=0x64;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x6C;
+ bufferU[j++]=0x00;
+ bufferU[j++]=READ_B; //check SDO
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ bufferU[j++]=READ_B; //check SDO
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ for(t=0,sdo=0;t<20&&sdo==0;t++){
+ PacketIO(2);
+ for(z=0;z<DIMBUF-1&&bufferI[z]!=READ_B;z++);
+ sdo=bufferI[z+1]&2;
+ }
+ if(sdo==0&&saveLog) fprintf(logfile,"SDO=0\r\n");
+ PrintMessage(strings[S_Compl]); //"completed\r\n"
+//****************** write code ********************
+ PrintMessage(strings[S_StartCodeProg]); //"Write code ... "
+ PrintStatusSetup();
+ if(saveLog)fprintf(logfile,"WRITE CODE\n");
+ int currPage=-1;
+ j=0;
+ if(page==0){ //byte write
+ for(i=0,k=0;i<dim;i+=2){
+ if(memCODE[i]!=0xFF||memCODE[i+1]!=0xFF){
+ bufferU[j++]=AT_HV_RTX;
+ bufferU[j++]=6;
+ bufferU[j++]=0x4C; //Write FLASH
+ bufferU[j++]=0x10;
+ bufferU[j++]=0x1C;
+ bufferU[j++]=i>>9;
+ bufferU[j++]=0x0C;
+ bufferU[j++]=(i/2)&0xFF;
+ bufferU[j++]=0x2C;
+ bufferU[j++]=memCODE[i];
+ bufferU[j++]=0x64; //write data low
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x6C;
+ bufferU[j++]=0x00;
+ bufferU[j++]=READ_B; //check SDO
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k,k); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ bufferU[j++]=READ_B; //check SDO
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ j=0;
+ for(t=0,sdo=0;t<20&&sdo==0;t++){
+ PacketIO(2);
+ for(z=0;z<DIMBUF-1&&bufferI[z]!=READ_B;z++);
+ sdo=bufferI[z+1]&2;
+ }
+ if(saveLog&&sdo==0) fprintf(logfile,"SDO=0\r\n");
+ bufferU[j++]=AT_HV_RTX;
+ bufferU[j++]=3;
+ bufferU[j++]=0x3C;
+ bufferU[j++]=memCODE[i+1];
+ bufferU[j++]=0x74; //write data high
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x7C;
+ bufferU[j++]=0x00;
+ bufferU[j++]=READ_B; //check SDO
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k,k); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ bufferU[j++]=READ_B; //check SDO
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ j=0;
+ for(t=0,sdo=0;t<20&&sdo==0;t++){
+ PacketIO(2);
+ for(z=0;z<DIMBUF-1&&bufferI[z]!=READ_B;z++);
+ sdo=bufferI[z+1]&2;
+ }
+ if(saveLog&&sdo==0) fprintf(logfile,"SDO=0\r\n");
+ PrintStatus(strings[S_CodeWriting],i*100/dim,i); //"Write: %d%%, addr. %03X"
+ //write verification
+ bufferU[j++]=AT_HV_RTX; //Read FLASH
+ bufferU[j++]=3;
+ bufferU[j++]=0x4C;
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x68;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x6C;
+ bufferU[j++]=0x00;
+ bufferU[j++]=AT_HV_RTX;
+ bufferU[j++]=2;
+ bufferU[j++]=0x78;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x7C;
+ bufferU[j++]=0x00;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ k=i;
+ for(z=0;z<DIMBUF-1;z++){
+ if(bufferI[z]==AT_HV_RTX){
+ if(memCODE[k]!=bufferI[z+1]){
+ PrintMessage4(strings[S_CodeVError],k,k,memCODE[k],bufferI[z+1]); //"Error writing address %4X: written %02X, read %02X\r\n"
+ err++;
+ }
+ k++;
+ z++;
+ }
+ }
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,err); //"i=%d, k=%d, err=%d\n"
+ }
+ if(max_err&&err>max_err){
+ PrintMessage1(strings[S_MaxErr],err); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ PrintMessage(strings[S_IntW]); //"Write interrupted"
+ i=dim;
+ }
+ }
+ }
+ }
+ else{ //page write
+ for(i=0;i<dim;i+=page*2){ //page in words
+ for(k=0;k<page;k++){
+ if(memCODE[i+k*2]!=0xFF||memCODE[i+k*2+1]!=0xFF) k=page;
+ }
+ if(k>page){ //only pages with data!=0xFF
+ bufferU[j++]=AT_HV_RTX;
+ bufferU[j++]=1;
+ bufferU[j++]=0x4C; //Write FLASH
+ bufferU[j++]=0x10;
+ for(k=0;k<page;k++){
+ bufferU[j++]=AT_HV_RTX;
+ bufferU[j++]=5;
+ bufferU[j++]=0x0C;
+ bufferU[j++]=(i/2+k)&0xFF;
+ bufferU[j++]=0x2C;
+ bufferU[j++]=memCODE[i+k*2]; //data low
+ bufferU[j++]=0x3C;
+ bufferU[j++]=memCODE[i+k*2+1]; //data high
+ bufferU[j++]=0x7D;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x7C;
+ bufferU[j++]=0x00;
+ if(j>DIMBUF-13||k>=page||i>=dim-2){
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k,k); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ }
+ }
+ if((i>>9)!=currPage){ //change high address if changed
+ bufferU[j++]=AT_HV_RTX;
+ bufferU[j++]=1;
+ bufferU[j++]=0x1C;
+ bufferU[j++]=i>>9;
+ currPage=i>>9;
+ }
+ bufferU[j++]=AT_HV_RTX; //write page
+ bufferU[j++]=2;
+ bufferU[j++]=0x64;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x6C;
+ bufferU[j++]=0x00;
+ bufferU[j++]=READ_B; //check SDO
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k,k); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ bufferU[j++]=READ_B; //check SDO
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ for(t=0,sdo=0;t<20&&sdo==0;t++){
+ PacketIO(2);
+ for(z=0;z<DIMBUF-1&&bufferI[z]!=READ_B;z++);
+ sdo=bufferI[z+1]&2;
+ }
+ if(sdo==0&&saveLog) fprintf(logfile,"SDO=0\r\n");
+ PrintStatus(strings[S_CodeWriting],i*100/dim,i); //"Write: %d%%, addr. %03X"
+ j=0;
+ //write verification
+ int m=0;
+ for(k=0;k<page;k++){
+ if(k==0){
+ bufferU[j++]=AT_HV_RTX; //Read FLASH
+ bufferU[j++]=4;
+ bufferU[j++]=0x4C;
+ bufferU[j++]=0x02;
+ }
+ else{
+ bufferU[j++]=AT_HV_RTX;
+ bufferU[j++]=3;
+ }
+ bufferU[j++]=0x0C;
+ bufferU[j++]=(i/2+k)&0xFF;
+ bufferU[j++]=0x68;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x6C;
+ bufferU[j++]=0x00;
+ bufferU[j++]=AT_HV_RTX;
+ bufferU[j++]=2;
+ bufferU[j++]=0x78;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x7C;
+ bufferU[j++]=0x00;
+ if(j>DIMBUF-14||k>=page||i>=dim-2){
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ for(z=0;z<DIMBUF-1;z++){
+ if(bufferI[z]==AT_HV_RTX){
+ if(memCODE[i+m]!=bufferI[z+1]){
+ PrintMessage4(strings[S_CodeVError],i+m,i+m,memCODE[i+m],bufferI[z+1]); //"Error writing address %4X: written %02X, read %02X\r\n"
+ err++;
+ }
+ m++;
+ z++;
+ }
+ }
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,m,m,err); //"i=%d, k=%d, err=%d\n"
+ }
+ if(max_err&&err>max_err){
+ PrintMessage1(strings[S_MaxErr],err); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ PrintMessage(strings[S_IntW]); //"Write interrupted"
+ i=dim;
+ }
+ }
+ }
+ }
+ }
+ }
+ PrintStatusEnd();
+ PrintMessage1(strings[S_ComplErr],err); //"completed, %d errors\r\n"
+//****************** write eeprom ********************
+ if(dim2){
+ int errEE=0;
+ PrintMessage(strings[S_EEAreaW]); //"Write EEPROM ... "
+ PrintStatusSetup();
+ if(saveLog)fprintf(logfile,"WRITE EEPROM\n");
+ j=0;
+ for(i=0;i<dim2;i++){
+ if(memEE[i]!=0xFF){
+ bufferU[j++]=AT_HV_RTX; //Write EEPROM
+ bufferU[j++]=7;
+ bufferU[j++]=0x4C;
+ bufferU[j++]=0x11;
+ bufferU[j++]=0x0C;
+ bufferU[j++]=i&0xFF;
+ bufferU[j++]=0x1C;
+ bufferU[j++]=i>>8;
+ bufferU[j++]=0x2C;
+ bufferU[j++]=memEE[i];
+ bufferU[j++]=0x6D;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x64;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x6C;
+ bufferU[j++]=0x00;
+ bufferU[j++]=READ_B; //check SDO
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ j=0;
+ PacketIO(2);
+ PrintStatus(strings[S_CodeWriting],i*100/dim2,i); //"Write: %d%%, addr. %03X"
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k,k); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ bufferU[j++]=READ_B; //check SDO
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ j=0;
+ for(t=0,sdo=0;t<20&&sdo==0;t++){
+ PacketIO(2);
+ for(z=0;z<DIMBUF-1&&bufferI[z]!=READ_B;z++);
+ sdo=bufferI[z+1]&2;
+ }
+ if(sdo==0&&saveLog) fprintf(logfile,"SDO=0\r\n");
+ //write verification
+ bufferU[j++]=AT_HV_RTX; //Read EEPROM
+ bufferU[j++]=5;
+ bufferU[j++]=0x4C;
+ bufferU[j++]=0x03;
+ bufferU[j++]=0x1C;
+ bufferU[j++]=i>>8;
+ bufferU[j++]=0x0C;
+ bufferU[j++]=i&0xFF;
+ bufferU[j++]=0x68;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x6C;
+ bufferU[j++]=0x00;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ for(z=0;z<DIMBUF-1&&bufferI[z]!=AT_HV_RTX;z++);
+ if(memEE[i]!=bufferI[z+1]){
+ PrintMessage4(strings[S_CodeVError],i,i,memEE[i],bufferI[z+1]); //"Error writing address %4X: written %02X, read %02X\r\n"
+ errEE++;
+ }
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,errEE); //"i=%d, k=%d, errors=%d\n"
+ }
+ if(err+errEE>=max_err) break;
+ }
+ }
+ PrintStatusEnd();
+ err+=errEE;
+ if(err>=max_err){
+ PrintMessage("\r\n");
+ PrintMessage1(strings[S_MaxErr],err); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ }
+ PrintMessage1(strings[S_ComplErr],errEE); //"completed: %d errors\r\n"
+ }
+//****************** write FUSE ********************
+ int err_f=0;
+ if(AVRlock<0x100||AVRfuse<0x100||AVRfuse_h<0x100||AVRfuse_x<0x100)PrintMessage(strings[S_FuseAreaW]); //"Write Fuse ... "
+ if(AVRfuse<0x100){
+ if(saveLog)fprintf(logfile,"WRITE FUSE\n");
+ bufferU[j++]=AT_HV_RTX;
+ bufferU[j++]=4;
+ bufferU[j++]=0x4C;
+ bufferU[j++]=0x40;
+ bufferU[j++]=0x2C;
+ bufferU[j++]=AVRfuse;
+ bufferU[j++]=0x64;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x6C;
+ bufferU[j++]=0x00;
+ bufferU[j++]=READ_B; //check SDO
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ j=0;
+ PacketIO(2);
+ for(z=0;z<DIMBUF-1&&bufferI[z]!=READ_B;z++);
+ sdo=bufferI[z+1]&2;
+ bufferU[j++]=READ_B; //check SDO
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ for(i=0;i<20&&sdo==0;i++){
+ PacketIO(2);
+ for(z=0;z<DIMBUF-1&&bufferI[z]!=READ_B;z++);
+ sdo=bufferI[z+1]&2;
+ }
+ if(sdo==0&&saveLog) fprintf(logfile,"SDO=0\r\n");
+ j=0;
+ bufferU[j++]=AT_HV_RTX;
+ bufferU[j++]=3;
+ bufferU[j++]=0x4C;
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x68;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x6C;
+ bufferU[j++]=0x00;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ for(z=0;z<DIMBUF-1&&bufferI[z]!=AT_HV_RTX;z++);
+ if(z==DIMBUF-1||AVRfuse!=bufferI[z+1]){
+ PrintMessage3(strings[S_WErr1],"fuse",AVRfuse,bufferI[z+1]); //"Error writing %s: written %02X, read %02X"
+ err_f++;
+ }
+ }
+ if(AVRfuse_h<0x100){
+ if(saveLog)fprintf(logfile,"WRITE FUSEH\n");
+ bufferU[j++]=AT_HV_RTX;
+ bufferU[j++]=4;
+ bufferU[j++]=0x4C;
+ bufferU[j++]=0x40;
+ bufferU[j++]=0x2C;
+ bufferU[j++]=AVRfuse_h;
+ bufferU[j++]=0x74;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x7C;
+ bufferU[j++]=0x00;
+ bufferU[j++]=READ_B; //check SDO
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ j=0;
+ PacketIO(2);
+ for(z=0;z<DIMBUF-1&&bufferI[z]!=READ_B;z++);
+ sdo=bufferI[z+1]&2;
+ bufferU[j++]=READ_B; //check SDO
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ for(i=0;i<20&&sdo==0;i++){
+ PacketIO(2);
+ for(z=0;z<DIMBUF-1&&bufferI[z]!=READ_B;z++);
+ sdo=bufferI[z+1]&2;
+ }
+ if(sdo==0&&saveLog) fprintf(logfile,"SDO=0\r\n");
+ j=0;
+ bufferU[j++]=AT_HV_RTX;
+ bufferU[j++]=3;
+ bufferU[j++]=0x4C;
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x7A;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x7E;
+ bufferU[j++]=0x00;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ for(z=0;z<DIMBUF-1&&bufferI[z]!=AT_HV_RTX;z++);
+ if(z==DIMBUF-1||AVRfuse_h!=bufferI[z+1]){
+ PrintMessage3(strings[S_WErr1],"fuseH",AVRfuse_h,bufferI[z+1]); //"Error writing %s: written %02X, read %02X"
+ err_f++;
+ }
+ }
+ if(AVRfuse_x<0x100){
+ if(saveLog)fprintf(logfile,"WRITE FUSEX\n");
+ bufferU[j++]=AT_HV_RTX;
+ bufferU[j++]=4;
+ bufferU[j++]=0x4C;
+ bufferU[j++]=0x40;
+ bufferU[j++]=0x2C;
+ bufferU[j++]=AVRfuse_x;
+ bufferU[j++]=0x66;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x6E;
+ bufferU[j++]=0x00;
+ bufferU[j++]=READ_B; //check SDO
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ j=0;
+ PacketIO(2);
+ for(z=0;z<DIMBUF-1&&bufferI[z]!=READ_B;z++);
+ sdo=bufferI[z+1]&2;
+ bufferU[j++]=READ_B; //check SDO
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ for(i=0;i<20&&sdo==0;i++){
+ PacketIO(2);
+ for(z=0;z<DIMBUF-1&&bufferI[z]!=READ_B;z++);
+ sdo=bufferI[z+1]&2;
+ }
+ if(sdo==0&&saveLog) fprintf(logfile,"SDO=0\r\n");
+ j=0;
+ bufferU[j++]=AT_HV_RTX;
+ bufferU[j++]=3;
+ bufferU[j++]=0x4C;
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x6A;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x6E;
+ bufferU[j++]=0x00;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ for(z=0;z<DIMBUF-1&&bufferI[z]!=AT_HV_RTX;z++);
+ if(z==DIMBUF-1||AVRfuse_x!=bufferI[z+1]){
+ PrintMessage3(strings[S_WErr1],"fuseX",AVRfuse_x,bufferI[z+1]); //"Error writing %s: written %02X, read %02X"
+ err_f++;
+ }
+ }
+ if(AVRlock<0x100){
+ if(saveLog)fprintf(logfile,"WRITE LOCK\n");
+ bufferU[j++]=AT_HV_RTX;
+ bufferU[j++]=4;
+ bufferU[j++]=0x4C;
+ bufferU[j++]=0x20;
+ bufferU[j++]=0x2C;
+ bufferU[j++]=AVRlock;
+ bufferU[j++]=0x64;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x6C;
+ bufferU[j++]=0x00;
+ bufferU[j++]=READ_B; //check SDO
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ j=0;
+ PacketIO(2);
+ for(z=0;z<DIMBUF-1&&bufferI[z]!=READ_B;z++);
+ sdo=bufferI[z+1]&2;
+ bufferU[j++]=READ_B; //check SDO
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ for(i=0;i<20&&sdo==0;i++){
+ PacketIO(2);
+ for(z=0;z<DIMBUF-1&&bufferI[z]!=READ_B;z++);
+ sdo=bufferI[z+1]&2;
+ }
+ if(sdo==0&&saveLog) fprintf(logfile,"SDO=0\r\n");
+ j=0;
+ bufferU[j++]=AT_HV_RTX;
+ bufferU[j++]=3;
+ bufferU[j++]=0x4C;
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x78;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x7C;
+ bufferU[j++]=0x00;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ for(z=0;z<DIMBUF-1&&bufferI[z]!=AT_HV_RTX;z++);
+ if(z==DIMBUF-1||AVRlock!=bufferI[z+1]){
+ PrintMessage3(strings[S_WErr1],"lock",AVRlock,bufferI[z+1]); //"Error writing %s: written %02X, read %02X"
+ err_f++;
+ }
+ }
+ err+=err_f;
+ if(AVRlock<0x100||AVRfuse<0x100||AVRfuse_h<0x100||AVRfuse_x<0x100){
+ PrintMessage1(strings[S_ComplErr],err_f); //"completed, %d errors\r\n"
+ }
+//****************** exit program mode ********************
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=SET_PORT_DIR; //All input
+ bufferU[j++]=0xFF;
+ bufferU[j++]=0xFF;
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ unsigned int stop=GetTickCount();
+ sprintf(str,strings[S_EndErr],(stop-start)/1000.0,err,err!=1?strings[S_ErrPlur]:strings[S_ErrSing]); //"\r\nEnd (%.2f s) %d %s\r\n\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+ PrintStatusClear();
+}
diff --git a/progAVR.h b/progAVR.h
new file mode 100644
index 0000000..df793c5
--- /dev/null
+++ b/progAVR.h
@@ -0,0 +1,8 @@
+void ReadAT(int dim, int dim2, int options);
+void ReadAT_HV(int dim, int dim2, int options);
+void WriteAT(int dim, int dim2, int dummy1, int dummy2);
+void WriteATmega(int dim, int dim2, int page, int options);
+void WriteAT_HV(int dim, int dim2, int page, int options);
+void DisplayCODEAVR(int dim);
+void WriteATfuseSlow(int fuse);
+#define SLOW 256
diff --git a/progEEPROM.c b/progEEPROM.c
new file mode 100644
index 0000000..f0e8259
--- /dev/null
+++ b/progEEPROM.c
@@ -0,0 +1,2311 @@
+/**
+ * \file progEEPROM.c
+ * algorithms to program various EEPROM types
+ * Copyright (C) 2009-2022 Alberto Maccioni
+ *
+ * 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"
+
+void ReadI2C(int dim,int addr)
+// read I2C memories
+// dim=size in bytes
+// addr:
+// [3:0] =0: 1 byte address =1: 2 byte address
+// [7:4] A2:A0 value
+// [11:8] 17th address bit location (added to control byte)
+{
+ int k=0,z=0,i,j;
+ int AX=(addr>>4)&7;
+ int addr17=(addr>>8)&0xF;
+ addr&=1;
+ if(dim>0x30000||dim<0){
+ PrintMessage(strings[S_EELim]); //"EEPROM size out of limits\r\n"
+ return;
+ }
+ if(saveLog){
+ OpenLogFile(); //"Log.txt"
+ fprintf(logfile,"ReadI2C(%d,%d) (0x%X,0x%X)\n",dim,addr,dim,addr);
+ }
+ sizeEE=dim;
+ if(memEE) free(memEE);
+ memEE=(unsigned char*)malloc(dim); //EEPROM
+ unsigned int start=GetTickCount();
+ hvreg=0;
+ j=0;
+ bufferU[j++]=VREG_DIS;
+ bufferU[j++]=I2C_INIT;
+ bufferU[j++]=AX; //100k
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+//****************** read ********************
+ PrintMessage(strings[S_ReadEE]); //read EEPROM ...
+ PrintStatusSetup();
+ int inc;
+ for(i=0,j=0;i<dim;i+=inc){
+ if(i<0x10000&&i>0x10000-(DIMBUF-4)) inc=0x10000-i; //do not cross 64KB boundary
+ else inc=i<dim-(DIMBUF-4)?DIMBUF-4:dim-i;
+ if(!addr){ //1 byte address
+ bufferU[j++]=I2C_READ;
+ bufferU[j++]=inc;
+ bufferU[j++]=0xA0+((i>>7)&0x0E);
+ bufferU[j++]=i&0xFF;
+ }
+ else{ //2 byte address
+ bufferU[j++]=I2C_READ2;
+ bufferU[j++]=inc;
+ bufferU[j++]=0xA0+(i>0xFFFF?addr17:0); //17th bit if>64K
+ bufferU[j++]=(i>>8)&0xFF;
+ bufferU[j++]=i&0xFF;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(8);
+ for(j=0;j<DIMBUF-1&&bufferI[j]!=I2C_READ&&bufferI[j]!=I2C_READ2;j++);
+ if(j<DIMBUF-1&&bufferI[j+1]<0xFA){
+ for(z=j+2;z<j+2+bufferI[j+1]&&z<DIMBUF;z++) memEE[k++]=bufferI[z];
+ }
+ PrintStatus(strings[S_CodeReading2],i*100/(dim),i); //"Read: %d%%, addr. %05X"
+ if(RWstop) i=dim;
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k,k); //"i=%d(0x%X), k=%d(0x%X) \n"
+ }
+ }
+ PrintStatusEnd();
+ if(k!=dim){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ReadEEErr],dim,k); //"Error reading EEPROM area, requested %d bytes, read %d\r\n"
+ sizeEE=k;
+ }
+ else PrintMessage(strings[S_Compl]);
+//****************** exit ********************
+ bufferU[j++]=EN_VPP_VCC; //0
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ unsigned int stop=GetTickCount();
+ PrintStatusClear();
+ DisplayEE(); //visualize
+ int sum=0;
+ for(i=0;i<sizeEE;i++) sum+=memEE[i];
+ PrintMessage1("Checksum: 0x%X\r\n",sum&0xFFFF);
+ sprintf(str,strings[S_End],(stop-start)/1000.0); //"\r\nEnd (%.2f s)\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+}
+
+void WriteI2C(int dim,int addr,int page)
+// write I2C memories
+// dim=size in bytes
+// addr:
+// [3:0] =0: 1 byte address =1: 2 byte address
+// [7:4] A2:A0 value
+// [11:8] 17th address bit location (added to control byte)
+// page=page size
+{
+ int k=0,z=0,i,j;
+ int err=0;
+ int AX=(addr>>4)&7;
+ int addr17=(addr>>8)&0xF;
+ addr&=1;
+ hvreg=0;
+ if(dim>0x30000||dim<0){
+ PrintMessage(strings[S_EELim]); //"EEPROM size out of limits\r\n"
+ return;
+ }
+ if(saveLog){
+ OpenLogFile(); //"Log.txt"
+ fprintf(logfile,"WriteI2C(%d,%d,%d) (0x%X,0x%X)\n",dim,addr,page,dim,addr);
+ }
+ if(dim>sizeEE){
+ i=sizeEE;
+ memEE=(unsigned char*)realloc(memEE,dim);
+ for(;i<dim;i++) memEE[i]=0xFF;
+ sizeEE=dim;
+ }
+ if(dim<1){
+ PrintMessage(strings[S_NoCode]); //"Data area is empty\r\n"
+ return;
+ }
+ unsigned int start=GetTickCount();
+ j=0;
+ bufferU[j++]=VREG_DIS;
+ bufferU[j++]=I2C_INIT;
+ bufferU[j++]=AX; //100k
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+//****************** write ********************
+ PrintMessage(strings[S_EEAreaW]); //"Write EEPROM ... "
+ PrintStatusSetup();
+ for(;page>=DIMBUF-6;page>>=1);
+ for(i=0,j=0;i<dim;i+=page){
+ bufferU[j++]=I2C_WRITE;
+ if(!addr){ //1 byte address
+ bufferU[j++]=page;
+ bufferU[j++]=0xA0+((i>>7)&0x0E);
+ bufferU[j++]=i&0xFF;
+ }
+ else{ //2 byte address
+ bufferU[j++]=page+1;
+ bufferU[j++]=0xA0+(i>0xFFFF?addr17:0); //17th bit if>64K
+ bufferU[j++]=(i>>8)&0xFF;
+ bufferU[j++]=i&0xFF;
+ }
+ for(k=0;k<page;k++) bufferU[j++]=memEE[i+k];
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(3);
+ for(j=0;j<DIMBUF-1&&bufferI[j]!=I2C_WRITE;j++);
+ if(bufferI[j]!=I2C_WRITE||bufferI[j+1]>=0xFA) i=dim+10;
+ PrintStatus(strings[S_CodeWriting2],i*100/(dim),i); //"Write: %d%%, addr. %04X"
+ if(RWstop) i=dim;
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k,k); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ bufferU[j++]=I2C_WRITE;
+ bufferU[j++]=0;
+ bufferU[j++]=0xA0; //ACK polling
+ bufferU[j++]=0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ int ack=0xFD;
+ for(j=0;ack==0xFD&&j<20;j++){ //ACK polling until write complete
+ PacketIO(2);
+ for(j=0;j<DIMBUF-1&&bufferI[j]!=I2C_WRITE;j++);
+ if(bufferI[j]!=I2C_WRITE||bufferI[j+1]>=0xFA) ack=0xFD;
+ else ack=bufferI[j+1];
+ }
+ j=0;
+ }
+ PrintStatusEnd();
+ PrintMessage(strings[S_Compl]); //"completed\r\n"
+//****************** verify EEPROM ********************
+ PrintMessage(strings[S_EEV]); //"Verify EEPROM ... "
+ PrintStatusSetup();
+ k=0;
+ int inc;
+ for(i=0,j=0;i<dim;i+=inc){
+ if(i<0x10000&&i>0x10000-(DIMBUF-4)) inc=0x10000-i; //do not cross 64KB boundary
+ else inc=i<dim-(DIMBUF-4)?DIMBUF-4:dim-i;
+ if(!addr){ //1 byte address
+ bufferU[j++]=I2C_READ;
+ bufferU[j++]=inc;
+ bufferU[j++]=0xA0+((i>>7)&0x0E);
+ bufferU[j++]=i&0xFF;
+ }
+ else{ //2 byte address
+ bufferU[j++]=I2C_READ2;
+ bufferU[j++]=inc;
+ bufferU[j++]=0xA0+(i>0xFFFF?addr17:0); //17th bit if>64K
+ bufferU[j++]=(i>>8)&0xFF;
+ bufferU[j++]=i&0xFF;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(8);
+ for(j=0;j<DIMBUF-1&&bufferI[j]!=I2C_READ&&bufferI[j]!=I2C_READ2;j++);
+ if((bufferI[j]==I2C_READ||bufferI[j]==I2C_READ2)&&bufferI[j+1]<0xFA){
+ for(z=j+2;z<(j+2+bufferI[j+1])&&z<DIMBUF;z++){
+ if(memEE[k++]!=bufferI[z]){
+ PrintMessage("\r\n");
+ PrintMessage4(strings[S_CodeVError],i+z-3,i+z-3,memEE[k-1],bufferI[z]); //"Error verifying address %04X (%d), written %02X, read %02X\r\n"
+ err++;
+ }
+ }
+ }
+ PrintStatus(strings[S_CodeV2],i*100/(dim),i); //"Verify: %d%%, addr. %04X"
+ if(RWstop) i=dim;
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,err); //"i=%d, k=%d, err=%d\n"
+ }
+ if(err>=max_err) break;
+ }
+ PrintStatusEnd();
+ if(k!=dim){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ReadEEErr],dim,k); //"Error reading EEPROM area, requested %d bytes, read %d\r\n"
+ }
+ PrintMessage1(strings[S_ComplErr],err); //"completed: %d errors\r\n"
+//****************** exit ********************
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ unsigned int stop=GetTickCount();
+ PrintStatusClear();
+ sprintf(str,strings[S_EndErr],(stop-start)/1000.0,err,err!=1?strings[S_ErrPlur]:strings[S_ErrSing]); //"\r\nEnd (%.2f s) %d %s\r\n\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+}
+
+#define PRE 0x08 //RB3
+#define S 0x10 //RB4
+#define W 0x20 //RB5
+#define ORG 0x20 //RB5
+
+void Read93x(int dim,int na,int options)
+// read 93Sx6 uW memories
+// dim=size in bytes
+// na=address bits
+// options=0: x16 organization =1: x8 organization
+{
+ int k=0,z=0,i,j,x8;
+ hvreg=0;
+ if(dim>0x3000||dim<0){
+ PrintMessage(strings[S_EELim]); //"EEPROM size out of limits\r\n"
+ return;
+ }
+ if(na>13) na=13;
+ if(saveLog){
+ OpenLogFile(); //"Log.txt"
+ fprintf(logfile,"Read93x(%d,%d,%d) (0x%X,0x%X)\n",dim,na,options,dim,na);
+ }
+ x8=options&1;
+ sizeEE=dim;
+ if(memEE) free(memEE);
+ memEE=(unsigned char*)malloc(dim); //EEPROM
+ unsigned int start=GetTickCount();
+ j=0;
+ bufferU[j++]=VREG_DIS;
+ bufferU[j++]=uW_INIT;
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=x8?S:S+ORG;
+ bufferU[j++]=0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+//****************** read ********************
+ PrintMessage(strings[S_ReadEE]); //read EEPROM ...
+ PrintStatusSetup();
+ int dim2=x8?dim:dim/2;
+ for(i=0;i<dim2;){
+ for(j=0;j<DIMBUF-14&&i<dim2;){
+ bufferU[j++]=uWTX;
+ bufferU[j++]=na+3; //READ
+ bufferU[j++]=0xC0+((i>>(na-5))&0x1F); //110aaaaa aaax0000
+ bufferU[j++]=(i<<(13-na))&0xFF;
+ bufferU[j++]=uWRX;
+ bufferU[j++]=x8?8:16;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=x8?0:ORG;
+ bufferU[j++]=0;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=x8?S:S+ORG;
+ bufferU[j++]=0;
+ i++;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ for(z=0;z<DIMBUF-3;z++){
+ for(;bufferI[z]!=uWRX&&z<DIMBUF-3;z++);
+ if(bufferI[z]==uWRX){
+ if(x8) memEE[k++]=bufferI[z+2];
+ else{
+ memEE[k+1]=bufferI[z+2];
+ memEE[k]=bufferI[z+3];
+ k+=2;
+ }
+ z+=3;
+ }
+ }
+ PrintStatus(strings[S_CodeReading2],i*100/dim2,i); //"Read: %d%%, addr. %05X"
+ if(RWstop) i=dim;
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k,k); //"i=%d(0x%X), k=%d(0x%X) \n"
+ }
+ }
+ PrintStatusEnd();
+ if(k!=dim){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ReadEEErr],dim,k); //"Error reading EEPROM area, requested %d bytes, read %d\r\n"
+ sizeEE=k;
+ }
+ else PrintMessage(strings[S_Compl]);
+//****************** exit ********************
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=EN_VPP_VCC; //0
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ unsigned int stop=GetTickCount();
+ PrintStatusClear();
+ DisplayEE(); //visualize
+ int sum=0;
+ for(i=0;i<sizeEE;i++) sum+=memEE[i];
+ PrintMessage1("Checksum: 0x%X\r\n",sum&0xFFFF);
+ sprintf(str,strings[S_End],(stop-start)/1000.0); //"\r\nEnd (%.2f s)\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+}
+
+void Write93Sx(int dim,int na,int page)
+// write 93Sx6 uW memories
+// dim=size in bytes
+// na=address bits
+// page=page size (bytes)
+// automatic write delay
+{
+ int k=0,z=0,i,j;
+ int err=0;
+ hvreg=0;
+ if(dim>0x1000||dim<0){
+ PrintMessage(strings[S_EELim]); //"EEPROM size out of limits\r\n"
+ return;
+ }
+ if(na>13) na=13;
+ if(page>48) page=48;
+ if(saveLog){
+ OpenLogFile(); //"Log.txt"
+ fprintf(logfile,"Write93Sx(%d,%d,%d) (0x%X,0x%X)\n",dim,na,page,dim,na);
+ }
+ if(dim>sizeEE){
+ i=sizeEE;
+ memEE=(unsigned char*)realloc(memEE,dim);
+ for(;i<dim;i++) memEE[i]=0xFF;
+ sizeEE=dim;
+ }
+ if(dim<1){
+ PrintMessage(strings[S_NoCode]); //"Data area is empty\r\n"
+ return;
+ }
+ unsigned int start=GetTickCount();
+ j=0;
+ bufferU[j++]=VREG_DIS;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=uW_INIT;
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=S+W;
+ bufferU[j++]=0;
+ bufferU[j++]=uWTX;
+ bufferU[j++]=na+3;
+ bufferU[j++]=0x98; //100 11xxx write enable
+ bufferU[j++]=0;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=W;
+ bufferU[j++]=0;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=S+W+PRE;
+ bufferU[j++]=0;
+ bufferU[j++]=uWTX;
+ bufferU[j++]=na+3;
+ bufferU[j++]=0x98; //100 11xxx Prot. reg. enable
+ bufferU[j++]=0;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=W+PRE;
+ bufferU[j++]=0;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=S+W+PRE;
+ bufferU[j++]=0;
+ bufferU[j++]=uWTX;
+ bufferU[j++]=na+3;
+ bufferU[j++]=0xFF; //111 11111111 Prot. reg. clear
+ bufferU[j++]=0xF0;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=W+PRE;
+ bufferU[j++]=0;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=S+W;
+ bufferU[j++]=0;
+ bufferU[j++]=uWTX;
+ bufferU[j++]=na+3;
+ bufferU[j++]=0x98; //100 11xxx write enable
+ bufferU[j++]=0;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=W;
+ bufferU[j++]=0;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=S+W+PRE;
+ bufferU[j++]=0;
+ bufferU[j++]=uWTX;
+ bufferU[j++]=na+3;
+ bufferU[j++]=0xC0; //110 xxxxx Prot. reg. read
+ bufferU[j++]=0;
+ bufferU[j++]=uWRX;
+ bufferU[j++]=10;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=W+PRE;
+ bufferU[j++]=0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+//****************** write ********************
+ PrintMessage(strings[S_EEAreaW]); //"Write EEPROM ... "
+ PrintStatusSetup();
+ int addr=0;
+ for(i=0,j=0;i<dim;i+=page,addr+=(0x10000>>na)*page/2){
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=W; //make sure to start with S=0
+ bufferU[j++]=0;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=S+W;
+ bufferU[j++]=0;
+ bufferU[j++]=uWTX;
+ bufferU[j++]=3;
+ bufferU[j++]=0xE0; //111aaaaa aaa(a) D page write
+ bufferU[j++]=uWTX;
+ bufferU[j++]=na;
+ bufferU[j++]=addr>>8;
+ if(na>8) bufferU[j++]=addr&0xFF;
+ bufferU[j++]=uWTX;
+ bufferU[j++]=8*page;
+ for(k=0;k<page;k+=2){
+ bufferU[j++]=memEE[i+k+1];
+ bufferU[j++]=memEE[i+k];
+ }
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=W;
+ bufferU[j++]=0;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=S+W; //S=1 to check status
+ bufferU[j++]=0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ for(j=0;j<DIMBUF-1&&bufferI[j]!=uWTX;j++);
+ if(bufferI[j]!=uWTX||bufferI[j+1]>=0xFA) i=dim+10;
+ bufferU[j++]=uWRX;
+ bufferU[j++]=1;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ for(z=0,k=0;z<30&&!k;z++){ //Wait until ready
+ PacketIO(2);
+ for(j=0;j<DIMBUF-1&&bufferI[j]!=uWRX;j++);
+ if(bufferI[j]==uWRX) k=bufferI[j+2];
+ }
+ j=0;
+ PrintStatus(strings[S_CodeWriting2],i*100/(dim),i); //"Write: %d%%, addr. %04X"
+ if(RWstop) i=dim;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k,k); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ }
+ PrintStatusEnd();
+ PrintMessage(strings[S_Compl]); //"completed\r\n"
+//****************** verify EEPROM ********************
+ PrintMessage(strings[S_EEV]); //"Verify EEPROM ... "
+ PrintStatusSetup();
+ j=0;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=S;
+ bufferU[j++]=0;
+ bufferU[j++]=uWTX;
+ bufferU[j++]=na+3; //READ (16bit)
+ bufferU[j++]=0xC0; //110aaaaa aaax0000
+ bufferU[j++]=0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ k=0;
+ int n=(DIMBUF-2);
+ if(n>30) n=30; //max 240 bit = 30 Byte
+ for(i=0,j=0;i<dim;i+=n){
+ bufferU[j++]=uWRX;
+ bufferU[j++]=i<(dim-n)?n*8:(dim-i)*8;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ for(j=0;bufferI[j]!=uWRX&&j<DIMBUF-1;j++);
+ if(bufferI[j]==uWRX){
+ for(z=j+2;z<j+2+bufferI[j+1]/8&&z<DIMBUF;z+=2,k+=2){
+ if(memEE[k+1]!=bufferI[z]){
+ PrintMessage("\r\n");
+ PrintMessage4(strings[S_CodeVError],i+z-3,i+z-3,memEE[k+1],bufferI[z]); //"Error verifying address %04X (%d), written %02X, read %02X\r\n"
+ err++;
+ }
+ if(memEE[k]!=bufferI[z+1]){
+ PrintMessage("\r\n");
+ PrintMessage4(strings[S_CodeVError],i+z-3,i+z-3,memEE[k],bufferI[z+1]); //"Error verifying address %04X (%d), written %02X, read %02X\r\n"
+ err++;
+ }
+ }
+ }
+ PrintStatus(strings[S_CodeV2],i*100/(dim),i); //"Verify: %d%%, addr. %04X"
+ if(RWstop) i=dim;
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,err); //"i=%d, k=%d, err=%d\n"
+ }
+ if(err>=max_err) break;
+ }
+ PrintStatusEnd();
+ if(k!=dim){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ReadEEErr],dim,k); //"Error reading EEPROM area, requested %d bytes, read %d\r\n"
+ }
+ PrintMessage1(strings[S_ComplErr],err); //"completed: %d errors\r\n"
+//****************** exit ********************
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ unsigned int stop=GetTickCount();
+ PrintStatusClear();
+ sprintf(str,strings[S_EndErr],(stop-start)/1000.0,err,err!=1?strings[S_ErrPlur]:strings[S_ErrSing]); //"\r\nEnd (%.2f s) %d %s\r\n\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+}
+
+void Write93Cx(int dim,int na, int options)
+// write 93Cx6 uW memories
+// dim=size in bytes
+// na=address bits
+// options=0: x16 organization =1: x8 organization
+{
+ int k=0,z=0,i,j;
+ int err=0;
+ hvreg=0;
+ if(dim>0x1000||dim<0){
+ PrintMessage(strings[S_EELim]); //"EEPROM size out of limits\r\n"
+ return;
+ }
+ if(na>13) na=13;
+ if(saveLog){
+ OpenLogFile(); //"Log.txt"
+ fprintf(logfile,"Write93Cx(%d,%d,%d) (0x%X,0x%X)\n",dim,na,options,dim,na);
+ }
+ if(dim>sizeEE){
+ i=sizeEE;
+ memEE=(unsigned char*)realloc(memEE,dim);
+ for(;i<dim;i++) memEE[i]=0xFF;
+ sizeEE=dim;
+ }
+ if(dim<1){
+ PrintMessage(strings[S_NoCode]); //"Data area is empty\r\n"
+ return;
+ }
+ unsigned int start=GetTickCount();
+ j=0;
+ bufferU[j++]=VREG_DIS;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=uW_INIT;
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=options==0?S+ORG+PRE:S+PRE;
+ bufferU[j++]=0;
+ bufferU[j++]=uWTX;
+ bufferU[j++]=na+3;
+ bufferU[j++]=0x98; //100 11xxx EWEN
+ bufferU[j++]=0;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=options==0?ORG+PRE:PRE;
+ bufferU[j++]=0;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=options==0?S+ORG+PRE:S+PRE;
+ bufferU[j++]=0;
+ bufferU[j++]=uWTX;
+ bufferU[j++]=na+3;
+ bufferU[j++]=0x90; //100 10xxx ERAL
+ bufferU[j++]=0;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=options==0?ORG+PRE:PRE;
+ bufferU[j++]=0;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=options==0?S+ORG+PRE:S+PRE;
+ bufferU[j++]=0;
+ bufferU[j++]=uWRX;
+ bufferU[j++]=1;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ j=0;
+ bufferU[j++]=uWRX;
+ bufferU[j++]=1;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ for(i=0,k=0;i<30&&!k;i++){ //Wait until ready
+ PacketIO(2);
+ for(j=0;j<DIMBUF-1&&bufferI[j]!=uWRX;j++);
+ if(bufferI[j]==uWRX) k=bufferI[j+2];
+ }
+//****************** write ********************
+ PrintMessage(strings[S_EEAreaW]); //"Write EEPROM ... "
+ PrintStatusSetup();
+ int addr=0;
+ j=0;
+ for(i=0;i<dim;i+=options==0?2:1,addr+=0x10000>>na){
+ if(memEE[i]<0xFF||(options==0&&memEE[i+1]<0xFF)){
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=options==0?ORG+PRE:PRE;
+ bufferU[j++]=0;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=options==0?S+ORG+PRE:S+PRE;
+ bufferU[j++]=0;
+ bufferU[j++]=uWTX;
+ bufferU[j++]=3;
+ bufferU[j++]=0xA0; //101aaaaa aaa(a) write
+ bufferU[j++]=uWTX;
+ bufferU[j++]=na;
+ bufferU[j++]=addr>>8;
+ if(na>8) bufferU[j++]=addr&0xFF;
+ bufferU[j++]=uWTX;
+ if(options==0){ //x16
+ bufferU[j++]=16;
+ bufferU[j++]=memEE[i+1];
+ bufferU[j++]=memEE[i];
+ }
+ else{ //x8
+ bufferU[j++]=8;
+ bufferU[j++]=memEE[i];
+ }
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=options==0?ORG+PRE:PRE;
+ bufferU[j++]=0;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=options==0?S+ORG+PRE:S+PRE;
+ bufferU[j++]=0;
+ bufferU[j++]=uWRX;
+ bufferU[j++]=1;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ PrintStatus(strings[S_CodeWriting2],i*100/(dim),i); //"Write: %d%%, addr. %04X"
+ if(RWstop) i=dim;
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k,k); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ bufferU[j++]=uWRX;
+ bufferU[j++]=1;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ for(z=0,k=0;z<30&&!k;z++){ //Wait until ready
+ PacketIO(2);
+ for(j=0;j<DIMBUF-1&&bufferI[j]!=uWRX;j++);
+ if(bufferI[j]==uWRX) k=bufferI[j+2];
+ }
+ j=0;
+ }
+ }
+ msDelay(2);
+ PrintStatusEnd();
+ if(i!=dim){
+ PrintMessage2(strings[S_CodeWError4],i,dim); //"Error writing code area, requested %d bytes, read %d\r\n"
+ }
+ else PrintMessage(strings[S_Compl]); //"completed\r\n"
+//****************** verify EEPROM ********************
+ PrintMessage(strings[S_EEV]); //"Verify EEPROM ... "
+ PrintStatusSetup();
+ j=0;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=options==0?ORG+PRE:PRE;
+ bufferU[j++]=0;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=options==0?S+ORG+PRE:S+PRE;
+ bufferU[j++]=0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ k=0;
+ int dim2=options==0?dim/2:dim;
+ for(i=0;i<dim2;){
+ for(j=0;j<DIMBUF-14&&i<dim2;){
+ bufferU[j++]=uWTX;
+ bufferU[j++]=na+3; //READ
+ bufferU[j++]=0xC0+((i>>(na-5))&0x1F); //110aaaaa aaax0000
+ bufferU[j++]=(i<<(13-na))&0xFF;
+ bufferU[j++]=uWRX;
+ bufferU[j++]=options==0?16:8;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=options==0?ORG:0;
+ bufferU[j++]=0;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=options==0?S+ORG:S;
+ bufferU[j++]=0;
+ i++;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ for(z=0;z<DIMBUF-3;z++){
+ for(;bufferI[z]!=uWRX&&z<DIMBUF-3;z++);
+ if(bufferI[z]==uWRX){
+ if(options==1){ //x8
+ if(memEE[k]!=bufferI[z+2]){
+ PrintMessage("\r\n");
+ PrintMessage4(strings[S_CodeVError],k,k,memEE[k],bufferI[z+2]); //"Error verifying address %04X (%d), written %02X, read %02X\r\n"
+ err++;
+ }
+ k++;
+ }
+ else{ //x16
+ if(memEE[k]!=bufferI[z+3]){
+ PrintMessage("\r\n");
+ PrintMessage4(strings[S_CodeVError],k,k,memEE[k],bufferI[z+3]); //"Error verifying address %04X (%d), written %02X, read %02X\r\n"
+ err++;
+ }
+ if(memEE[k+1]!=bufferI[z+2]){
+ PrintMessage("\r\n");
+ PrintMessage4(strings[S_CodeVError],k+1,k+1,memEE[k+1],bufferI[z+2]); //"Error verifying address %04X (%d), written %02X, read %02X\r\n"
+ err++;
+ }
+ k+=2;
+ }
+ z+=3;
+ }
+ }
+ PrintStatus(strings[S_CodeV2],i*100/dim2,i); //"Verify: %d%%, addr. %04X"
+ if(RWstop) i=dim;
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,err); //"i=%d, k=%d, err=%d\n"
+ }
+ if(err>=max_err) break;
+ }
+ PrintStatusEnd();
+ if(k!=dim){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ReadEEErr],dim,k); //"Error reading EEPROM area, requested %d bytes, read %d\r\n"
+ }
+ PrintMessage1(strings[S_ComplErr],err); //"completed: %d errors\r\n"
+//****************** exit ********************
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ unsigned int stop=GetTickCount();
+ PrintStatusClear();
+ sprintf(str,strings[S_EndErr],(stop-start)/1000.0,err,err!=1?strings[S_ErrPlur]:strings[S_ErrSing]); //"\r\nEnd (%.2f s) %d %s\r\n\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+}
+
+#define CS 8
+#define HLD 16 //Hold
+#define WP 0x40 //Write protect
+
+void Read25xx(int dim)
+// read 25xx SPI memories
+// dim=size in bytes
+{
+ int k=0,z=0,i,j,ID;
+ hvreg=0;
+ if(dim>0x1000000||dim<0){
+ PrintMessage(strings[S_EELim]); //"EEPROM size out of limits\r\n"
+ return;
+ }
+ if(saveLog){
+ OpenLogFile(); //"Log.txt"
+ fprintf(logfile,"Read25xx(%d) (0x%X)\n",dim,dim);
+ }
+ sizeEE=dim;
+ if(memEE) free(memEE);
+ memEE=(unsigned char*)malloc(dim); //EEPROM
+ unsigned int start=GetTickCount();
+ j=0;
+ bufferU[j++]=VREG_DIS;
+ bufferU[j++]=SPI_INIT;
+ bufferU[j++]=3; //0=100k, 1=200k, 2=300k, 3=500k (in reality 200k)
+// bufferU[j++]=SET_T1T2;
+// bufferU[j++]=2; //force T=28us -> 286 kbps
+// bufferU[j++]=0;
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=EXT_PORT; //CS=1, HLD=1, WP=0
+ bufferU[j++]=CS+HLD;
+ bufferU[j++]=0;
+ bufferU[j++]=EXT_PORT; //CS=0, HLD=1, WP=0
+ bufferU[j++]=HLD;
+ bufferU[j++]=0;
+ bufferU[j++]=SPI_WRITE; //READ ID
+ bufferU[j++]=1;
+ bufferU[j++]=0x9F;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=3;
+ bufferU[j++]=EXT_PORT; //CS=1, HLD=1, WP=0
+ bufferU[j++]=CS+HLD;
+ bufferU[j++]=0;
+ bufferU[j++]=EXT_PORT; //CS=0, HLD=1, WP=0
+ bufferU[j++]=HLD;
+ bufferU[j++]=0;
+ bufferU[j++]=SPI_WRITE; //Read
+ if(dim>0x10000){ //24 bit address
+ bufferU[j++]=4;
+ bufferU[j++]=3;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ }
+ else if(dim>0x200){ //16 bit address
+ bufferU[j++]=3;
+ bufferU[j++]=3;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ }
+ else{ //8 bit address
+ bufferU[j++]=2;
+ bufferU[j++]=3;
+ bufferU[j++]=0;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ for(z=0;z<DIMBUF-4&&bufferI[z]!=SPI_READ;z++);
+ ID=(bufferI[z+2]<<16)+(bufferI[z+3]<<8)+bufferI[z+4];
+ if(ID>0&&ID!=0xFFFFFF) PrintMessage1("DEVICE ID=0x%06X\r\n",ID);
+//****************** read ********************
+ PrintMessage(strings[S_ReadEE]); //read EEPROM ...
+ PrintStatusSetup();
+ for(i=0,j=0;i<dim;i+=DIMBUF-4){
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=i<dim-(DIMBUF-4)?DIMBUF-4:dim-i;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(4);
+ for(j=0;j<DIMBUF-1&&bufferI[j]!=SPI_READ;j++);
+ if(bufferI[j]==SPI_READ&&bufferI[j+1]<0xFA){
+ for(z=j+2;z<j+2+bufferI[j+1]&&z<DIMBUF;z++) memEE[k++]=bufferI[z];
+ }
+ PrintStatus(strings[S_CodeReading2],i*100/(dim),i); //"Read: %d%%, addr. %05X"
+ if(RWstop) i=dim;
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k,k); //"i=%d(0x%X), k=%d(0x%X) \n"
+ }
+ }
+ PrintStatusEnd();
+ if(k!=dim){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ReadEEErr],dim,k); //"Error reading EEPROM area, requested %d bytes, read %d\r\n"
+ sizeEE=k;
+ }
+ else PrintMessage(strings[S_Compl]);
+//****************** exit ********************
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=EN_VPP_VCC; //0
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ unsigned int stop=GetTickCount();
+ PrintStatusClear();
+ DisplayEE(); //visualize
+ int sum=0;
+ for(i=0;i<sizeEE;i++) sum+=memEE[i];
+ PrintMessage1("Checksum: 0x%X\r\n",sum&0xFFFF);
+ sprintf(str,strings[S_End],(stop-start)/1000.0); //"\r\nEnd (%.2f s)\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+}
+
+/*void Read25xxFast(int dim)
+// read 25xx SPI memories
+// dim=size in bytes
+{
+ int k=0,z=0,i,j,ID;
+ hvreg=0;
+ if(dim>0x1000000||dim<0){
+ PrintMessage(strings[S_EELim]); //"EEPROM size out of limits\r\n"
+ return;
+ }
+ if(saveLog){
+ OpenLogFile(); //"Log.txt"
+ fprintf(logfile,"Read25xxF(%d) (0x%X)\n",dim,dim);
+ }
+ sizeEE=dim;
+ if(memEE) free(memEE);
+ memEE=(unsigned char*)malloc(dim); //EEPROM
+ unsigned int start=GetTickCount();
+ j=0;
+ bufferU[j++]=VREG_DIS;
+ bufferU[j++]=SPI_INIT;
+ bufferU[j++]=3; //0=100k, 1=200k, 2=300k, 3=500k (in reality 200k)
+// bufferU[j++]=SET_T1T2;
+// bufferU[j++]=2; //force T=28us -> 286 kbps
+// bufferU[j++]=0;
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=EXT_PORT; //CS=1, HLD=1, WP=0
+ bufferU[j++]=CS+HLD;
+ bufferU[j++]=0;
+ bufferU[j++]=EXT_PORT; //CS=0, HLD=1, WP=1
+ bufferU[j++]=HLD;
+ bufferU[j++]=WP;
+ bufferU[j++]=SPI_WRITE; //READ ID
+ bufferU[j++]=1;
+ bufferU[j++]=0x9F;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=3;
+ bufferU[j++]=EXT_PORT; //CS=1, HLD=1, WP=1
+ bufferU[j++]=CS+HLD;
+ bufferU[j++]=WP;
+ bufferU[j++]=EXT_PORT; //CS=0, HLD=1, WP=0
+ bufferU[j++]=HLD;
+ bufferU[j++]=0;
+ bufferU[j++]=SPI_WRITE; //Read
+ if(dim>0x10000){ //24 bit address
+ bufferU[j++]=4;
+ bufferU[j++]=3;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ }
+ else if(dim>0x200){ //16 bit address
+ bufferU[j++]=3;
+ bufferU[j++]=3;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ }
+ else{ //8 bit address
+ bufferU[j++]=2;
+ bufferU[j++]=3;
+ bufferU[j++]=0;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ for(z=0;z<DIMBUF-4&&bufferI[z]!=SPI_READ;z++);
+ ID=(bufferI[z+2]<<16)+(bufferI[z+3]<<8)+bufferI[z+4];
+ if(ID>0&&ID!=0xFFFFFF) PrintMessage1("DEVICE ID=0x%06X\r\n",ID);
+//****************** read ********************
+ PrintMessage(strings[S_ReadEE]); //read EEPROM ...
+ PrintStatusSetup();
+ #define rSize (DIMBUF-5-2)
+ #define npack 255
+ j=0;
+ bufferU[j++]=0xF6;
+ bufferU[j++]=npack;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=rSize;
+ bufferU[j++]=0xF7;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ for(i=0;i<dim;i+=rSize*npack){
+ #define TIMEOUT 50
+ ULONG Result;
+ __int64 start,stop,freq,timeout;
+ QueryPerformanceCounter((LARGE_INTEGER *)&start);
+ QueryPerformanceFrequency((LARGE_INTEGER *)&freq);
+ //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
+ fprintf(logfile,"bufferU=[");
+ for(int i=0;i<DIMBUF;i++){
+ if(i%32==0) fprintf(logfile,"\n");
+ fprintf(logfile,"%02X ",bufferU[i]);
+ }
+ fprintf(logfile,"]\n");
+ for(int r=0;r<npack;r++){
+ Result = ReadFile(ReadHandle,bufferI0,DIMBUF+1,&NumberOfBytesRead,(LPOVERLAPPED) &HIDOverlapped);
+ Result = WaitForSingleObject(hEventObject,TIMEOUT);
+// if(saveLog&&logfile) WriteLogIO();
+ fprintf(logfile,"bufferI=[");
+ for(int i=0;i<DIMBUF;i++){
+ if(i%32==0) fprintf(logfile,"\n");
+ fprintf(logfile,"%02X ",bufferI[i]);
+ }
+ fprintf(logfile,"]\n");
+ 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);
+ QueryPerformanceCounter((LARGE_INTEGER *)&start);
+ for(j=0;j<DIMBUF-1&&bufferI[j]!=SPI_READ;j++);
+ if(bufferI[j]==SPI_READ&&bufferI[j+1]<0xFA){
+ for(z=j+2;z<j+2+bufferI[j+1]&&z<DIMBUF&&k<dim;z++) memEE[k++]=bufferI[z];
+ }
+ PrintStatus(strings[S_CodeReading2],i*100/(dim),i); //"Read: %d%%, addr. %05X"
+ if(RWstop) i=dim;
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k,k); //"i=%d(0x%X), k=%d(0x%X) \n"
+ }
+ }
+ }
+ PrintStatusEnd();
+ if(k!=dim){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ReadEEErr],dim,k); //"Error reading EEPROM area, requested %d bytes, read %d\r\n"
+ sizeEE=k;
+ }
+ else PrintMessage(strings[S_Compl]);
+//****************** exit ********************
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=EN_VPP_VCC; //0
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ unsigned int stop=GetTickCount();
+ PrintStatusClear();
+ DisplayEE(); //visualize
+ int sum=0;
+ for(i=0;i<sizeEE;i++) sum+=memEE[i];
+ PrintMessage1("Checksum: 0x%X\r\n",sum&0xFFFF);
+ sprintf(str,strings[S_End],(stop-start)/1000.0); //"\r\nEnd (%.2f s)\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+}
+*/
+
+void Write25xx(int dim,int options)
+// write SPI memories
+// dim=size in bytes
+// options:
+// [11:0]=page size
+// [12]=erase before write
+// [13]=use status register 2
+// automatic write delay
+{
+ int k=0,z=0,i,j,ID;
+ int err=0;
+ hvreg=0;
+ int page=options&0xFFF;
+ if(dim>0x1000000||dim<0){
+ PrintMessage(strings[S_EELim]); //"EEPROM size out of limits\r\n"
+ return;
+ }
+ if(saveLog){
+ OpenLogFile(); //"Log.txt"
+ fprintf(logfile,"Write25xx(%d,%d) (0x%X,0x%X)\n",dim,options,dim,options);
+ }
+ if(dim>sizeEE){
+ i=sizeEE;
+ memEE=(unsigned char*)realloc(memEE,dim);
+ for(;i<dim;i++) memEE[i]=0xFF;
+ sizeEE=dim;
+ }
+ if(dim<1){
+ PrintMessage(strings[S_NoCode]); //"Data area is empty\r\n"
+ return;
+ }
+ unsigned int start=GetTickCount();
+ j=0;
+ bufferU[j++]=VREG_DIS;
+ bufferU[j++]=SPI_INIT;
+ bufferU[j++]=3; //0=100k, 1=200k, 2=300k, 3=500k
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=EXT_PORT; //CS=1, HLD=1, WP=0
+ bufferU[j++]=CS+HLD;
+ bufferU[j++]=0;
+ bufferU[j++]=EXT_PORT; //CS=0, HLD=1, WP=0
+ bufferU[j++]=HLD;
+ bufferU[j++]=0;
+ bufferU[j++]=SPI_WRITE; //READ ID
+ bufferU[j++]=1;
+ bufferU[j++]=0x9F;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=3;
+ bufferU[j++]=EXT_PORT; //CS=1, HLD=1, WP=1
+ bufferU[j++]=CS+HLD;
+ bufferU[j++]=WP;
+ bufferU[j++]=EXT_PORT; //CS=0, HLD=1, WP=1
+ bufferU[j++]=HLD;
+ bufferU[j++]=WP;
+ bufferU[j++]=SPI_WRITE; //READ STATUS
+ bufferU[j++]=1;
+ bufferU[j++]=5;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=1;
+ bufferU[j++]=EXT_PORT; //CS=1, HLD=1, WP=1
+ bufferU[j++]=CS+HLD;
+ bufferU[j++]=WP;
+ if(options&0x2000){
+ bufferU[j++]=EXT_PORT; //CS=0, HLD=1, WP=1
+ bufferU[j++]=HLD;
+ bufferU[j++]=WP;
+ bufferU[j++]=SPI_WRITE; //READ STATUS2
+ bufferU[j++]=1;
+ bufferU[j++]=0x35;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=1;
+ bufferU[j++]=EXT_PORT; //CS=1, HLD=1, WP=1
+ bufferU[j++]=CS+HLD;
+ bufferU[j++]=WP;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ j=0;
+ for(z=0;z<DIMBUF-4&&bufferI[z]!=SPI_READ;z++);
+ ID=(bufferI[z+2]<<16)+(bufferI[z+3]<<8)+bufferI[z+4];
+ if(ID>0&&ID!=0xFFFFFF){
+ PrintMessage1("DEVICE ID=0x%06X\r\n",ID);
+ if(saveLog) fprintf(logfile,"DEVICE ID=0x%06X\n",ID);
+ }
+ msDelay(10); //wait power-up timer in some devices
+ bufferU[j++]=EXT_PORT; //CS=0, HLD=1, WP=1
+ bufferU[j++]=HLD;
+ bufferU[j++]=WP;
+ bufferU[j++]=SPI_WRITE; //WRITE ENABLE
+ bufferU[j++]=1;
+ bufferU[j++]=6;
+ bufferU[j++]=EXT_PORT; //CS=1, HLD=1, WP=1
+ bufferU[j++]=CS+HLD;
+ bufferU[j++]=WP;
+ bufferU[j++]=EXT_PORT; //CS=0, HLD=1, WP=1
+ bufferU[j++]=HLD;
+ bufferU[j++]=WP;
+ if(options&0x2000){ //status 1+2
+ bufferU[j++]=SPI_WRITE; //WRITE STATUS
+ bufferU[j++]=3;
+ bufferU[j++]=1;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ }
+ else{
+ bufferU[j++]=SPI_WRITE; //WRITE STATUS
+ bufferU[j++]=2;
+ bufferU[j++]=1;
+ bufferU[j++]=0;
+ }
+ bufferU[j++]=EXT_PORT; //CS=1, HLD=1, WP=1
+ bufferU[j++]=CS+HLD;
+ bufferU[j++]=WP;
+ bufferU[j++]=EXT_PORT; //CS=0, HLD=1, WP=1
+ bufferU[j++]=HLD;
+ bufferU[j++]=WP;
+ bufferU[j++]=SPI_WRITE; //READ STATUS
+ bufferU[j++]=1;
+ bufferU[j++]=5;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=1;
+ bufferU[j++]=EXT_PORT; //CS=1, HLD=1, WP=1
+ bufferU[j++]=CS+HLD;
+ bufferU[j++]=WP;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ j=0;
+ if(options&0x1000){ //erase before write
+ PrintMessage(strings[S_StartErase]); //"Erasing ... "
+ if(saveLog) fprintf(logfile,"%s\n",strings[S_StartErase]); //"Erasing ... "
+ bufferU[j++]=EXT_PORT; //CS=0, HLD=1, WP=1
+ bufferU[j++]=HLD;
+ bufferU[j++]=WP;
+ bufferU[j++]=SPI_WRITE; //READ STATUS
+ bufferU[j++]=1;
+ bufferU[j++]=5;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=1;
+ bufferU[j++]=EXT_PORT; //CS=1, HLD=1, WP=1
+ bufferU[j++]=CS+HLD;
+ bufferU[j++]=WP;
+ if(options&0x2000){
+ bufferU[j++]=EXT_PORT; //CS=0, HLD=1, WP=1
+ bufferU[j++]=HLD;
+ bufferU[j++]=WP;
+ bufferU[j++]=SPI_WRITE; //READ STATUS2
+ bufferU[j++]=1;
+ bufferU[j++]=0x35;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=1;
+ bufferU[j++]=EXT_PORT; //CS=1, HLD=1, WP=1
+ bufferU[j++]=CS+HLD;
+ bufferU[j++]=WP;
+ }
+ bufferU[j++]=EXT_PORT; //CS=0, HLD=1, WP=1
+ bufferU[j++]=HLD;
+ bufferU[j++]=WP;
+ bufferU[j++]=SPI_WRITE; //WRITE ENABLE
+ bufferU[j++]=1;
+ bufferU[j++]=6;
+ bufferU[j++]=EXT_PORT; //CS=1, HLD=1, WP=1
+ bufferU[j++]=CS+HLD;
+ bufferU[j++]=WP;
+ bufferU[j++]=EXT_PORT; //CS=0, HLD=1, WP=1
+ bufferU[j++]=HLD;
+ bufferU[j++]=WP;
+ bufferU[j++]=SPI_WRITE; //CHIP ERASE
+ bufferU[j++]=1;
+ bufferU[j++]=0xC7;
+ bufferU[j++]=EXT_PORT; //CS=1, HLD=1, WP=1
+ bufferU[j++]=CS+HLD;
+ bufferU[j++]=WP;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ j=0;
+ bufferU[j++]=EXT_PORT; //CS=0, HLD=1, WP=1
+ bufferU[j++]=HLD;
+ bufferU[j++]=WP;
+ bufferU[j++]=SPI_WRITE; //READ STATUS
+ bufferU[j++]=1;
+ bufferU[j++]=5;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=1;
+ bufferU[j++]=EXT_PORT; //CS=1, HLD=1, WP=1
+ bufferU[j++]=CS+HLD;
+ bufferU[j++]=WP;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ int pp;
+ for(pp=1,j=0;pp&&j<400;j++){ //wait for erase completion max 40s
+ PacketIO(2);
+ msDelay(100);
+ for(z=0;z<DIMBUF-1&&bufferI[z]!=SPI_READ;z++);
+ pp=bufferI[z+2]&1; //WIP bit
+ PrintStatus(strings[S_StartErase],0,0); //"Erasing ... " Also allows the gui loop to run
+ }
+ if(saveLog) fprintf(logfile,"Erase time %d ms\n",j*100);
+ PrintMessage(strings[S_Compl]); //"completed"
+ PrintStatus(strings[S_Compl],0,0); //"completed"
+// msDelay(100);
+ }
+//****************** write ********************
+ PrintMessage(strings[S_EEAreaW]); //"Write EEPROM ... "
+ if(saveLog) fprintf(logfile,"%s\n",strings[S_EEAreaW]); //"Write EEPROM ... "
+ int pp;
+ for(i=0,j=0;i<dim;i+=page){
+ if(options&0x1000){ //if chip erase skip empty pages
+ for(k=page;k==page&&i<dim-page;){
+ for(k=0;k<page;k++){ if(memEE[i+k]<0xFF) k=page;}
+ if(k==page) i+=page;
+ }
+ }
+ bufferU[j++]=EXT_PORT; //CS=0, HLD=1, WP=1
+ bufferU[j++]=HLD;
+ bufferU[j++]=WP;
+ bufferU[j++]=SPI_WRITE; //WRITE ENABLE
+ bufferU[j++]=1;
+ bufferU[j++]=6;
+ bufferU[j++]=EXT_PORT; //CS=1, HLD=1, WP=1
+ bufferU[j++]=CS+HLD;
+ bufferU[j++]=WP;
+ bufferU[j++]=EXT_PORT; //CS=0, HLD=1, WP=1
+ bufferU[j++]=HLD;
+ bufferU[j++]=WP;
+ bufferU[j++]=SPI_WRITE; //WRITE
+ if(dim>0x10000){ //24 bit address
+ bufferU[j++]=4;
+ bufferU[j++]=2;
+ bufferU[j++]=i>>16;
+ bufferU[j++]=(i>>8)&0xFF;
+ bufferU[j++]=i&0xFF;
+ }
+ else if(dim>0x200){ //16 bit address
+ bufferU[j++]=3;
+ bufferU[j++]=2;
+ bufferU[j++]=i>>8;
+ bufferU[j++]=i&0xFF;
+ }
+ else{ //8 bit address
+ bufferU[j++]=2;
+ bufferU[j++]=2+(i&0x100?8:0);
+ bufferU[j++]=i&0xFF;
+ }
+ pp=page<DIMBUF-j-4?page:DIMBUF-j-4;
+ for(k=0;k<page;){
+ bufferU[j++]=SPI_WRITE;
+ bufferU[j++]=pp;
+ for(;k<page&&pp;k++,pp--) bufferU[j++]=memEE[i+k];
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ for(z=0;z<DIMBUF-1&&bufferI[z]!=SPI_WRITE;z++);
+ if(bufferI[z+1]>=0xFA) k=i=dim+10;
+ pp=(page-k)<DIMBUF-4?page-k:DIMBUF-4;
+ j=0;
+ }
+ bufferU[j++]=EXT_PORT; //CS=1, HLD=1, WP=1
+ bufferU[j++]=CS+HLD;
+ bufferU[j++]=WP;
+
+ bufferU[j++]=EXT_PORT; //CS=0, HLD=1, WP=1
+ bufferU[j++]=HLD;
+ bufferU[j++]=WP;
+ bufferU[j++]=SPI_WRITE; //READ STATUS
+ bufferU[j++]=1;
+ bufferU[j++]=5;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=1;
+ bufferU[j++]=EXT_PORT; //CS=1, HLD=1, WP=1
+ bufferU[j++]=CS+HLD;
+ bufferU[j++]=WP;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ bufferU[j++]=EXT_PORT; //CS=0, HLD=1, WP=1
+ bufferU[j++]=HLD;
+ bufferU[j++]=WP;
+ bufferU[j++]=SPI_WRITE; //READ STATUS
+ bufferU[j++]=1;
+ bufferU[j++]=5;
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=1;
+ bufferU[j++]=EXT_PORT; //CS=1, HLD=1, WP=1
+ bufferU[j++]=CS+HLD;
+ bufferU[j++]=WP;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ for(pp=1,j=0;pp&&j<50;j++){ //wait for write completion
+ PacketIO(2);
+ for(z=0;z<DIMBUF-1&&bufferI[z]!=SPI_READ;z++);
+ pp=bufferI[z+2]&1; //WIP bit
+ }
+ PrintStatus(strings[S_CodeWriting2],i*100/(dim),i); //"Write: %d%%, addr. %04X"
+ if(RWstop) i=dim;
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,0,0); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ }
+ PrintStatusEnd();
+ PrintMessage(strings[S_Compl]); //"completed\r\n"
+//****************** verify EEPROM ********************
+ PrintMessage(strings[S_EEV]); //"Verify EEPROM ... "
+ if(saveLog) fprintf(logfile,"%s\n",strings[S_EEV]); //"Verify EEPROM ... "
+ PrintStatusSetup();
+ j=0;
+ bufferU[j++]=EXT_PORT; //CS=0, HLD=1, WP=0
+ bufferU[j++]=HLD;
+ bufferU[j++]=0;
+ bufferU[j++]=SPI_WRITE; //Read
+ if(dim>0x10000){ //24 bit address
+ bufferU[j++]=4;
+ bufferU[j++]=3;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ }
+ else if(dim>0x200){ //16 bit address
+ bufferU[j++]=3;
+ bufferU[j++]=3;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ }
+ else{ //8 bit address
+ bufferU[j++]=2;
+ bufferU[j++]=3;
+ bufferU[j++]=0;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ int i0,k2,valid;
+ k=0;
+ for(i=0,j=0;i<dim;i+=DIMBUF-4){
+ if(options&0x1000){ //skip empty space if erase before write
+ i0=i;
+ for(valid=0;!valid&&i<dim;i+=valid?0:DIMBUF-4){ //skip verification if 0xFF
+ for(k2=0;k2<DIMBUF-4&&!valid&&i+k2<dim;k2++) if(memEE[i+k2]<0xFF) valid=1;
+ }
+ if(i>=dim) break;
+ if(i>i0){ //some data was skipped; update current address
+ j=0;
+ bufferU[j++]=EXT_PORT; //CS=1, HLD=1, WP=1
+ bufferU[j++]=CS+HLD;
+ bufferU[j++]=WP;
+ bufferU[j++]=EXT_PORT; //CS=0, HLD=1, WP=0
+ bufferU[j++]=HLD;
+ bufferU[j++]=0;
+ bufferU[j++]=SPI_WRITE; //Read
+ if(dim>0x10000){ //24 bit address
+ bufferU[j++]=4;
+ bufferU[j++]=3;
+ bufferU[j++]=i>>16;
+ bufferU[j++]=(i>>8)&0xFF;
+ bufferU[j++]=i&0xFF;
+ }
+ else if(dim>0x200){ //16 bit address
+ bufferU[j++]=3;
+ bufferU[j++]=3;
+ bufferU[j++]=i>>8;
+ bufferU[j++]=i&0xFF;
+ }
+ else{ //8 bit address
+ bufferU[j++]=2;
+ bufferU[j++]=3+(i&0x100?8:0);
+ bufferU[j++]=i&0xFF;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ }
+ }
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=i<dim-(DIMBUF-4)?DIMBUF-4:dim-i;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(4);
+ for(j=0;j<DIMBUF-1&&bufferI[j]!=SPI_READ;j++);
+ if(bufferI[j]==SPI_READ&&bufferI[j+1]<0xFA){
+ for(z=0;z<bufferI[j+1]&&z<DIMBUF;z++){
+ if(memEE[i+z]!=bufferI[z+j+2]){
+ PrintMessage4(strings[S_CodeVError],i+z,i+z,memEE[i+z],bufferI[z+3]); //"Error verifying address %04X (%d), written %02X, read %02X\r\n"
+ err++;
+ }
+ }
+ }
+ PrintStatus(strings[S_CodeV2],i*100/(dim),i); //"Verify: %d%%, addr. %04X"
+ if(RWstop) i=dim;
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,err); //"i=%d, k=%d, err=%d\n"
+ }
+ if(err>=max_err) break;
+ }
+ PrintStatusEnd();
+ if(i<dim){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ReadEEErr],dim,i); //"Error reading EEPROM area, requested %d bytes, read %d\r\n"
+ }
+ PrintMessage1(strings[S_ComplErr],err); //"completed: %d errors\r\n"
+//****************** exit ********************
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ unsigned int stop=GetTickCount();
+ PrintStatusClear();
+ sprintf(str,strings[S_EndErr],(stop-start)/1000.0,err,err!=1?strings[S_ErrPlur]:strings[S_ErrSing]); //"\r\nEnd (%.2f s) %d %s\r\n\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+}
+
+struct ID_OW{
+ int id;
+ char *device;
+} OW_LIST[]={
+ {0x10,"DS1820\r\n"},
+ {0x14,"DS2430\r\n"},
+ {0x23,"DS2433\r\n"},
+ {0x28,"DS18B20\r\n"},
+ {0x2D,"DS2431\r\n"},
+ {0x43,"DS28EC20\r\n"},
+};
+
+void OW_ID(int id)
+{
+ char s[64];
+ int i;
+ for(i=0;i<sizeof(OW_LIST)/sizeof(OW_LIST[0]);i++){
+ if(id==OW_LIST[i].id){
+ sprintf(s,OW_LIST[i].device,id);
+ PrintMessage(s);
+ return;
+ }
+ }
+ sprintf(s,"%s",strings[S_nodev]); //"Unknown device\r\n");
+ PrintMessage(s);
+}
+
+#define READ_ROM 0x33
+#define MATCH_ROM 0x55
+#define SKIP_ROM 0xCC
+#define SEARCH_ROM 0xF0
+#define WRITE_SCRATCHPAD 0x0F
+#define READ_SCRATCHPAD 0xAA
+#define COPY_SCRATCHPAD 0x55
+#define READ_MEMORY 0xF0
+#define WRITE_APP_REGISTER 0x99
+#define READ_STAT_REGISTER 0x66
+#define READ_APP_REGISTER 0xC3
+#define COPY_LOCK_APP_REGISTER 0x5A
+
+void ReadOneWireMem(int dim,int options)
+// read OneWire memories
+// dim=size in bytes
+// options:
+// 1=status register + application register
+// 2=protection bytes + ID after memory area
+{
+ int k=0,z=0,i,j;
+ hvreg=0;
+ if(FWVersion<0x800){
+ PrintMessage1(strings[S_FWver2old],"0.8.0"); //"This firmware is too old. Version %s is required\r\n"
+ return;
+ }
+ if(dim>0x10000||dim<0){
+ PrintMessage(strings[S_EELim]); //"EEPROM size out of limits\r\n"
+ return;
+ }
+ if(saveLog){
+ OpenLogFile(); //"Log.txt"
+ fprintf(logfile,"ReadOneWireMem(%d) (0x%X)\n",dim,dim);
+ }
+ sizeEE=dim;
+ if(memEE) free(memEE);
+ memEE=(unsigned char*)malloc(dim); //EEPROM
+ unsigned int start=GetTickCount();
+ j=0;
+ bufferU[j++]=VREG_DIS;
+ bufferU[j++]=uW_INIT; //set RB1=0 to use as GND terminal beside RB0
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=OW_RESET;
+ bufferU[j++]=OW_WRITE;
+ bufferU[j++]=1;
+ bufferU[j++]=READ_ROM;
+ bufferU[j++]=OW_READ;
+ bufferU[j++]=8;
+ if(dim<=32){ //1 byte address
+ bufferU[j++]=OW_WRITE;
+ bufferU[j++]=2;
+ bufferU[j++]=READ_MEMORY;
+ bufferU[j++]=0; //address
+ }
+ else{ //2 byte address
+ bufferU[j++]=OW_WRITE;
+ bufferU[j++]=3;
+ bufferU[j++]=READ_MEMORY;
+ bufferU[j++]=0; //address
+ bufferU[j++]=0; //address
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(12);
+ j=0;
+ for(z=0;bufferI[z]!=OW_RESET&&z<DIMBUF;z++);
+ if(bufferI[z]==OW_RESET&&bufferI[z+1]==0){ //no presence pulse
+ PrintMessage(strings[S_ComErr]); //communication error
+ bufferU[j++]=EN_VPP_VCC; //turn off
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ return;
+ }
+ for(;bufferI[z]!=OW_READ&&z<DIMBUF;z++);
+ if(bufferI[z]==OW_READ&&z<DIMBUF-9){
+ PrintMessage1("Family code: 0x%02X ",bufferI[z+2]);
+ OW_ID(bufferI[z+2]);
+ PrintMessage3("Serial ID: 0x%02X%02X%02X",bufferI[z+3],bufferI[z+4],bufferI[z+5]);
+ PrintMessage3("%02X%02X%02X",bufferI[z+6],bufferI[z+7],bufferI[z+8]);
+ PrintMessage1("\r\nCRC: 0x%02X\r\n",bufferI[z+9]);
+ }
+//****************** read ********************
+ PrintStatusSetup();
+ for(i=0,j=0;i<dim;i+=DIMBUF-4){
+ bufferU[j++]=OW_READ;
+ bufferU[j++]=i<dim-(DIMBUF-4)?DIMBUF-4:dim-i;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(37);
+ for(j=0;bufferI[j]!=OW_READ&&j<DIMBUF;j++);
+ if(bufferI[j]==OW_READ&&bufferI[j+1]<0xFA){
+ for(z=j+2;z<j+2+bufferI[j+1]&&z<DIMBUF;z++) memEE[k++]=bufferI[z];
+ }
+ PrintStatus(strings[S_CodeReading2],i*100/(dim),i); //"Read: %d%%, addr. %05X"
+ if(RWstop) i=dim;
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k,k); //"i=%d(0x%X), k=%d(0x%X) \n"
+ }
+ }
+ if(options==1){ //read status register + application register
+ bufferU[j++]=OW_RESET;
+ bufferU[j++]=OW_WRITE;
+ bufferU[j++]=3;
+ bufferU[j++]=SKIP_ROM;
+ bufferU[j++]=READ_STAT_REGISTER;
+ bufferU[j++]=0;
+ bufferU[j++]=OW_READ;
+ bufferU[j++]=1;
+ bufferU[j++]=OW_RESET;
+ bufferU[j++]=OW_WRITE;
+ bufferU[j++]=3;
+ bufferU[j++]=SKIP_ROM;
+ bufferU[j++]=READ_APP_REGISTER;
+ bufferU[j++]=0;
+ bufferU[j++]=OW_READ;
+ bufferU[j++]=8;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(15);
+ j=0;
+ for(z=0;bufferI[z]!=OW_READ&&z<DIMBUF-2;z++);
+ if(z<DIMBUF-2) PrintMessage1("Status register: 0x%02X\r\n",bufferI[z+2]);
+ for(z+=2;bufferI[z]!=OW_READ&&z<DIMBUF-10;z++);
+ PrintMessage("Application register: 0x");
+ for(i=z+2;i<z+10&&i<DIMBUF;i++) PrintMessage1("%02X",bufferI[i]);
+ PrintMessage("\r\n");
+ }
+ else if(options==2){ //read protection & ID bytes
+ bufferU[j++]=OW_READ;
+ if(dim==0xA00) bufferU[j++]=0x24;
+ else bufferU[j++]=8;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(25);
+ j=0;
+ for(z=0;bufferI[z]!=OW_READ&&z<DIMBUF-2;z++);
+ if(bufferI[z]==OW_READ&&bufferI[z+1]<0xFA){
+ if(dim==0xA00){
+ for(i=0;i<10;i++) PrintMessage2("Protection Control Byte Block %d: 0x%02X\r\n",i,bufferI[z+2+i]);
+ PrintMessage("User EEPROM:\r\n");
+ for(i=0;i<10;i++) PrintMessage1("%02X",bufferI[z+2+i+10]);
+ PrintMessage("\r\n");
+ for(i=0;i<10;i++) PrintMessage1("%02X",bufferI[z+2+i+20]);
+ PrintMessage1("\r\nMemory Block Lock: 0x%02X\r\n",bufferI[z+2+30]);
+ PrintMessage1("Register Page Lock: 0x%02X\r\n",bufferI[z+2+31]);
+ PrintMessage1("Factory Byte: 0x%02X\r\n",bufferI[z+2+32]);
+ PrintMessage2("Factory Trim Bytes: 0x%02X%02X\r\n",bufferI[z+2+33],bufferI[z+2+34]);
+ PrintMessage2("Manufacturer ID: 0x%02X%02X\r\n",bufferI[z+2+35],bufferI[z+2+36]);
+ }
+ else{
+ PrintMessage1("Protection Control Byte Page 0: 0x%02X\r\n",bufferI[z+2]);
+ PrintMessage1("Protection Control Byte Page 1: 0x%02X\r\n",bufferI[z+2+1]);
+ PrintMessage1("Protection Control Byte Page 2: 0x%02X\r\n",bufferI[z+2+2]);
+ PrintMessage1("Protection Control Byte Page 3: 0x%02X\r\n",bufferI[z+2+3]);
+ PrintMessage1("Copy Protection Byte: 0x%02X\r\n",bufferI[z+2+4]);
+ PrintMessage1("Factory Byte: 0x%02X\r\n",bufferI[z+2+5]);
+ PrintMessage2("User Bytes/Manufacturer ID: 0x%02X%02X\r\n",bufferI[z+2+6],bufferI[z+2+7]);
+ }
+ }
+ }
+ PrintStatusEnd();
+ if(k!=dim){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ReadEEErr],dim,k); //"Error reading EEPROM area, requested %d bytes, read %d\r\n"
+ sizeEE=k;
+ }
+//****************** exit ********************
+ bufferU[j++]=EN_VPP_VCC; //turn off
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ unsigned int stop=GetTickCount();
+ PrintStatusClear();
+ DisplayEE(); //visualize
+ int sum=0;
+ for(i=0;i<sizeEE;i++) sum+=memEE[i];
+ PrintMessage1("Checksum: 0x%X\r\n",sum&0xFFFF);
+ sprintf(str,strings[S_End],(stop-start)/1000.0); //"\r\nEnd (%.2f s)\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+}
+
+void WriteOneWireMem(int dim,int options)
+// write OneWire memories
+// dim=size in bytes
+// options:
+// 0 = 8 byte scratchpad
+// 1 = 32 byte scratchpad
+{
+ int k=0,z=0,i,j;
+ int err=0;
+ hvreg=0;
+ if(FWVersion<0x800){
+ PrintMessage1(strings[S_FWver2old],"0.8.0"); //"This firmware is too old. Version %s is required\r\n"
+ return;
+ }
+ if(dim>0x10000||dim<0){
+ PrintMessage(strings[S_EELim]); //"EEPROM size out of limits\r\n"
+ return;
+ }
+ if(saveLog){
+ OpenLogFile(); //"Log.txt"
+ fprintf(logfile,"WriteOneWireMem(%d,%d) (0x%X,0x%X)\n",dim,options,dim,options);
+ }
+ if(dim>sizeEE){
+ i=sizeEE;
+ memEE=(unsigned char*)realloc(memEE,dim);
+ for(;i<dim;i++) memEE[i]=0xFF;
+ sizeEE=dim;
+ }
+ if(dim<1){
+ PrintMessage(strings[S_NoCode]); //"Data area is empty\r\n"
+ return;
+ }
+ unsigned int start=GetTickCount();
+ j=0;
+ bufferU[j++]=VREG_DIS;
+ bufferU[j++]=uW_INIT; //set RB1=0 to use as GND terminal beside RB0
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=OW_RESET;
+ bufferU[j++]=OW_WRITE;
+ bufferU[j++]=1;
+ bufferU[j++]=READ_ROM;
+ bufferU[j++]=OW_READ;
+ bufferU[j++]=8;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(12);
+ j=0;
+ for(z=0;bufferI[z]!=OW_RESET&&z<DIMBUF;z++);
+ if(bufferI[z]==OW_RESET&&bufferI[z+1]==0){ //no presence pulse
+ PrintMessage(strings[S_ComErr]); //communication error
+ bufferU[j++]=EN_VPP_VCC; //turn off
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ if(saveLog) CloseLogFile();
+ return;
+ }
+ for(z=0;bufferI[z]!=OW_READ&&z<DIMBUF;z++);
+ if(bufferI[z]==OW_READ){
+ PrintMessage1("Family code: 0x%02X ",bufferI[z+2]);
+ OW_ID(bufferI[z+2]);
+ PrintMessage3("Serial ID: 0x%02X%02X%02X",bufferI[z+3],bufferI[z+4],bufferI[z+5]);
+ PrintMessage3("%02X%02X%02X",bufferI[z+6],bufferI[z+7],bufferI[z+8]);
+ PrintMessage1("\r\nCRC: 0x%02X\r\n",bufferI[z+9]);
+ }
+//****************** write ********************
+ PrintMessage(strings[S_EEAreaW]); //"Write EEPROM ... "
+ int page=options==0?8:32;
+ for(i=0,j=0;i<dim;i+=page){
+ bufferU[j++]=OW_RESET;
+ bufferU[j++]=OW_WRITE;
+ bufferU[j++]=page+(dim<=32?3:4);
+ bufferU[j++]=SKIP_ROM;
+ bufferU[j++]=WRITE_SCRATCHPAD;
+ bufferU[j++]=i&0xFF;
+ if(dim>32) bufferU[j++]=i>>8;
+ for(k=0;k<page;k++) bufferU[j++]=memEE[i+k];
+ bufferU[j++]=OW_RESET;
+ bufferU[j++]=OW_WRITE;
+ bufferU[j++]=dim<=32?3:5;
+ bufferU[j++]=SKIP_ROM;
+ bufferU[j++]=COPY_SCRATCHPAD;
+ if(dim<=32) bufferU[j++]=0xA5;
+ else{
+ bufferU[j++]=i&0xFF;
+ bufferU[j++]=i>>8;
+ bufferU[j++]=page-1;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(6+0.8*page);
+ msDelay(10); //TPROG
+ j=0;
+ PrintStatus(strings[S_CodeWriting2],i*100/(dim),i); //"Write: %d%%, addr. %04X"
+ if(RWstop) i=dim;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,0,0); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ }
+ PrintStatusEnd();
+ PrintMessage(strings[S_Compl]); //"completed\r\n"
+//****************** verify EEPROM ********************
+ PrintMessage(strings[S_EEV]); //"Verify EEPROM ... "
+ if(saveLog) fprintf(logfile,"%s\n",strings[S_EEV]); //"Verify EEPROM ... "
+ PrintStatusSetup();
+ k=0;
+ bufferU[j++]=OW_RESET;
+ bufferU[j++]=OW_WRITE;
+ bufferU[j++]=1;
+ bufferU[j++]=SKIP_ROM;
+ if(dim<=32){ //1 byte address
+ bufferU[j++]=OW_WRITE;
+ bufferU[j++]=2;
+ bufferU[j++]=READ_MEMORY;
+ bufferU[j++]=0; //address
+ }
+ else{ //2 byte address
+ bufferU[j++]=OW_WRITE;
+ bufferU[j++]=3;
+ bufferU[j++]=READ_MEMORY;
+ bufferU[j++]=0; //address
+ bufferU[j++]=0; //address
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(10);
+ j=0;
+ for(i=0,j=0;i<dim;i+=DIMBUF-4){
+ bufferU[j++]=OW_READ;
+ bufferU[j++]=i<dim-(DIMBUF-4)?DIMBUF-4:dim-i;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(37);
+ for(j=0;bufferI[j]!=OW_READ&&j<DIMBUF;j++);
+ if(bufferI[j]==OW_READ&&bufferI[j+1]<0xFA){
+ for(z=j+2;z<j+2+bufferI[j+1]&&z<DIMBUF;z++){
+ if(memEE[k++]!=bufferI[z]){
+ PrintMessage("\r\n");
+ PrintMessage4(strings[S_CodeVError],i+z-(j+2),i+z-(j+2),memEE[k-1],bufferI[z]); //"Error verifying address %04X (%d), written %02X, read %02X\r\n"
+ err++;
+ }
+ }
+ }
+ PrintStatus(strings[S_CodeV2],i*100/(dim),i); //"Verify: %d%%, addr. %04X"
+ if(RWstop) i=dim;
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,err); //"i=%d, k=%d, err=%d\n"
+ }
+ if(err>=max_err) break;
+ }
+ PrintStatusEnd();
+ if(k!=dim){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ReadEEErr],dim,k); //"Error reading EEPROM area, requested %d bytes, read %d\r\n"
+ sizeEE=k;
+ }
+ PrintMessage1(strings[S_ComplErr],err); //"completed: %d errors\r\n"
+//****************** exit ********************
+ bufferU[j++]=EN_VPP_VCC; //turn off
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ unsigned int stop=GetTickCount();
+ PrintStatusClear();
+ sprintf(str,strings[S_EndErr],(stop-start)/1000.0,err,err!=1?strings[S_ErrPlur]:strings[S_ErrSing]); //"\r\nEnd (%.2f s) %d %s\r\n\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+}
+
+#define READ_SCRATCHPAD2 0xBE
+#define CONVERT_TEMP 0x44
+#define RECALL_EE 0xB8
+#define READ_PWSUP 0xB4
+
+void ReadDS1820()
+// read DS1820 one-wire digital thermometer
+{
+ int z=0,j;
+ double TLSB=0.5;
+ hvreg=0;
+ if(FWVersion<0x800){
+ PrintMessage1(strings[S_FWver2old],"0.8.0"); //"This firmware is too old. Version %s is required\r\n"
+ return;
+ }
+ if(saveLog){
+ OpenLogFile(); //"Log.txt"
+ fprintf(logfile,"ReadDS1820()\n");
+ }
+ unsigned int start=GetTickCount();
+ j=0;
+ bufferU[j++]=VREG_DIS;
+ bufferU[j++]=uW_INIT; //set RB1=0 to use as GND terminal beside RB0
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=OW_RESET;
+ bufferU[j++]=OW_WRITE;
+ bufferU[j++]=1;
+ bufferU[j++]=READ_ROM;
+ bufferU[j++]=OW_READ;
+ bufferU[j++]=8;
+ bufferU[j++]=OW_RESET;
+ bufferU[j++]=OW_WRITE;
+ bufferU[j++]=2;
+ bufferU[j++]=SKIP_ROM;
+ bufferU[j++]=CONVERT_TEMP;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(16);
+ j=0;
+ for(z=0;bufferI[z]!=OW_RESET&&z<DIMBUF;z++);
+ if(bufferI[z]==OW_RESET&&bufferI[z+1]==0){ //no presence pulse
+ PrintMessage(strings[S_ComErr]); //communication error
+ bufferU[j++]=EN_VPP_VCC; //turn off
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ if(saveLog) CloseLogFile();
+ return;
+ }
+ for(z=0;bufferI[z]!=OW_READ&&z<DIMBUF;z++);
+ if(z<DIMBUF-9){
+ PrintMessage1("Family code: 0x%02X ",bufferI[z+2]);
+ OW_ID(bufferI[z+2]);
+ if(bufferI[z+2]==0x10) TLSB=0.5; //DS1820
+ else if(bufferI[z+2]==0x28) TLSB=0.0625; //DS18B20
+ PrintMessage3("Serial ID: 0x%02X%02X%02X",bufferI[z+3],bufferI[z+4],bufferI[z+5]);
+ PrintMessage3("%02X%02X%02X",bufferI[z+6],bufferI[z+7],bufferI[z+8]);
+ PrintMessage1("\r\nCRC: 0x%02X\r\n",bufferI[z+9]);
+ }
+//****************** read ********************
+ msDelay(800);
+ bufferU[j++]=OW_RESET;
+ bufferU[j++]=OW_WRITE;
+ bufferU[j++]=2;
+ bufferU[j++]=SKIP_ROM;
+ bufferU[j++]=READ_SCRATCHPAD2;
+ bufferU[j++]=OW_READ;
+ bufferU[j++]=8;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(10);
+ j=0;
+ for(z=0;bufferI[z]!=OW_READ&&z<DIMBUF-2;z++);
+ //PrintMessage("0x");
+ //for(i=z+2;i<z+10&&i<DIMBUF;i++) PrintMessage1("%02X",bufferI[i]);
+ //PrintMessage("\r\n");
+ int T=bufferI[z+2]+(bufferI[z+3]<<8);
+ if(T>0xF000) T|=0xFFFF0000; //adjust negative value
+#ifdef _MSC_VER
+ PrintMessage2("T=%.4f°C (0x%04X)\r\n",T*TLSB,T);
+#else
+ PrintMessage2("T=%.4f°C (0x%04X)\r\n",T*TLSB,T);
+#endif
+//****************** exit ********************
+ bufferU[j++]=EN_VPP_VCC; //turn off
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ unsigned int stop=GetTickCount();
+ sprintf(str,strings[S_End],(stop-start)/1000.0); //"\r\nEnd (%.2f s)\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+}
+
+
+#define UNIO_READ 0x03
+#define UNIO_CRRD 0x06
+#define UNIO_WRITE 0x6C
+#define UNIO_WREN 0x96
+#define UNIO_WRDI 0x91
+#define UNIO_RDSR 0x05
+#define UNIO_WRSR 0x6E
+#define UNIO_ERAL 0x6D
+#define UNIO_SETAL 0x67
+
+void Read11xx(int dim)
+// read 11xx UNIO memories
+// dim=size in bytes
+{
+ int k=0,z=0,i,j;
+ hvreg=0;
+ if(FWVersion<0x800){
+ PrintMessage1(strings[S_FWver2old],"0.8.0"); //"This firmware is too old. Version %s is required\r\n"
+ return;
+ }
+ if(dim>=0x10000||dim<0){
+ PrintMessage(strings[S_EELim]); //"EEPROM size out of limits\r\n"
+ return;
+ }
+ if(saveLog){
+ OpenLogFile(); //"Log.txt"
+ fprintf(logfile,"Read11xx(%d) (0x%X)\n",dim,dim);
+ }
+ sizeEE=dim;
+ if(memEE) free(memEE);
+ memEE=(unsigned char*)malloc(dim); //EEPROM
+ unsigned int start=GetTickCount();
+ j=0;
+ bufferU[j++]=VREG_DIS;
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=UNIO_COM;
+ bufferU[j++]=2; //write x bytes
+ bufferU[j++]=1; //read x bytes
+ bufferU[j++]=0xA0;
+ bufferU[j++]=UNIO_RDSR;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+//****************** read ********************
+ PrintMessage(strings[S_ReadEE]); //read EEPROM ...
+ PrintStatusSetup();
+ for(i=0,j=0;i<dim;i+=DIMBUF-5){
+ bufferU[j++]=UNIO_COM;
+ bufferU[j++]=4; //write x bytes
+ bufferU[j++]=i<dim-(DIMBUF-5)?DIMBUF-5:dim-i; //read x bytes
+ bufferU[j++]=0xA0;
+ bufferU[j++]=UNIO_READ;
+ bufferU[j++]=i>>8;
+ bufferU[j++]=i&0xFF;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(14);
+ for(j=0;j<DIMBUF-1&&bufferI[j]!=UNIO_COM;j++);
+ if(bufferI[j]==UNIO_COM&&bufferI[j+1]<0xFA){
+ for(z=j+2;z<j+2+bufferI[j+1]&&z<DIMBUF;z++) memEE[k++]=bufferI[z];
+ }
+ PrintStatus(strings[S_CodeReading2],i*100/(dim),i); //"Read: %d%%, addr. %05X"
+ if(RWstop) i=dim;
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k,k); //"i=%d(0x%X), k=%d(0x%X) \n"
+ }
+ }
+ PrintStatusEnd();
+ if(k!=dim){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ReadEEErr],dim,k); //"Error reading EEPROM area, requested %d bytes, read %d\r\n"
+ sizeEE=k;
+ }
+ else PrintMessage(strings[S_Compl]);
+//****************** exit ********************
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ unsigned int stop=GetTickCount();
+ PrintStatusClear();
+ DisplayEE(); //visualize
+ int sum=0;
+ for(i=0;i<sizeEE;i++) sum+=memEE[i];
+ PrintMessage1("Checksum: 0x%X\r\n",sum&0xFFFF);
+ sprintf(str,strings[S_End],(stop-start)/1000.0); //"\r\nEnd (%.2f s)\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+}
+
+void Write11xx(int dim,int page)
+// write 11xx UNIO memories
+// dim=size in bytes
+// page=page size
+{
+ int k=0,z=0,i,j;
+ int err=0;
+ if(FWVersion<0x800){
+ PrintMessage1(strings[S_FWver2old],"0.8.0"); //"This firmware is too old. Version %s is required\r\n"
+ return;
+ }
+ hvreg=0;
+ if(dim>=0x10000||dim<0){
+ PrintMessage(strings[S_EELim]); //"EEPROM size out of limits\r\n"
+ return;
+ }
+ if(saveLog){
+ OpenLogFile(); //"Log.txt"
+ fprintf(logfile,"Write11xx(%d,%d) (0x%X,0x%X)\n",dim,page,dim,page);
+ }
+ if(dim>sizeEE){
+ i=sizeEE;
+ memEE=(unsigned char*)realloc(memEE,dim);
+ for(;i<dim;i++) memEE[i]=0xFF;
+ sizeEE=dim;
+ }
+ if(dim<1){
+ PrintMessage(strings[S_NoCode]); //"Data area is empty\r\n"
+ return;
+ }
+ unsigned int start=GetTickCount();
+ j=0;
+ bufferU[j++]=VREG_DIS;
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=UNIO_STBY;
+ bufferU[j++]=UNIO_COM;
+ bufferU[j++]=2; //write x bytes
+ bufferU[j++]=0; //read x bytes
+ bufferU[j++]=0xA0;
+ bufferU[j++]=UNIO_WREN;
+ bufferU[j++]=UNIO_COM;
+ bufferU[j++]=2; //write x bytes
+ bufferU[j++]=1; //read x bytes
+ bufferU[j++]=0xA0;
+ bufferU[j++]=UNIO_RDSR;
+ bufferU[j++]=UNIO_COM;
+ bufferU[j++]=3; //write x bytes
+ bufferU[j++]=0; //read x bytes
+ bufferU[j++]=0xA0;
+ bufferU[j++]=UNIO_WRSR;
+ bufferU[j++]=0;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=UNIO_COM;
+ bufferU[j++]=2; //write x bytes
+ bufferU[j++]=1; //read x bytes
+ bufferU[j++]=0xA0;
+ bufferU[j++]=UNIO_RDSR;
+ bufferU[j++]=UNIO_COM;
+ bufferU[j++]=2; //write x bytes
+ bufferU[j++]=0; //read x bytes
+ bufferU[j++]=0xA0;
+ bufferU[j++]=UNIO_WREN;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(25);
+//****************** write ********************
+ PrintMessage(strings[S_EEAreaW]); //"Write EEPROM ... "
+ PrintStatusSetup();
+ for(;page>=DIMBUF-8;page>>=1);
+ for(i=0,j=0;i<dim;i+=page){
+ bufferU[j++]=UNIO_COM;
+ bufferU[j++]=4+page; //write x bytes
+ bufferU[j++]=0; //read x bytes
+ bufferU[j++]=0xA0;
+ bufferU[j++]=UNIO_WRITE;
+ bufferU[j++]=i>>8;
+ bufferU[j++]=i&0xFF;
+ for(k=0;k<page;k++) bufferU[j++]=memEE[i+k];
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO((5+page)*0.2+2);
+ for(j=0;j<DIMBUF-1&&bufferI[j]!=UNIO_COM;j++);
+ if(bufferI[j]!=UNIO_COM||bufferI[j+1]>=0xFA) i=dim+10;
+ PrintStatus(strings[S_CodeWriting2],i*100/(dim),i); //"Write: %d%%, addr. %04X"
+ if(RWstop) i=dim;
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k,k); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ bufferU[j++]=UNIO_COM;
+ bufferU[j++]=2; //write x bytes
+ bufferU[j++]=1; //read x bytes
+ bufferU[j++]=0xA0;
+ bufferU[j++]=UNIO_RDSR;
+ bufferU[j++]=UNIO_COM;
+ bufferU[j++]=2; //write x bytes
+ bufferU[j++]=0; //read x bytes
+ bufferU[j++]=0xA0;
+ bufferU[j++]=UNIO_WREN;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ int status=1;
+ for(k=0;status&&k<20;k++){ //status polling until write complete
+ PacketIO(2);
+ for(j=0;j<DIMBUF-1&&bufferI[j]!=UNIO_COM;j++);
+ if(bufferI[j]==UNIO_COM) status=bufferI[j+2]&1;
+ }
+ j=0;
+ }
+ PrintStatusEnd();
+ PrintMessage(strings[S_Compl]); //"completed\r\n"
+//****************** verify EEPROM ********************
+ PrintMessage(strings[S_EEV]); //"Verify EEPROM ... "
+ PrintStatusSetup();
+ k=0;
+ for(i=0,j=0;i<dim;i+=DIMBUF-4){
+ bufferU[j++]=UNIO_COM;
+ bufferU[j++]=4; //write x bytes
+ bufferU[j++]=i<dim-(DIMBUF-4)?DIMBUF-4:dim-i; //read x bytes
+ bufferU[j++]=0xA0;
+ bufferU[j++]=UNIO_READ;
+ bufferU[j++]=i>>8;
+ bufferU[j++]=i&0xFF;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(14);
+ for(j=0;j<DIMBUF-1&&bufferI[j]!=UNIO_COM;j++);
+ if(bufferI[j]==UNIO_COM&&bufferI[j+1]<0xFA){
+ for(z=j+2;z<j+2+bufferI[j+1]&&z<DIMBUF;z++){
+ if(memEE[k++]!=bufferI[z]){
+ PrintMessage("\r\n");
+ PrintMessage4(strings[S_CodeVError],i+z-3,i+z-3,memEE[k-1],bufferI[z]); //"Error verifying address %04X (%d), written %02X, read %02X\r\n"
+ err++;
+ }
+ }
+ }
+ PrintStatus(strings[S_CodeV2],i*100/(dim),i); //"Verify: %d%%, addr. %04X"
+ if(RWstop) i=dim;
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,err); //"i=%d, k=%d, err=%d\n"
+ }
+ if(err>=max_err) break;
+ }
+ PrintStatusEnd();
+ if(k!=dim){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ReadEEErr],dim,k); //"Error reading EEPROM area, requested %d bytes, read %d\r\n"
+ }
+ PrintMessage1(strings[S_ComplErr],err); //"completed: %d errors\r\n"
+//****************** exit ********************
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ unsigned int stop=GetTickCount();
+ PrintStatusClear();
+ sprintf(str,strings[S_EndErr],(stop-start)/1000.0,err,err!=1?strings[S_ErrPlur]:strings[S_ErrSing]); //"\r\nEnd (%.2f s) %d %s\r\n\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+}
diff --git a/progEEPROM.h b/progEEPROM.h
new file mode 100644
index 0000000..bcd50d2
--- /dev/null
+++ b/progEEPROM.h
@@ -0,0 +1,12 @@
+void ReadI2C(int dim,int addr);
+void WriteI2C(int dim,int addr,int page);
+void Read93x(int dim,int na,int options);
+void Write93Sx(int dim,int na,int page);
+void Write93Cx(int dim,int na, int options);
+void Read25xx(int dim);
+void Write25xx(int dim,int options);
+void ReadOneWireMem(int dim,int options);
+void WriteOneWireMem(int dim,int options);
+void ReadDS1820();
+void Read11xx(int dim);
+void Write11xx(int dim,int page);
diff --git a/progP12.c b/progP12.c
new file mode 100644
index 0000000..f86a44a
--- /dev/null
+++ b/progP12.c
@@ -0,0 +1,666 @@
+/**
+ * \file progP12.c - algorithms to program the PIC12 (12 bit word) family of microcontrollers
+ * Copyright (C) 2009-2016 Alberto Maccioni
+ *
+ * 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"
+
+void Read12F5xx(int dim,int dim2)
+// read 12 bit PIC
+// dim=program size dim2=config size
+// vdd before vpp
+// CONFIG @ 0x7FF (upon entering in program mode)
+// OSCCAL in last memory location
+// 4 ID + reserved area beyond code memory
+{
+ int k=0,z=0,i,j;
+ char s[256],t[256];
+ if(dim2<4) dim2=4;
+ sizeW=0x1000;
+ if(memCODE_W) free(memCODE_W);
+ memCODE_W=(WORD*)malloc(sizeof(WORD)*sizeW);
+ if(saveLog){
+ OpenLogFile(); //"Log.txt"
+ fprintf(logfile,"Read12F5xx(%d,%d)\n",dim,dim2);
+ }
+ unsigned int start=GetTickCount();
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T1T2;
+ bufferU[j++]=1; //T1=1u
+ bufferU[j++]=100; //T2=100u
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2000>>8;
+ bufferU[j++]=2000&0xff;
+ bufferU[j++]=EN_VPP_VCC; //enter program mode
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC; //VDD+VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=NOP;
+ bufferU[j++]=READ_DATA_PROG; //configuration word
+ bufferU[j++]=INC_ADDR; // 7FF->000
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ for(z=0;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if(z<DIMBUF-2){
+ memCODE_W[0xfff]=(bufferI[z+1]<<8)+bufferI[z+2];
+ PrintMessage("\r\n");
+ PrintMessage1(strings[S_ConfigWord],memCODE_W[0xfff]); //"\r\nConfiguration word: 0x%03X\r\n"
+ switch(memCODE_W[0xfff]&0x03){
+ case 0:
+ PrintMessage(strings[S_LPOsc]); //"LP oscillator\r\n"
+ break;
+ case 1:
+ PrintMessage(strings[S_XTOsc]); //"XT oscillator\r\n"
+ break;
+ case 2:
+ PrintMessage(strings[S_IntOsc]); //"Internal osc.\r\n"
+ break;
+ case 3:
+ PrintMessage(strings[S_RCOsc]); //"RC oscillator\r\n"
+ break;
+ }
+ if(memCODE_W[0xfff]&0x04) PrintMessage(strings[S_WDTON]); //"WDT ON\r\n"
+ else PrintMessage(strings[S_WDTOFF]); //"WDT OFF\r\n"
+ if(memCODE_W[0xfff]&0x08) PrintMessage(strings[S_CPOFF]); //"Code protection OFF\r\n"
+ else PrintMessage(strings[S_CPON]); //"Code protection ON\r\n"
+ if(memCODE_W[0xfff]&0x10) PrintMessage(strings[S_MCLRON]); //"Master clear ON\r\n"
+ else PrintMessage(strings[S_MCLROFF]); //"Master clear OFF\r\n"
+ }
+ else PrintMessage(strings[S_NoConfigW]); //"Impossible to read config word\r\n"
+//****************** read code ********************
+ PrintMessage(strings[S_CodeReading1]); //reading code ...
+ PrintStatusSetup();
+ for(i=0,j=0;i<dim+dim2;i++){
+ bufferU[j++]=READ_DATA_PROG;
+ bufferU[j++]=INC_ADDR;
+ if(j>DIMBUF*2/4-3||i==dim+dim2-1){ //2 ins -> 4 ans
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ for(z=0;z<DIMBUF-2;z++){
+ if(bufferI[z]==READ_DATA_PROG){
+ memCODE_W[k++]=(bufferI[z+1]<<8)+bufferI[z+2];
+ z+=2;
+ }
+ }
+ PrintStatus(strings[S_CodeReading],i*100/(dim+dim2),i); //"Read: %d%%, addr. %03X"
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k,k); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ }
+ }
+ PrintStatusEnd();
+ bufferU[j++]=NOP; //exit program mode
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(1);
+ unsigned int stop=GetTickCount();
+ for(i=k;i<0xfff;i++) memCODE_W[i]=0xfff;
+ if(k!=dim+dim2){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ReadErr],dim+dim2,k); //"Error reading, requested %d words, read %d\r\n"
+ }
+ else PrintMessage(strings[S_Compl]);
+//****************** visualize ********************
+ for(i=0;i<4;i+=2){
+ PrintMessage4(strings[S_ChipID],i,memCODE_W[dim+i],i+1,memCODE_W[dim+i+1]); //"ID%d: 0x%03X ID%d: 0x%03X\r\n"
+ }
+ if(dim2>4){
+ PrintMessage1(strings[S_BKOsccal],memCODE_W[dim+4]); //"Backup OSCCAL: 0x%03X\r\n"
+ }
+ PrintMessage(strings[S_CodeMem]); //"\r\nCode memory\r\n"
+ s[0]=0;
+ int valid=0,empty=1;
+ char* aux=(char*)malloc((dim/COL+1)*(16+COL*5));
+ aux[0]=0;
+ for(i=0;i<dim;i+=COL){
+ valid=0;
+ for(j=i;j<i+COL&&j<dim;j++){
+ sprintf(t,"%03X ",memCODE_W[j]);
+ strcat(s,t);
+ if(memCODE_W[j]<0xfff) valid=1;
+ }
+ if(valid){
+ sprintf(t,"%04X: %s\r\n",i,s);
+ empty=0;
+ strcat(aux,t);
+ }
+ s[0]=0;
+ }
+ if(empty) PrintMessage(strings[S_Empty]); //empty
+ else PrintMessage(aux);
+ free(aux);
+ if(dim2>5){
+ aux=(char*)malloc((dim2/COL+1)*(16+COL*5));
+ aux[0]=0;
+ s[0]=0;
+ PrintMessage(strings[S_ConfigResMem]); //"\r\nConfig and reserved memory:\r\n"
+ empty=1;
+ for(i=dim;i<dim+dim2;i+=COL){
+ valid=0;
+ for(j=i;j<i+COL&&j<dim+64;j++){
+ sprintf(t,"%03X ",memCODE_W[j]);
+ strcat(s,t);
+ if(memCODE_W[j]<0xfff) valid=1;
+ }
+ if(valid){
+ sprintf(t,"%04X: %s\r\n",i,s);
+ empty=0;
+ strcat(aux,t);
+ }
+ s[0]=0;
+ }
+ if(empty) PrintMessage(strings[S_Empty]); //empty
+ else PrintMessage(aux);
+ free(aux);
+ }
+ sprintf(str,strings[S_End],(stop-start)/1000.0); //"\r\nEnd (%.2f s)\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+ PrintStatusClear(); //clear status report
+}
+
+void Write12F5xx(int dim,int OscAddr)
+{
+// write 12 bit PIC
+// dim=program size max~4300=10CC
+// OscAddr=OSCCAL address (saved at the beginning), -1 not to use it
+// vdd before vpp
+// CONFIG @ 0x7FF upon entering program mode
+// BACKUP OSCCAL @ dim+5 (saved at the beginning)
+// erase: BULK_ERASE_PROG (1001) +10ms
+// write: BEGIN_PROG (1000) + Tprogram 2ms + END_PROG2 (1110);
+ int k=0,z=0,i,j,w;
+ int err=0;
+ WORD osccal=-1,BKosccal=-1;
+ if(OscAddr>dim) OscAddr=dim-1;
+ if(OscAddr==-1) use_BKosccal=use_osccal=0;
+ if(sizeW<0x1000){
+ PrintMessage(strings[S_NoConfigW2]); //"Can't find CONFIG (0xFFF)\r\n"
+ return;
+ }
+ if(saveLog){
+ OpenLogFile(); //"Log.txt"
+ fprintf(logfile,"Write12F5xx(%d,%d)\n",dim,OscAddr);
+ }
+ for(i=0;i<sizeW;i++) memCODE_W[i]&=0xFFF;
+ unsigned int start=GetTickCount();
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T1T2;
+ bufferU[j++]=1; //T1=1u
+ bufferU[j++]=100; //T2=100u
+ bufferU[j++]=EN_VPP_VCC; //enter program mode
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=NOP;
+ bufferU[j++]=EN_VPP_VCC; //VDD+VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=NOP;
+ if(OscAddr!=-1){
+ for(i=-1;i<OscAddr-0xff;i+=0xff){
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=0xff;
+ }
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=OscAddr-i;
+ bufferU[j++]=READ_DATA_PROG; // OSCCAL
+ if(OscAddr<dim){
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=dim-OscAddr;
+ }
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=0x4; // 400->404
+ bufferU[j++]=READ_DATA_PROG; // backup OSCCAL
+ }
+ bufferU[j++]=NOP; //exit program mode
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=10000>>8;
+ bufferU[j++]=10000&0xff;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(15);
+ if(OscAddr!=-1){
+ for(z=4;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if(z<DIMBUF-2) osccal=(bufferI[z+1]<<8)+bufferI[z+2];
+ for(z+=3;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if(z<DIMBUF-2) BKosccal=(bufferI[z+1]<<8)+bufferI[z+2];
+ if(osccal==-1||BKosccal==-1){
+ PrintMessage(strings[S_ErrOsccal]); //"Error reading OSCCAL and BKOSCCAL"
+ PrintMessage("\r\n");
+ return;
+ }
+ PrintMessage1(strings[S_Osccal],osccal); //"OSCCAL: 0x%03X\r\n"
+ PrintMessage1(strings[S_BKOsccal],BKosccal); //"Backup OSCCAL: 0x%03X\r\n"
+ }
+//****************** erase memory ********************
+ PrintMessage(strings[S_StartErase]); //"Erase ... "
+ j=0;
+ bufferU[j++]=EN_VPP_VCC; // enter program mode
+ bufferU[j++]=0x1;
+ bufferU[j++]=NOP;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x5;
+ if(dim>OscAddr+1){ //12F519 (Flash+EEPROM)
+ bufferU[j++]=BULK_ERASE_PROG; // Bulk erase
+ bufferU[j++]=WAIT_T3; // delay T3=10ms
+ for(i=-1;i<dim-0xff;i+=0xff){ // 0x43F
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=0xff;
+ }
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=dim-i-1;
+ bufferU[j++]=BULK_ERASE_PROG; // Bulk erase EEPROM
+ bufferU[j++]=WAIT_T3; // delay T3=10ms
+ if(programID){
+ bufferU[j++]=INC_ADDR;
+ bufferU[j++]=BULK_ERASE_PROG; // Bulk erase
+ bufferU[j++]=WAIT_T3; // delay T3=10ms
+ }
+ }
+ else{ //12Fxxx
+ if(programID){
+ for(i=-1;i<dim-0xff;i+=0xff){
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=0xff;
+ }
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=dim-i;
+ bufferU[j++]=BULK_ERASE_PROG; // Bulk erase
+ bufferU[j++]=WAIT_T3; // delay T3=10ms
+ }
+ else{
+ bufferU[j++]=BULK_ERASE_PROG; // Bulk erase
+ bufferU[j++]=WAIT_T3; // delay T3=10ms
+ }
+ }
+ bufferU[j++]=EN_VPP_VCC; // exit program mode
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=WAIT_T3; // delay T3=10ms before entering program mode
+ bufferU[j++]=EN_VPP_VCC; // enter program mode
+ bufferU[j++]=0x1;
+ bufferU[j++]=NOP;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x5;
+ bufferU[j++]=INC_ADDR; // 7FF->000
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2000>>8; //T3=2ms
+ bufferU[j++]=2000&0xff;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO((dim>OscAddr+1)?50:30);
+ PrintMessage(strings[S_Compl]); //"completed\r\n"
+//****************** write code ********************
+ PrintMessage(strings[S_StartCodeProg]); //"Write code ... "
+ PrintStatusSetup();
+ int dim1=dim;
+ if(programID) dim1=dim+5;
+ if(memCODE_W[dim+4]>=0xFFF) memCODE_W[dim+4]=BKosccal; //reload BKosccal if not present
+ if(use_BKosccal) memCODE_W[OscAddr]=BKosccal;
+ else if(use_osccal) memCODE_W[OscAddr]=osccal;
+ for(i=k=w=0,j=0;i<dim1;i++){
+ if(memCODE_W[i]<0xfff){
+ bufferU[j++]=LOAD_DATA_PROG;
+ bufferU[j++]=memCODE_W[i]>>8; //MSB
+ bufferU[j++]=memCODE_W[i]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG;
+ bufferU[j++]=WAIT_T3; //Tprogram 2ms
+ bufferU[j++]=END_PROG2;
+ bufferU[j++]=WAIT_T2; //Tdischarge
+ bufferU[j++]=READ_DATA_PROG;
+ w++;
+ }
+ bufferU[j++]=INC_ADDR;
+ if(j>DIMBUF-10||i==dim1-1){
+ PrintStatus(strings[S_CodeWriting],i*100/dim,i); //"Write: %d%%, ind. %03X"
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(w*3+3);
+ w=0;
+ for(z=0;z<DIMBUF-7;z++){
+ if(bufferI[z]==INC_ADDR&&memCODE_W[k]>=0xfff) k++;
+ else if(bufferI[z]==LOAD_DATA_PROG&&bufferI[z+5]==READ_DATA_PROG){
+ if (memCODE_W[k]!=(bufferI[z+6]<<8)+bufferI[z+7]){
+ PrintMessage("\r\n");
+ PrintMessage3(strings[S_CodeWError],k,memCODE_W[k],(bufferI[z+6]<<8)+bufferI[z+7]); //"Error writing address %3X: written %03X, read %03X"
+ err++;
+ if(max_err&&err>max_err){
+ PrintMessage1(strings[S_MaxErr],err); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ PrintMessage(strings[S_IntW]); //"write interrupted"
+ i=dim1;
+ z=DIMBUF;
+ }
+ }
+ k++;
+ z+=8;
+ }
+ }
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,err); //"i=%d, k=%d, errors=%d\n"
+ }
+ }
+ }
+ PrintStatusEnd();
+ err+=i-k;
+ PrintMessage1(strings[S_ComplErr],err); //"completed, %d errors\r\n"
+//****************** write CONFIG ********************
+ PrintMessage(strings[S_ConfigW]); //"Write CONFIG ... "
+ int err_c=0;
+ bufferU[j++]=NOP; //exit program mode
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=WAIT_T3; //10 ms tra uscita e rientro prog. mode
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=EN_VPP_VCC; //enter program mode
+ bufferU[j++]=0x1;
+ bufferU[j++]=NOP;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x5;
+ bufferU[j++]=LOAD_DATA_PROG; //config word
+ bufferU[j++]=memCODE_W[0xfff]>>8; //MSB
+ bufferU[j++]=memCODE_W[0xfff]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG;
+ bufferU[j++]=WAIT_T3; //Tprogram 2ms
+ bufferU[j++]=END_PROG2;
+ bufferU[j++]=WAIT_T2; //Tdischarge
+ bufferU[j++]=READ_DATA_PROG;
+ bufferU[j++]=NOP; //exit program mode
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(20);
+ unsigned int stop=GetTickCount();
+ for(z=0;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if (~memCODE_W[0xfff]&((bufferI[z+1]<<8)+bufferI[z+2])){ //error if written 0 and read 1 (~W&R)
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ConfigWErr],memCODE_W[0xfff],(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing CONFIG:\r\nwritten %03X, read %03X\r\n"
+ err_c++;
+ }
+ err+=err_c;
+ if (z>DIMBUF-2){
+ PrintMessage("\r\n");
+ PrintMessage(strings[S_ConfigWErr2]); //"Error writing CONFIG"
+ }
+ PrintMessage1(strings[S_ComplErr],err_c); //"completed, %d errors\r\n"
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,err); //"i=%d, k=%d, errors=%d\n"
+ }
+ sprintf(str,strings[S_EndErr],(stop-start)/1000.0,err,err!=1?strings[S_ErrPlur]:strings[S_ErrSing]); //"\r\nEnd (%.2f s) %d %s\r\n\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+ PrintStatusClear(); //clear status report
+}
+
+void Write12C5xx(int dim,int dummy)
+{
+// write 12 bit PIC with OTP
+// dim=program size max~4300=10CC
+// vdd before vpp
+// CONFIG @ 0x7FF upon entering program mode
+// write: BEGIN_PROG (1000) + Tprogram 100us + END_PROG2 (1110);
+// 8 pulses + 11N overpulses
+ int k=0,z=0,i,j;
+ int err=0;
+ WORD osccal=-1;
+ int OscAddr=dim-1;
+ if(FWVersion<0x800){
+ PrintMessage1(strings[S_FWver2old],"0.8.0"); //"This firmware is too old. Version %s is required\r\n"
+ return;
+ }
+ if(sizeW<0x1000){
+ PrintMessage(strings[S_NoConfigW2]); //"Can't find CONFIG (0xFFF)\r\n"
+ return;
+ }
+ if(saveLog){
+ OpenLogFile(); //"Log.txt"
+ fprintf(logfile,"Write12C5xx(%d)\n",dim);
+ }
+ for(i=0;i<sizeW;i++) memCODE_W[i]&=0xFFF;
+ unsigned int start=GetTickCount();
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T1T2;
+ bufferU[j++]=1; //T1=1u
+ bufferU[j++]=100; //T2=100u
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_MN;
+ bufferU[j++]=8; //M=8 pulses
+ bufferU[j++]=11; //N=11 overpulses
+ bufferU[j++]=EN_VPP_VCC; //enter program mode
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=NOP;
+ bufferU[j++]=EN_VPP_VCC; //VDD+VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=NOP;
+ for(i=-1;i<OscAddr-0xff;i+=0xff){
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=0xff;
+ }
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=OscAddr-i;
+ bufferU[j++]=READ_DATA_PROG; // OSCCAL
+ bufferU[j++]=NOP; //exit program mode
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=10000>>8;
+ bufferU[j++]=10000&0xff;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(15);
+ j=0;
+ for(z=4;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if(z<DIMBUF-2) osccal=(bufferI[z+1]<<8)+bufferI[z+2];
+ if(osccal==-1){
+ PrintMessage(strings[S_ErrOsccal]); //"Error reading OSCCAL and BKOSCCAL"
+ PrintMessage("\r\n");
+ return;
+ }
+ PrintMessage1(strings[S_Osccal],osccal); //"OSCCAL: 0x%03X\r\n"
+ bufferU[j++]=EN_VPP_VCC; // enter program mode
+ bufferU[j++]=0x1;
+ bufferU[j++]=NOP;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x5;
+ bufferU[j++]=INC_ADDR; // 7FF->000
+ bufferU[j++]=READ_ADC;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+//****************** write code ********************
+ PrintMessage(strings[S_StartCodeProg]); //"Write code ... "
+ PrintStatusSetup();
+ int N,Nt=0,Nmin=255,Nmax=0,xN=0;
+ int dim1=dim;
+ if(programID) dim1=dim+5;
+ if(use_osccal) memCODE_W[OscAddr]=osccal;
+ for(i=k=0,j=0;i<dim1;i++){
+ if(memCODE_W[i]<0xfff){
+ bufferU[j++]=PROG_C; //prog&verify with 8 pulses and 11N overpulses
+ bufferU[j++]=memCODE_W[i]>>8; //MSB
+ bufferU[j++]=memCODE_W[i]&0xff; //LSB
+ bufferU[j++]=READ_DATA_PROG;
+ bufferU[j++]=READ_ADC;
+ bufferU[j++]=INC_ADDR;
+ }
+ else{
+ for(;memCODE_W[i]>=0xfff&&j<DIMBUF-1&&i<dim1;i++) bufferU[j++]=INC_ADDR;
+ i--;
+ }
+ PrintStatus(strings[S_CodeWriting],i*100/dim,i); //"Write: %d%%, ind. %03X"
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(10+3); //Tprogram max 100u*96 ~ 10ms
+ j=0;
+ if(bufferI[1]==PROG_C&&bufferI[3]==READ_DATA_PROG){
+ N=bufferI[2];
+ if(N<0xF0){
+ Nt+=N;
+ xN++;
+ if(N<Nmin)Nmin=N;
+ if(N>Nmax)Nmax=N;
+ }
+ if(memCODE_W[k]!=(bufferI[4]<<8)+bufferI[5]){
+ PrintMessage("\r\n");
+ PrintMessage3(strings[S_CodeWError],k,memCODE_W[k],(bufferI[4]<<8)+bufferI[5]); //"Error writing address %3X: written %03X, read %03X"
+ err++;
+ if(max_err&&err>max_err){
+ PrintMessage1(strings[S_MaxErr],err); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ PrintMessage(strings[S_IntW]); //"write interrupted"
+ i=dim1;
+ z=DIMBUF;
+ }
+ }
+ k++;
+ }
+ else for(z=0;z<DIMBUF;z++){
+ if(bufferI[z]==INC_ADDR&&memCODE_W[k]>=0xfff) k++;
+ }
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,err); //"i=%d, k=%d, errors=%d\n"
+ }
+ }
+ PrintStatusEnd();
+ err+=i-k;
+ PrintMessage1(strings[S_ComplErr],err); //"completed, %d errors\r\n"
+ if(saveLog && xN) fprintf(logfile,"Programming pulses: avg %.1f, min %d, max %d\r\n",(double)Nt/xN,Nmin,Nmax);
+//****************** write CONFIG ********************
+ if(memCODE_W[0xfff]<0xfff){
+ PrintMessage(strings[S_ConfigW]); //"Write CONFIG ... "
+ int err_c=0;
+ bufferU[j++]=EN_VPP_VCC; //exit program mode
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=WAIT_T3; //10 ms
+ bufferU[j++]=EN_VPP_VCC; //enter program mode
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x5;
+ bufferU[j++]=LOAD_DATA_PROG; //config word
+ bufferU[j++]=memCODE_W[0xfff]>>8; //MSB
+ bufferU[j++]=memCODE_W[0xfff]&0xff; //LSB
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(12);
+ j=0;
+ for(i=0;i<20;i++){ //20 pulses
+ bufferU[j++]=BEGIN_PROG;
+ bufferU[j++]=WAIT_T2; //Tprogram 100us
+ bufferU[j++]=END_PROG2;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ j=0;
+ for(i=0;i<5;i++){ //20*5=100 pulses
+ PacketIO(3);
+ }
+ bufferU[j++]=READ_DATA_PROG;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ if (~memCODE_W[0xfff]&((bufferI[2]<<8)+bufferI[3])){ //error if written 0 and read 1 (~W&R)
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ConfigWErr],memCODE_W[0xfff],(bufferI[2]<<8)+bufferI[3]); //"Error writing CONFIG:\r\nwritten %03X, read %03X\r\n"
+ err_c++;
+ }
+ err+=err_c;
+ }
+ PrintMessage1(strings[S_ComplErr],err); //"completed, %d errors\r\n"
+//****************** exit ********************
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ unsigned int stop=GetTickCount();
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,err); //"i=%d, k=%d, errors=%d\n"
+ }
+ sprintf(str,strings[S_EndErr],(stop-start)/1000.0,err,err!=1?strings[S_ErrPlur]:strings[S_ErrSing]); //"\r\nEnd (%.2f s) %d %s\r\n\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+ PrintStatusClear(); //clear status report
+}
diff --git a/progP12.h b/progP12.h
new file mode 100644
index 0000000..110c0a3
--- /dev/null
+++ b/progP12.h
@@ -0,0 +1,3 @@
+void Read12F5xx(int dim, int dim2);
+void Write12F5xx(int dim,int OscAddr);
+void Write12C5xx(int dim,int dummy); \ No newline at end of file
diff --git a/progP16.c b/progP16.c
new file mode 100644
index 0000000..3871494
--- /dev/null
+++ b/progP16.c
@@ -0,0 +1,6546 @@
+/**
+ * \file progP16.c - algorithms to program the PIC16 (14 bit word) family of microcontrollers
+ * Copyright (C) 2009-2022 Alberto Maccioni
+ *
+ * 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"
+
+struct ID16{
+ int id;
+ char *device;
+ int revmask;
+} PIC16LIST[]={
+ {0x00A>>1,"16F72 rev%d\r\n",0x1F}, //00 0000 101x xxxx
+ {0x046>>1,"12F683 rev%d\r\n",0x1F}, //00 0100 011x xxxx
+ {0x04A>>1,"16F685 rev%d\r\n",0x1F}, //00 0100 101x xxxx
+ {0x04C>>1,"16F818 rev%d\r\n",0x1F}, //00 0100 110x xxxx
+ {0x04E>>1,"16F819 rev%d\r\n",0x1F}, //00 0100 111x xxxx
+ {0x056>>1,"16F84A rev%d\r\n",0x1F}, //00 0101 011x xxxx
+ {0x060>>1,"16F73 rev%d\r\n",0x1F}, //00 0110 000x xxxx
+ {0x062>>1,"16F74 rev%d\r\n",0x1F}, //00 0110 001x xxxx
+ {0x064>>1,"16F76 rev%d\r\n",0x1F}, //00 0110 010x xxxx
+ {0x066>>1,"16F77 rev%d\r\n",0x1F}, //00 0110 011x xxxx
+ {0x072>>1,"16F87 rev%d\r\n",0x1F}, //00 0111 001x xxxx
+ {0x076>>1,"16F88 rev%d\r\n",0x1F}, //00 0111 011x xxxx
+ {0x07A>>1,"16F627 rev%d\r\n",0x1F}, //00 0111 101x xxxx
+ {0x07C>>1,"16F628 rev%d\r\n",0x1F}, //00 0111 110x xxxx
+ {0x08E>>1,"16F872 rev%d\r\n",0x1F}, //00 1000 111x xxxx
+ {0x092>>1,"16F874 rev%d\r\n",0x1F}, //00 1001 001x xxxx
+ {0x096>>1,"16F873 rev%d\r\n",0x1F}, //00 1001 011x xxxx
+ {0x09A>>1,"16F877 rev%d\r\n",0x1F}, //00 1001 101x xxxx
+ {0x09E>>1,"16F876 rev%d\r\n",0x1F}, //00 1001 111x xxxx
+ {0x0BA>>1,"16F737 rev%d\r\n",0x1F}, //00 1011 101x xxxx
+ {0x0BE>>1,"16F747 rev%d\r\n",0x1F}, //00 1011 111x xxxx
+ {0x0D0>>1,"16F870 rev%d\r\n",0x1F}, //00 1101 000x xxxx
+ {0x0D2>>1,"16F871 rev%d\r\n",0x1F}, //00 1101 001x xxxx
+ {0x0DE>>1,"16F777 rev%d\r\n",0x1F}, //00 1101 111x xxxx
+ {0x0E0>>1,"16F876A rev%d\r\n",0xF}, //00 1110 0000 xxxx
+ {0x0E2>>1,"16F877A rev%d\r\n",0xF}, //00 1110 0010 xxxx
+ {0x0E4>>1,"16F873A rev%d\r\n",0xF}, //00 1110 0100 xxxx
+ {0x0E6>>1,"16F874A rev%d\r\n",0xF}, //00 1110 0110 xxxx
+ {0x0EA>>1,"16F767 rev%d\r\n",0x1F}, //00 1110 101x xxxx
+ {0x0F8>>1,"12F629 rev%d\r\n",0x1F}, //00 1111 100x xxxx
+ {0x0FA>>1,"12F635 rev%d\r\n",0x1F}, //00 1111 101x xxxx
+ {0x0FC>>1,"12F675 rev%d\r\n",0x1F}, //00 1111 110x xxxx
+ {0x104>>1,"16F627A rev%d\r\n",0x1F}, //01 0000 010x xxxx
+ {0x106>>1,"16F628A rev%d\r\n",0x1F}, //01 0000 011x xxxx
+ {0x108>>1,"16F684 rev%d\r\n",0x1F}, //01 0000 100x xxxx
+ {0x110>>1,"16F648A rev%d\r\n",0x1F}, //01 0001 000x xxxx
+ {0x10A>>1,"16F636-639 rev%d\r\n",0x1F}, //01 0000 101x xxxx
+ {0x10C>>1,"16F630 rev%d\r\n",0x1F}, //01 0000 110x xxxx
+ {0x10E>>1,"16F676 rev%d\r\n",0x1F}, //01 0000 111x xxxx
+ {0x114>>1,"16F716 rev%d\r\n",0x1F}, //01 0001 010x xxxx
+ {0x118>>1,"16F688 rev%d\r\n",0x1F}, //01 0001 100x xxxx
+ {0x120>>1,"16F785 rev%d\r\n",0x1F}, //01 0010 000x xxxx
+ {0x122>>1,"16HV785 rev%d\r\n",0x1F}, //01 0010 001x xxxx
+ {0x124>>1,"16F616 rev%d\r\n",0x1F}, //01 0010 010x xxxx
+ {0x126>>1,"16HV616 rev%d\r\n",0x1F}, //01 0010 011x xxxx
+ {0x132>>1,"16F687 rev%d\r\n",0x1F}, //01 0011 001x xxxx
+ {0x134>>1,"16F689 rev%d\r\n",0x1F}, //01 0011 010x xxxx
+ {0x138>>1,"16F917 rev%d\r\n",0xF}, //01 0011 1000 xxxx
+ {0x13A>>1,"16F916 rev%d\r\n",0xF}, //01 0011 1010 xxxx
+ {0x13C>>1,"16F914 rev%d\r\n",0xF}, //01 0011 1100 xxxx
+ {0x13E>>1,"16F913 rev%d\r\n",0xF}, //01 0011 1110 xxxx
+ {0x140>>1,"16F690 rev%d\r\n",0x1F}, //01 0100 000x xxxx
+ {0x142>>1,"16F631 rev%d\r\n",0x1F}, //01 0100 001x xxxx
+ {0x144>>1,"16F677 rev%d\r\n",0x1F}, //01 0100 010x xxxx
+ {0x146>>1,"16F946 rev%d\r\n",0xF}, //01 0100 0110 xxxx
+ {0x148>>1,"16F1847 rev%d\r\n",0x1F}, //01 0100 100x xxxx
+ {0x14A>>1,"16LF1847 rev%d\r\n",0x1F}, //01 0100 101x xxxx
+ {0x150>>1,"12F752 rev%d\r\n",0x1F}, //01 0101 000x xxxx
+ {0x152>>1,"12HV752 rev%d\r\n",0x1F}, //01 0101 001x xxxx
+ {0x158>>1,"16F1526 rev%d\r\n",0x1F}, //01 0101 100x xxxx
+ {0x15A>>1,"16F1527 rev%d\r\n",0x1F}, //01 0101 101x xxxx
+ {0x15C>>1,"16LF1526 rev%d\r\n",0x1F}, //01 0101 110x xxxx
+ {0x15E>>1,"16LF1527 rev%d\r\n",0x1F}, //01 0101 111x xxxx
+ {0x164>>1,"16F1513 rev%d\r\n",0x1F}, //01 0110 010x xxxx
+ {0x168>>1,"16F1516 rev%d\r\n",0x1F}, //01 0110 100x xxxx
+ {0x16A>>1,"16F1517 rev%d\r\n",0x1F}, //01 0110 101x xxxx
+ {0x16C>>1,"16F1518 rev%d\r\n",0x1F}, //01 0110 110x xxxx
+ {0x16E>>1,"16F1519 rev%d\r\n",0x1F}, //01 0110 111x xxxx
+ {0x170>>1,"16F1512 rev%d\r\n",0x1F}, //01 0111 000x xxxx
+ {0x172>>1,"16LF1512 rev%d\r\n",0x1F}, //01 0111 001x xxxx
+ {0x174>>1,"16LF1513 rev%d\r\n",0x1F}, //01 0111 010x xxxx
+ {0x178>>1,"16LF1516 rev%d\r\n",0x1F}, //01 0111 100x xxxx
+ {0x17A>>1,"16LF1517 rev%d\r\n",0x1F}, //01 0111 101x xxxx
+ {0x17C>>1,"16LF1518 rev%d\r\n",0x1F}, //01 0111 110x xxxx
+ {0x17E>>1,"16LF1519 rev%d\r\n",0x1F}, //01 0111 111x xxxx
+ {0x180>>1,"16F727 rev%d\r\n",0x1F}, //01 1000 000x xxxx
+ {0x182>>1,"16F726 rev%d\r\n",0x1F}, //01 1000 001x xxxx
+ {0x184>>1,"16F724 rev%d\r\n",0x1F}, //01 1000 010x xxxx
+ {0x186>>1,"16F723 rev%d\r\n",0x1F}, //01 1000 011x xxxx
+ {0x188>>1,"16F722 rev%d\r\n",0x1F}, //01 1000 100x xxxx
+ {0x190>>1,"16LF727 rev%d\r\n",0x1F}, //01 1001 000x xxxx
+ {0x192>>1,"16LF726 rev%d\r\n",0x1F}, //01 1001 001x xxxx
+ {0x194>>1,"16LF724 rev%d\r\n",0x1F}, //01 1001 010x xxxx
+ {0x196>>1,"16LF723 rev%d\r\n",0x1F}, //01 1001 011x xxxx
+ {0x198>>1,"16LF722 rev%d\r\n",0x1F}, //01 1001 100x xxxx
+ {0x1AC>>1,"16F707 rev%d\r\n",0x1F}, //01 1010 110x xxxx
+ {0x1AE>>1,"16LF707 rev%d\r\n",0x1F}, //01 1010 111x xxxx
+ {0x1B0>>1,"16F723A rev%d\r\n",0x1F}, //01 1011 000x xxxx
+ {0x1B2>>1,"16F722A rev%d\r\n",0x1F}, //01 1011 001x xxxx
+ {0x1B4>>1,"16LF723A rev%d\r\n",0x1F}, //01 1011 010x xxxx
+ {0x1B6>>1,"16LF722A rev%d\r\n",0x1F}, //01 1011 011x xxxx
+ {0x1B8>>1,"12F1840 rev%d\r\n",0x1F}, //01 1011 100x xxxx
+ {0x1BA>>1,"12LF1840 rev%d\r\n",0x1F}, //01 1011 101x xxxx
+ {0x1C0>>1,"16F720 rev%d\r\n",0x1F}, //01 1100 000x xxxx
+ {0x1C2>>1,"16F721 rev%d\r\n",0x1F}, //01 1100 001x xxxx
+ {0x1C4>>1,"16LF720 rev%d\r\n",0x1F}, //01 1100 010x xxxx
+ {0x1C6>>1,"16LF721 rev%d\r\n",0x1F}, //01 1100 011x xxxx
+ {0x200>>1,"16F882 rev%d\r\n",0x1F}, //10 0000 000x xxxx
+ {0x202>>1,"16F883 rev%d\r\n",0x1F}, //10 0000 001x xxxx
+ {0x204>>1,"16F884 rev%d\r\n",0x1F}, //10 0000 010x xxxx
+ {0x206>>1,"16F886 rev%d\r\n",0x1F}, //10 0000 011x xxxx
+ {0x208>>1,"16F887 rev%d\r\n",0x1F}, //10 0000 100x xxxx
+ {0x218>>1,"12F615 rev%d\r\n",0x1F}, //10 0001 100x xxxx
+ {0x21A>>1,"12HV615 rev%d\r\n",0x1F}, //10 0001 101x xxxx
+ {0x224>>1,"12F609 rev%d\r\n",0x1F}, //10 0010 010x xxxx
+ {0x226>>1,"16F610 rev%d\r\n",0x1F}, //10 0010 011x xxxx
+ {0x228>>1,"12HV609 rev%d\r\n",0x1F}, //10 0010 100x xxxx
+ {0x22A>>1,"16HV610 rev%d\r\n",0x1F}, //10 0010 101x xxxx
+ {0x232>>1,"16F1933 rev%d\r\n",0x1F}, //10 0011 001x xxxx
+ {0x234>>1,"16F1934 rev%d\r\n",0x1F}, //10 0011 010x xxxx
+ {0x236>>1,"16F1936 rev%d\r\n",0x1F}, //10 0011 011x xxxx
+ {0x238>>1,"16F1937 rev%d\r\n",0x1F}, //10 0011 100x xxxx
+ {0x23A>>1,"16F1938 rev%d\r\n",0x1F}, //10 0011 101x xxxx
+ {0x23C>>1,"16F1939 rev%d\r\n",0x1F}, //10 0011 110x xxxx
+ {0x242>>1,"16LF1933 rev%d\r\n",0x1F}, //10 0100 001x xxxx
+ {0x244>>1,"16LF1934 rev%d\r\n",0x1F}, //10 0100 010x xxxx
+ {0x246>>1,"16LF1936 rev%d\r\n",0x1F}, //10 0100 011x xxxx
+ {0x248>>1,"16LF1937 rev%d\r\n",0x1F}, //10 0100 100x xxxx
+ {0x24A>>1,"16LF1938 rev%d\r\n",0x1F}, //10 0100 101x xxxx
+ {0x24C>>1,"16LF1939 rev%d\r\n",0x1F}, //10 0100 110x xxxx
+ {0x250>>1,"16F1946 rev%d\r\n",0x1F}, //10 0101 000x xxxx
+ {0x252>>1,"16F1947 rev%d\r\n",0x1F}, //10 0101 001x xxxx
+ {0x258>>1,"16LF1946 rev%d\r\n",0x1F}, //10 0101 100x xxxx
+ {0x25A>>1,"16LF1947 rev%d\r\n",0x1F}, //10 0101 101x xxxx
+ {0x270>>1,"12F1822 rev%d\r\n",0x1F}, //10 0111 000x xxxx
+ {0x272>>1,"16F1823 rev%d\r\n",0x1F}, //10 0111 001x xxxx
+ {0x274>>1,"16F1824 rev%d\r\n",0x1F}, //10 0111 010x xxxx
+ {0x276>>1,"16F1825 rev%d\r\n",0x1F}, //10 0111 011x xxxx
+ {0x278>>1,"16F1826 rev%d\r\n",0x1F}, //10 0111 100x xxxx
+ {0x27A>>1,"16F1827 rev%d\r\n",0x1F}, //10 0111 101x xxxx
+ {0x280>>1,"12LF1822 rev%d\r\n",0x1F}, //10 1000 000x xxxx
+ {0x282>>1,"16LF1823 rev%d\r\n",0x1F}, //10 1000 001x xxxx
+ {0x284>>1,"16LF1824 rev%d\r\n",0x1F}, //10 1000 010x xxxx
+ {0x286>>1,"16LF1825 rev%d\r\n",0x1F}, //10 1000 011x xxxx
+ {0x288>>1,"16LF1826 rev%d\r\n",0x1F}, //10 1000 100x xxxx
+ {0x28A>>1,"16LF1827 rev%d\r\n",0x1F}, //10 1000 101x xxxx
+ {0x298>>1,"10F322 rev%d\r\n",0x1F}, //10 1001 100x xxxx
+ {0x29A>>1,"10F320 rev%d\r\n",0x1F}, //10 1001 101x xxxx
+ {0x29C>>1,"10LF322 rev%d\r\n",0x1F}, //10 1001 110x xxxx
+ {0x29E>>1,"10LF320 rev%d\r\n",0x1F}, //10 1001 111x xxxx
+ {0x2A0>>1,"16F1782 rev%d\r\n",0x1F}, //10 1010 000x xxxx
+ {0x2A2>>1,"16F1783 rev%d\r\n",0x1F}, //10 1010 001x xxxx
+ {0x2A4>>1,"16F1784 rev%d\r\n",0x1F}, //10 1010 010x xxxx
+ {0x2A6>>1,"16F1786 rev%d\r\n",0x1F}, //10 1010 011x xxxx
+ {0x2A8>>1,"16F1787 rev%d\r\n",0x1F}, //10 1010 100x xxxx
+ {0x2AA>>1,"16LF1782 rev%d\r\n",0x1F}, //10 1010 101x xxxx
+ {0x2AC>>1,"16LF1783 rev%d\r\n",0x1F}, //10 1010 110x xxxx
+ {0x2AE>>1,"16LF1784 rev%d\r\n",0x1F}, //10 1010 111x xxxx
+ {0x2B0>>1,"16LF1786 rev%d\r\n",0x1F}, //10 1011 000x xxxx
+ {0x2B2>>1,"16LF1787 rev%d\r\n",0x1F}, //10 1011 001x xxxx
+ {0x2C0>>1,"16LF1903 rev%d\r\n",0x1F}, //10 1100 000x xxxx
+ {0x2C2>>1,"16LF1902 rev%d\r\n",0x1F}, //10 1100 001x xxxx
+ {0x2C4>>1,"16LF1907 rev%d\r\n",0x1F}, //10 1100 010x xxxx
+ {0x2C6>>1,"16LF1906 rev%d\r\n",0x1F}, //10 1100 011x xxxx
+ {0x2C8>>1,"16LF1904 rev%d\r\n",0x1F}, //10 1100 100x xxxx
+ {0x2CC>>1,"12F1501 rev%d\r\n",0x1F}, //10 1100 110x xxxx
+ {0x2CE>>1,"16F1503 rev%d\r\n",0x1F}, //10 1100 111x xxxx
+ {0x2D0>>1,"16F1507 rev%d\r\n",0x1F}, //10 1101 000x xxxx
+ {0x2D2>>1,"16F1508 rev%d\r\n",0x1F}, //10 1101 001x xxxx
+ {0x2D4>>1,"16F1509 rev%d\r\n",0x1F}, //10 1101 010x xxxx
+ {0x2D8>>1,"12LF1501 rev%d\r\n",0x1F}, //10 1101 100x xxxx
+ {0x2DA>>1,"16LF1503 rev%d\r\n",0x1F}, //10 1101 101x xxxx
+ {0x2DC>>1,"16LF1507 rev%d\r\n",0x1F}, //10 1101 110x xxxx
+ {0x2DE>>1,"16LF1508 rev%d\r\n",0x1F}, //10 1101 111x xxxx
+ {0x2E0>>1,"16LF1509 rev%d\r\n",0x1F}, //10 1110 000x xxxx
+ {0x2F0>>1,"16LF1554 rev%d\r\n",0x1F}, //10 1111 000x xxxx
+ {0x2F2>>1,"16LF1559 rev%d\r\n",0x1F}, //10 1111 001x xxxx
+// New devices with DevID & DevRev in different locations:
+ {0x3000,"16F1574\r\n",0},
+ {0x3001,"16F1575\r\n",0},
+ {0x3002,"16F1578\r\n",0},
+ {0x3003,"16F1579\r\n",0},
+ {0x3004,"16LF1574\r\n",0},
+ {0x3005,"16LF1575\r\n",0},
+ {0x3006,"16LF1578\r\n",0},
+ {0x3007,"16LF1579\r\n",0},
+ {0x3020,"16F1454\r\n",0},
+ {0x3021,"16F1455\r\n",0},
+ {0x3023,"16F1459\r\n",0},
+ {0x3024,"16LF1454\r\n",0},
+ {0x3025,"16LF1455\r\n",0},
+ {0x3027,"16LF1459\r\n",0},
+ {0x302A,"16F1789\r\n",0},
+ {0x302B,"16F1788\r\n",0},
+ {0x302C,"16LF1789\r\n",0},
+ {0x302D,"16LF1788\r\n",0},
+ {0x3030,"16F753\r\n",0},
+ {0x3031,"16HV753\r\n",0},
+ {0x303A,"16F18324\r\n",0},
+ {0x303B,"16F18344\r\n",0},
+ {0x303C,"16LF18324\r\n",0},
+ {0x303D,"16LF18344\r\n",0},
+ {0x303E,"16F18325\r\n",0},
+ {0x303F,"16F18345\r\n",0},
+ {0x3040,"16LF18325\r\n",0},
+ {0x3041,"16LF18345\r\n",0},
+ {0x3042,"16F1708\r\n",0},
+ {0x3043,"16F1704\r\n",0},
+ {0x3044,"16LF1708\r\n",0},
+ {0x3045,"16LF1704\r\n",0},
+ {0x3048,"16F1716\r\n",0},
+ {0x3049,"16F1713\r\n",0},
+ {0x304A,"16LF1716\r\n",0},
+ {0x304B,"16LF1713\r\n",0},
+ {0x304C,"16F1613\r\n",0},
+ {0x304D,"16LF1613\r\n",0},
+ {0x3050,"12F1572\r\n",0},
+ {0x3051,"12F1571\r\n",0},
+ {0x3052,"12LF1572\r\n",0},
+ {0x3053,"12LF1571\r\n",0},
+ {0x3054,"16F1709\r\n",0},
+ {0x3055,"16F1705\r\n",0},
+ {0x3056,"16LF1709\r\n",0},
+ {0x3057,"16LF1705\r\n",0},
+ {0x3058,"12F1612\r\n",0},
+ {0x3059,"12LF1612\r\n",0},
+ {0x305A,"16F1719\r\n",0},
+ {0x305B,"16F1718\r\n",0},
+ {0x305C,"16F1717\r\n",0},
+ {0x305D,"16LF1719\r\n",0},
+ {0x305E,"16LF1718\r\n",0},
+ {0x305F,"16LF1717\r\n",0},
+ {0x3060,"16F1707\r\n",0},
+ {0x3061,"16F1703\r\n",0},
+ {0x3062,"16LF1707\r\n",0},
+ {0x3063,"16LF1703\r\n",0},
+ {0x3066,"16F18313\r\n",0},
+ {0x3067,"16F18323\r\n",0},
+ {0x3068,"16LF18313\r\n",0},
+ {0x3069,"16LF18323\r\n",0},
+ {0x306A,"16F18854\r\n",0},
+ {0x306B,"16LF18854\r\n",0},
+ {0x306C,"16F18855\r\n",0},
+ {0x306D,"16F18875\r\n",0},
+ {0x306E,"16LF18855\r\n",0},
+ {0x306F,"16LF18875\r\n",0},
+ {0x3070,"16F18856\r\n",0},
+ {0x3071,"16F18876\r\n",0},
+ {0x3072,"16LF18856\r\n",0},
+ {0x3073,"16LF18876\r\n",0},
+ {0x3074,"16F18857\r\n",0},
+ {0x3075,"16F18877\r\n",0},
+ {0x3076,"16LF18857\r\n",0},
+ {0x3077,"16LF18877\r\n",0},
+ {0x3078,"16F1614\r\n",0},
+ {0x3079,"16F1618\r\n",0},
+ {0x307A,"16LF1614\r\n",0},
+ {0x307B,"16LF1618\r\n",0},
+ {0x307C,"16F1615\r\n",0},
+ {0x307D,"16F1619\r\n",0},
+ {0x307E,"16LF1615\r\n",0},
+ {0x307F,"16LF1619\r\n",0},
+ {0x3080,"16F1764\r\n",0},
+ {0x3081,"16F1765\r\n",0},
+ {0x3082,"16LF1764\r\n",0},
+ {0x3083,"16LF1765\r\n",0},
+ {0x3084,"16F1768\r\n",0},
+ {0x3085,"16F1769\r\n",0},
+ {0x3086,"16LF1768\r\n",0},
+ {0x3087,"16LF1769\r\n",0},
+ {0x308A,"16F1773\r\n",0},
+ {0x308B,"16F1776\r\n",0},
+ {0x308C,"16LF1773\r\n",0},
+ {0x308D,"16LF1776\r\n",0},
+ {0x308E,"16F1777\r\n",0},
+ {0x308F,"16F1778\r\n",0},
+ {0x3090,"16F1779\r\n",0},
+ {0x3091,"16LF1777\r\n",0},
+ {0x3092,"16LF1778\r\n",0},
+ {0x3093,"16LF1779\r\n",0},
+ {0x3096,"16F19155\r\n",0},
+ {0x3097,"16LF19155\r\n",0},
+ {0x3098,"16F19156\r\n",0},
+ {0x3099,"16LF19156\r\n",0},
+ {0x309A,"16F19175\r\n",0},
+ {0x309B,"16LF19175\r\n",0},
+ {0x309C,"16F19176\r\n",0},
+ {0x309D,"16LF19176\r\n",0},
+ {0x309E,"16F19195\r\n",0},
+ {0x309F,"16LF19195\r\n",0},
+ {0x30A0,"16F19196\r\n",0},
+ {0x30A1,"16LF19196\r\n",0},
+ {0x30A2,"16F19197\r\n",0},
+ {0x30A3,"16LF19197\r\n",0},
+ {0x30A4,"16F18326\r\n",0},
+ {0x30A5,"16F18346\r\n",0},
+ {0x30A6,"16LF18326\r\n",0},
+ {0x30A7,"16LF18346\r\n",0},
+ {0x30AC,"16F15354\r\n",0},
+ {0x30AD,"16LF15354\r\n",0},
+ {0x30AE,"16F15355\r\n",0},
+ {0x30AF,"16LF15355\r\n",0},
+ {0x30B0,"16F15356\r\n",0},
+ {0x30B1,"16LF15356\r\n",0},
+ {0x30B2,"16F15375\r\n",0},
+ {0x30B3,"16LF15375\r\n",0},
+ {0x30B4,"16F15376\r\n",0},
+ {0x30B5,"16LF15376\r\n",0},
+ {0x30B6,"16F15385\r\n",0},
+ {0x30B7,"16LF15385\r\n",0},
+ {0x30B8,"16F15386\r\n",0},
+ {0x30B9,"16LF15386\r\n",0},
+ {0x30BE,"16F15313\r\n",0},
+ {0x30BF,"16LF15313\r\n",0},
+ {0x30BA,"16F19185\r\n",0},
+ {0x30BB,"16LF19185\r\n",0},
+ {0x30BC,"16F19186\r\n",0},
+ {0x30BD,"16LF19186\r\n",0},
+ {0x30C0,"16F15323\r\n",0},
+ {0x30C1,"16LF15323\r\n",0},
+ {0x30C2,"16F15324\r\n",0},
+ {0x30C3,"16LF15324\r\n",0},
+ {0x30C4,"16F15344\r\n",0},
+ {0x30C5,"16LF15344\r\n",0},
+ {0x30C6,"16F15325\r\n",0},
+ {0x30C7,"16LF15325\r\n",0},
+ {0x30C8,"16F15345\r\n",0},
+ {0x30C9,"16LF15345\r\n",0},
+ {0x30CA,"16F18424\r\n",0},
+ {0x30CB,"16LF18424\r\n",0},
+ {0x30CC,"16F18425\r\n",0},
+ {0x30CD,"16LF18425\r\n",0},
+ {0x30CE,"16F18444\r\n",0},
+ {0x30CF,"16LF18444\r\n",0},
+ {0x30D0,"16F18445\r\n",0},
+ {0x30D1,"16LF18445\r\n",0},
+ {0x30D2,"16F18426\r\n",0},
+ {0x30D3,"16LF18426\r\n",0},
+ {0x30D4,"16F18446\r\n",0},
+ {0x30D5,"16LF18446\r\n",0},
+ {0x30D7,"16F18455\r\n",0},
+ {0x30D8,"16LF18455\r\n",0},
+ {0x30D9,"16F18456\r\n",0},
+ {0x30DA,"16LF18456\r\n",0},
+ {0x30DB,"16F17114\r\n",0},
+ {0x30DC,"16F17124\r\n",0},
+ {0x30DD,"16F17144\r\n",0},
+ {0x30DE,"16F17125\r\n",0},
+ {0x30DF,"16F17145\r\n",0},
+ {0x30E0,"16F17126\r\n",0},
+ {0x30E1,"16F17146\r\n",0},
+ {0x30E2,"16F17115\r\n",0},
+ {0x30E3,"16F15213\r\n",0},
+ {0x30E4,"16F15223\r\n",0},
+ {0x30E5,"16F15243\r\n",0},
+ {0x30E6,"16F15214\r\n",0},
+ {0x30E7,"16F15224\r\n",0},
+ {0x30E8,"16F15244\r\n",0},
+ {0x30E9,"16F15225\r\n",0},
+ {0x30EA,"16F15245\r\n",0},
+ {0x30EB,"16F15256\r\n",0},
+ {0x30EC,"16F15276\r\n",0},
+ {0x30ED,"16F15275\r\n",0},
+ {0x30EE,"16F15274\r\n",0},
+ {0x30EF,"16F15255\r\n",0},
+ {0x30F0,"16F15254\r\n",0},
+ {0x30F1,"16F18013\r\n",0},
+ {0x30F2,"16F18014\r\n",0},
+ {0x30F3,"16F18023\r\n",0},
+ {0x30F4,"16F18024\r\n",0},
+ {0x30F5,"16F18015\r\n",0},
+ {0x30F6,"16F18025\r\n",0},
+ {0x30F7,"16F18044\r\n",0},
+ {0x30F8,"16F18045\r\n",0},
+ {0x30F9,"16F18026\r\n",0},
+ {0x30FA,"16F18046\r\n",0},
+ {0x30FB,"16F18054\r\n",0},
+ {0x30FC,"16F18055\r\n",0},
+ {0x30FD,"16F18074\r\n",0},
+ {0x30FE,"16F18075\r\n",0},
+ {0x30FF,"16F18056\r\n",0},
+ {0x3100,"16F18076\r\n",0},
+ {0x3107,"16F18114\r\n",0},
+ {0x3108,"16F18124\r\n",0},
+ {0x3109,"16F18144\r\n",0},
+ {0x310A,"16F18154\r\n",0},
+ {0x310B,"16F18174\r\n",0},
+ {0x310C,"16F18115\r\n",0},
+ {0x310D,"16F18125\r\n",0},
+ {0x310E,"16F18145\r\n",0},
+ {0x310F,"16F18155\r\n",0},
+ {0x3110,"16F18175\r\n",0},
+ {0x3111,"16F18126\r\n",0},
+ {0x3112,"16F18146\r\n",0},
+ {0x3113,"16F18156\r\n",0},
+ {0x3114,"16F18176\r\n",0},
+ {0x3101,"16F17154\r\n",0},
+ {0x3102,"16F17174\r\n",0},
+ {0x3103,"16F17155\r\n",0},
+ {0x3104,"16F17175\r\n",0},
+ {0x3105,"16F17156\r\n",0},
+ {0x3106,"16F17176\r\n",0},
+};
+
+void PIC16_ID(int id)
+{
+ char s[64];
+ int i;
+ for(i=0;i<sizeof(PIC16LIST)/sizeof(PIC16LIST[0]);i++){
+ if(PIC16LIST[i].revmask&&(id>>5)==PIC16LIST[i].id){ //id + rev in same location
+ sprintf(s,PIC16LIST[i].device,id&PIC16LIST[i].revmask);
+ PrintMessage(s);
+ return;
+ }
+ else if(!PIC16LIST[i].revmask&&id==PIC16LIST[i].id){ //id separate from rev
+ sprintf(s,PIC16LIST[i].device);
+ PrintMessage(s);
+ return;
+ }
+ }
+ sprintf(s,"%s",strings[S_nodev]); //"Unknown device\r\n");
+ PrintMessage(s);
+}
+
+void DisplayCODE16F(int size){
+// display 14 bit PIC CODE memory
+ char s[256]="",t[256]="";
+ char* aux=(char*)malloc((size/COL+1)*(16+COL*5));
+ aux[0]=0;
+ int valid=0,empty=1,i,j,lines=0;
+ for(i=0;i<size&&i<sizeW;i+=COL){
+ valid=0;
+ for(j=i;j<i+COL&&j<sizeW&&i<size;j++){
+ sprintf(t,"%04X ",memCODE_W[j]);
+ strcat(s,t);
+ if((memCODE_W[j]&0x3fff)<0x3fff) valid=1;
+ }
+ if(valid){
+ sprintf(t,"%04X: %s\r\n",i,s);
+ empty=0;
+ strcat(aux,t);
+ lines++;
+ if(lines>500){ //limit number of lines printed
+ strcat(aux,"(...)\r\n");
+ i=(sizeW<size?sizeW:size)-COL*2;
+ lines=490;
+ }
+ }
+ s[0]=0;
+ }
+ if(empty) PrintMessage(strings[S_Empty]); //empty
+ else PrintMessage(aux);
+ free(aux);
+}
+
+void DisplayEE16F(int size){
+// display 14 bit PIC EEPROM memory
+ int valid=0,empty=1,i,j;
+ char s[256]="",t[256]="",v[256]="";
+ char* aux=(char*)malloc((size/COL+1)*(16+COL*5));
+ aux[0]=0;
+#ifdef __GTK_H__
+ char *g;
+#endif
+ empty=1;
+ v[0]=0;
+ for(i=0x2100;i<0x2100+size&&i<sizeW;i+=COL){
+ valid=0;
+ for(j=i;j<i+COL&&j<0x2100+size&&j<sizeW;j++){
+ sprintf(t,"%02X ",memCODE_W[j]&0xff);
+ strcat(s,t);
+ sprintf(t,"%c",isprint(memCODE_W[j]&0xFF)&&(memCODE_W[j]&0xFF)<0xFF?memCODE_W[j]&0xFF:'.');
+#ifdef __GTK_H__
+ g=g_locale_to_utf8(t,-1,NULL,NULL,NULL);
+ if(g) strcat(v,g);
+ g_free(g);
+#else
+ strcat(v,t);
+#endif
+ if((memCODE_W[j]&0xFF)<0xff) valid=1;/**/
+ }
+ if(valid){
+ sprintf(t,"%04X: %s %s\r\n",i,s,v);
+ empty=0;
+ strcat(aux,t);
+ }
+ s[0]=0;
+ v[0]=0;
+ }
+ if(empty) PrintMessage(strings[S_Empty]); //empty
+ else PrintMessage(aux);
+ free(aux);
+}
+
+void Read16Fxxx(int dim,int dim2,int dim3,int vdd)
+// read 14 bit PIC
+// dim=program size dim2=eeprom size dim3=config size
+// dim2<0 -> eeprom @ 0x2200
+// vdd=0 -> vpp before vdd
+// vdd=1 -> vdd (+50ms) before vpp
+// vdd=2 -> vdd before vpp
+// DevREV@0x2005
+// DevID@0x2006
+// Config@0x2007
+// Calib1/Config2@0x2008
+// Calib2/Calib1@0x2009
+// eeprom@0x2100
+{
+ int k=0,k2=0,z=0,i,j,ee2200=0;
+ char s[512],t[256],*aux;
+ if(dim2<0){
+ dim2=-dim2;
+ ee2200=1;
+ }
+ if(dim>0x2000||dim<0){
+ PrintMessage(strings[S_CodeLim]); //"Code size exceeds limits\r\n"
+ return;
+ }
+ if(dim2>0x400||dim2<0){ //Max 1K
+ PrintMessage(strings[S_EELim]); //"EEPROM size exceeds limits\r\n"
+ return;
+ }
+ if(dim3>0x100||dim3<0){
+ PrintMessage(strings[S_ConfigLim]); //"Config area size exceeds limits\r\n"
+ return;
+ }
+ if(dim3<8)dim3=8;
+ if(saveLog){
+ OpenLogFile(); //"log.txt"
+ fprintf(logfile,"Read16Fxxx(%d,%d,%d,%d)\n",dim,dim2,dim3,vdd);
+ }
+ sizeW=0x2100+dim2;
+ if(memCODE_W) free(memCODE_W);
+ memCODE_W=(WORD*)malloc(sizeof(WORD)*sizeW);
+ unsigned int start=GetTickCount();
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T1T2;
+ bufferU[j++]=1; //T1=1u
+ bufferU[j++]=100; //T2=100u
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2000>>8;
+ bufferU[j++]=2000&0xff;
+ bufferU[j++]=EN_VPP_VCC; //enter program mode
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ if(vdd==0){ //VPP before VDD
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=4; //VPP
+ bufferU[j++]=NOP;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x5; //VDD+VPP
+ }
+ else if(vdd==1){ //VDD before VPP with delay 50ms
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=1; //VDD
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=25000>>8;
+ bufferU[j++]=25000&0xff;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2000>>8;
+ bufferU[j++]=2000&0xff;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x5; //VDD+VPP
+ }
+ else if(vdd==2){ //VDD before VPP without delay
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=1; //VDD
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x5; //VDD+VPP
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(vdd?55:5);
+//****************** read code ********************
+ PrintMessage(strings[S_CodeReading1]); //read code ...
+ if(saveLog) fprintf(logfile,"%s\n",strings[S_CodeReading1]); //read code ...
+ PrintStatusSetup();
+ for(i=0,j=0;i<dim;i++){
+ bufferU[j++]=READ_DATA_PROG;
+ bufferU[j++]=INC_ADDR;
+ if(j>DIMBUF*2/4-3||i==dim-1){ //2B cmd -> 4B data
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ for(z=0;z<DIMBUF-2;z++){
+ if(bufferI[z]==READ_DATA_PROG){
+ memCODE_W[k++]=(bufferI[z+1]<<8)+bufferI[z+2];
+ z+=2;
+ }
+ }
+ PrintStatus(strings[S_CodeReading],i*100/(dim+dim2+dim3),i); //"Read: %d%%, addr. %03X"
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k,k); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ }
+ }
+ PrintStatusEnd();
+ if(k!=dim){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ReadCodeErr],dim,k); //"Error reading code area, requested %d words, read %d\r\n"
+ }
+ else PrintMessage(strings[S_Compl]);
+ for(i=k;i<0x2000;i++) memCODE_W[i]=0x3fff;
+//****************** read config area ********************
+ PrintMessage(strings[S_Read_CONFIG_A]); //read config ...
+ if(saveLog) fprintf(logfile,"%s\n",strings[S_Read_CONFIG_A]); //read config ...
+ bufferU[j++]=LOAD_CONF; //counter at 0x2000
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=0xFF; //fake config
+ for(i=0x2000;i<0x2000+dim3;i++){ //Config
+ bufferU[j++]=READ_DATA_PROG;
+ bufferU[j++]=INC_ADDR;
+ if(j>DIMBUF*2/4-3||i==0x2000+dim3-1){ //2B cmd -> 4B data
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ for(z=0;z<DIMBUF-2;z++){
+ if(bufferI[z]==READ_DATA_PROG){
+ memCODE_W[0x2000+k2++]=(bufferI[z+1]<<8)+bufferI[z+2];
+ z+=2;
+ }
+ }
+ PrintStatus(strings[S_CodeReading],(i-0x2000+dim)*100/(dim+dim2+dim3),i); //"Read: %d%%, addr. %03X"
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k2,k2); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ }
+ }
+ if(k2!=dim3){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ConfigErr],dim3,k2); //"Error reading config area, requested %d words, read %d\r\n"
+ }
+ else PrintMessage(strings[S_Compl]);
+ for(i=0x2000+k2;i<0x2000+dim3;i++) memCODE_W[i]=0x3fff;
+//****************** read eeprom ********************
+ if(dim2){
+ PrintMessage(strings[S_ReadEE]); //Read EEPROM ...
+ if(saveLog) fprintf(logfile,"%s\n",strings[S_ReadEE]); //Read EEPROM ...
+ PrintStatusSetup();
+ if(ee2200){ //eeprom a 0x2200
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=0xFF;
+ bufferU[j++]=INC_ADDR;
+ }
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=0x100-dim3;
+ for(k2=0,i=0x2100;i<0x2100+dim2;i++){
+ bufferU[j++]=READ_DATA_DATA;
+ bufferU[j++]=INC_ADDR;
+ if(j>DIMBUF*2/3-3||i==0x2100+dim2-1){ //2B cmd -> 3B data
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(8);
+ for(z=0;z<DIMBUF-1;z++){
+ if(bufferI[z]==READ_DATA_DATA){
+ memCODE_W[0x2100+k2++]=bufferI[z+1];
+ z++;
+ }
+ }
+ PrintStatus(strings[S_CodeReading],(i-0x2100+dim)*100/(dim+dim2+dim3),i); //"Read: %d%%, addr. %03X"
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k2,k2); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ }
+ }
+ PrintStatusEnd();
+ if(k2!=dim2){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ReadEEErr],dim2,k2); //"Error reading EE area, ..."
+ for(i=0x2100+k2;i<0x2100+dim2;i++) memCODE_W[i]=0x3fff;
+ }
+ else PrintMessage(strings[S_Compl]);
+ }
+ bufferU[j++]=NOP; //exit program mode
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=1; //VDD
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ unsigned int stop=GetTickCount();
+ PrintStatusClear(); //clear status report
+//****************** visualize ********************
+ for(i=0;i<4;i+=2){
+ PrintMessage4("ID%d: 0x%04X\tID%d: 0x%04X\r\n",i,memCODE_W[0x2000+i],i+1,memCODE_W[0x2000+i+1]);
+ }
+ PrintMessage1(strings[S_DevID],memCODE_W[0x2006]); //"DevID: 0x%04X\r\n"
+ if(memCODE_W[0x2005]<0x3FFF) PrintMessage1(strings[S_DevREV],memCODE_W[0x2005]); //"DevREV: 0x%04X\r\n"
+ PIC16_ID(memCODE_W[0x2006]);
+ PrintMessage1(strings[S_ConfigWord],memCODE_W[0x2007]); //"Configuration word: 0x%04X\r\n"
+ if(dim3>8){
+ PrintMessage1(strings[S_Config2Cal1],memCODE_W[0x2008]); //"Config2 or Cal1: 0x%04X\r\n"
+ }
+ if(dim3>9){
+ PrintMessage1(strings[S_Calib1_2],memCODE_W[0x2009]); //"Calibration word 1 or 2: 0x%04X\r\n"
+ }
+ PrintMessage(strings[S_CodeMem2]); //"\r\nCode memory\r\n"
+ DisplayCODE16F(dim);
+ s[0]=0;
+ int valid=0,empty=1;
+ if(dim3>8){
+ aux=(char*)malloc((dim3/COL+1)*(16+COL*5));
+ aux[0]=0;
+ empty=1;
+ PrintMessage(strings[S_ConfigResMem]); //"\r\nConfig and reserved memory:\r\n"
+ for(i=0x2000;i<0x2000+dim3;i+=COL){
+ valid=0;
+ for(j=i;j<i+COL&&j<0x2000+dim3;j++){
+ sprintf(t,"%04X ",memCODE_W[j]);
+ strcat(s,t);
+ if(memCODE_W[j]<0x3fff) valid=1;
+ }
+ if(valid){
+ snprintf(t,sizeof(t),"%04X: %s\r\n",i,s);
+ empty=0;
+ strcat(aux,t);
+ }
+ s[0]=0;
+ }
+ if(empty) PrintMessage(strings[S_Empty]); //empty
+ else PrintMessage(aux);
+ free(aux);
+ }
+ if(dim2){
+ PrintMessage(strings[S_EEMem]); //"\r\nEEPROM memory:\r\n"
+ DisplayEE16F(dim2);
+ }
+ sprintf(str,strings[S_End],(stop-start)/1000.0); //"\r\nEnd (%.2f s)\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+ PrintStatusClear(); //clear status report
+}
+
+void Read16F1xxx(int dim,int dim2,int dim3,int options)
+// read 14 bit enhanced PIC
+// dim=program size (up to 0x8000)
+// dim2=eeprom size (up to 0x400)
+// dim3=config area size @0x8000
+// options:
+// bit0=0 -> vpp before vdd
+// bit0=1 -> vdd before vpp
+// bit1=1 -> LVP programming
+// bit2=1 -> Config3@0x8009
+// bit3=1 -> Config4@0x800A
+// bit4=1 -> PIC16F18xxx (calib words @0xE000 + new commands)
+// DevREV@0x8005 DevID@0x8006
+// Config1@0x8007 Config2@0x8008
+// Config3@0x8009 Config4@0x800A
+// Calib1@0x8009/A Calib2@0x800A/B Calib3@0x800B/C
+// eeprom@0x0 or 0xF000
+{
+ int k=0,k2=0,z=0,i,j;
+ int F18x=options&16;
+ if(F18x&&FWVersion<0xA00){ //only for 16F18xxx
+ PrintMessage1(strings[S_FWver2old],"0.10.0"); //"This firmware is too old. Version %s is required\r\n"
+ return;
+ }
+ if(!CheckV33Regulator()){
+ PrintMessage(strings[S_noV33reg]); //Can't find 3.3V expansion board
+ return;
+ }
+ char s[256],t[256],*aux;
+ if(dim>0x8000||dim<0){
+ PrintMessage(strings[S_CodeLim]); //"Code size exceeds limits\r\n"
+ return;
+ }
+ if(dim2>0x400||dim2<0){ //Max 1K
+ PrintMessage(strings[S_EELim]); //"EEPROM size exceeds limits\r\n"
+ return;
+ }
+ if(dim3>0x200||dim3<0){
+ PrintMessage(strings[S_ConfigLim]); //"Config area size exceeds limits\r\n"
+ return;
+ }
+ if(dim3<11)dim3=11; //at least config1-2 + calib1-2
+ if(saveLog){
+ OpenLogFile(); //"Log.txt"
+ fprintf(logfile,"Read16F1xxx(%d,%d,%d,%d)\n",dim,dim2,dim3,options);
+ }
+ if((options&2)==0){ //HV entry
+ if(!StartHVReg(8.5)){
+ PrintMessage(strings[S_HVregErr]); //"HV regulator error\r\n"
+ return;
+ }
+ else hvreg=8.5;
+ }
+ else StartHVReg(-1); //LVP mode, turn off HV
+ sizeW=0x8200;
+ if(F18x) sizeW=0xE004;
+ sizeEE=dim2;
+ if(memCODE_W) free(memCODE_W);
+ memCODE_W=(WORD*)malloc(sizeof(WORD)*sizeW);
+ for(i=0;i<sizeW;i++) memCODE_W[i]=0x3fff;
+ if(memEE) free(memEE);
+ memEE=(unsigned char*)malloc(sizeEE); //EEPROM
+ for(i=0;i<sizeEE;i++) memEE[i]=0xFF;
+ unsigned int start=GetTickCount();
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T1T2;
+ bufferU[j++]=1; //T1=1u
+ bufferU[j++]=100; //T2=100u
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2000>>8;
+ bufferU[j++]=2000&0xff;
+ bufferU[j++]=EN_VPP_VCC; //enter program mode
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ if((options&2)==0){ //HV entry
+ if((options&1)==0){ //VPP before VDD
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=4; //VPP
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x5; //VDD+VPP
+ }
+ else{ //VDD before VPP without delay
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=1; //VDD
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x5; //VDD+VPP
+ }
+ }
+ else{ //Low voltage programming
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=4; //VPP
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=TX16; //0000 1010 0001 0010 1100 0010 1011 0010 = 0A12C2B2
+ bufferU[j++]=2;
+ bufferU[j++]=0x0A;
+ bufferU[j++]=0x12;
+ bufferU[j++]=0xC2;
+ bufferU[j++]=0xB2;
+ bufferU[j++]=SET_CK_D; //Clock pulse
+ bufferU[j++]=0x4;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+//****************** read code ********************
+ PrintMessage(strings[S_CodeReading1]); //read code ...
+ if(saveLog) fprintf(logfile,"%s\n",strings[S_CodeReading1]); //read code ...
+ PrintStatusSetup();
+ for(i=0,j=0;i<dim;i++){
+ bufferU[j++]=READ_DATA_PROG;
+ bufferU[j++]=INC_ADDR;
+ if(j>DIMBUF*2/4-3||i==dim-1){ //2B cmd -> 4B data
+ bufferU[j++]=FLUSH; //remember: FLUSH generates a response even empty!
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ for(z=0;z<DIMBUF-2;z++){
+ if(bufferI[z]==READ_DATA_PROG){
+ memCODE_W[k++]=(bufferI[z+1]<<8)+bufferI[z+2];
+ z+=2;
+ }
+ }
+ PrintStatus(strings[S_CodeReading],i*100/(dim+dim2+dim3),i); //"Read: %d%%, addr. %03X"
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k,k); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ }
+ }
+ PrintStatusEnd();
+ if(k!=dim){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ReadCodeErr],dim,k); //"Error reading code area, requested %d words, read %d\r\n"
+ }
+ else PrintMessage(strings[S_Compl]);
+//****************** read config area ********************
+ PrintMessage(strings[S_Read_CONFIG_A]); //read config ...
+ if(saveLog) fprintf(logfile,"%s\n",strings[S_Read_CONFIG_A]); //read config ...
+ bufferU[j++]=LOAD_CONF; //counter at 0x8000
+ bufferU[j++]=0xFF;
+ bufferU[j++]=0xFF;
+ for(i=0x8000;i<0x8000+dim3;i++){ //Config
+ bufferU[j++]=READ_DATA_PROG;
+ bufferU[j++]=INC_ADDR;
+ if(j>DIMBUF*2/4-3||i==0x8000+dim3-1){ //2B cmd -> 4B data
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ for(z=0;z<DIMBUF-2;z++){
+ if(bufferI[z]==READ_DATA_PROG){
+ memCODE_W[0x8000+k2++]=(bufferI[z+1]<<8)+bufferI[z+2];
+ z+=2;
+ }
+ }
+ PrintStatus(strings[S_CodeReading],(i-0x8000+dim)*100/(dim+dim2+dim3),i); //"Read: %d%%, addr %03X"
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k2,k2); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ }
+ }
+ if(k2!=dim3){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ConfigErr],dim3,k2); //"Error reading config area, requested %d words, read %d\r\n"
+ }
+ else PrintMessage(strings[S_Compl]);
+// for(i=0x8000+k2;i<0x8000+dim3;i++) memCODE_W[i]=0x3fff;
+//****************** read calibration area ********************
+ if(F18x){
+ k2=0;
+ PrintMessage(strings[S_Read_CONFIG_A]); //read config ...
+ bufferU[j++]=LOAD_PC; //counter at 0xE000
+ bufferU[j++]=0xE0;
+ bufferU[j++]=0x00;
+ for(i=0;i<4;i++) bufferU[j++]=READ_DATA_INC;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ for(z=0;z<DIMBUF-2;z++){
+ if(bufferI[z]==READ_DATA_INC){
+ memCODE_W[0xE000+k2++]=(bufferI[z+1]<<8)+bufferI[z+2];
+ z+=2;
+ }
+ }
+ j=0;
+ if(saveLog){
+ fprintf(logfile,"Calibration area @0xE000\n");
+ }
+ if(k2!=4){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ConfigErr],dim3,k2); //"Error reading config area, requested %d words, read %d\r\n"
+ }
+ else PrintMessage(strings[S_Compl]);
+ }
+//****************** read eeprom ********************
+ if(dim2&&!F18x){ //16F1xxx
+ PrintMessage(strings[S_ReadEE]); //Read EEPROM ...
+ if(saveLog) fprintf(logfile,"%s\n",strings[S_ReadEE]); //Read EEPROM ...
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x16; //Reset address
+ for(i=k=0;i<dim2;i++){
+ bufferU[j++]=READ_DATA_DATA;
+ bufferU[j++]=INC_ADDR;
+ if(j>DIMBUF*2/3-3||i==dim2-1){ //2B cmd -> 3B data
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ for(z=0;z<DIMBUF-1;z++){
+ if(bufferI[z]==READ_DATA_DATA){
+ memEE[k++]=bufferI[z+1];
+ z++;
+ }
+ }
+ PrintStatus(strings[S_CodeReading],i*100/(dim+dim2+dim3),i); //"Read: %d%%, addr %03X"
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k,k); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ }
+ }
+ PrintStatusEnd();
+ if(i!=dim2){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ReadEEErr],dim2,i); //"Error reading EE area, ..."
+ for(;i<dim2;i++) memEE[i]=0xff;
+ }
+ else PrintMessage(strings[S_Compl]);
+ }
+ else if(dim2&&F18x){ //16F18xxx
+ PrintMessage(strings[S_ReadEE]); //Read EEPROM ...
+ if(saveLog) fprintf(logfile,"%s\n",strings[S_ReadEE]); //Read EEPROM ...
+ bufferU[j++]=LOAD_PC; //counter at 0xF000
+ bufferU[j++]=0xF0;
+ bufferU[j++]=0x00;
+ for(i=k=0;i<dim2;i++){
+ bufferU[j++]=READ_DATA_INC;
+ if(j>DIMBUF/3-3||i==dim2-1){ //1B cmd -> 3B answer
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ for(z=0;z<DIMBUF-1;z++){
+ if(bufferI[z]==READ_DATA_INC){
+ memEE[k++]=bufferI[z+2]; //LSB
+ z+=2;
+ }
+ }
+ PrintStatus(strings[S_CodeReading],i*100/(dim+dim2+dim3),i); //"Read: %d%%, addr %03X"
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k,k); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ }
+ }
+ PrintStatusEnd();
+ if(i!=dim2){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ReadEEErr],dim2,i); //"Error reading EE area, ..."
+ for(;i<dim2;i++) memEE[i]=0xff;
+ }
+ else PrintMessage(strings[S_Compl]);
+ }
+/***********************************/
+ bufferU[j++]=NOP; //exit program mode
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=1; //VDD
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ unsigned int stop=GetTickCount();
+ PrintStatusClear(); //clear status report
+//****************** visualize ********************
+ for(i=0;i<4;i+=2){
+ PrintMessage4("ID%d: 0x%04X\tID%d: 0x%04X\r\n",i,memCODE_W[0x8000+i],i+1,memCODE_W[0x8000+i+1]);
+ }
+ PrintMessage1(strings[S_DevID],memCODE_W[0x8006]); //"DevID: 0x%04X\r\n"
+ if(memCODE_W[0x8005]<0x3FFF) PrintMessage1(strings[S_DevREV],memCODE_W[0x8005]); //"DevREV: 0x%04X\r\n"
+ PIC16_ID(memCODE_W[0x8006]);
+ PrintMessage2(strings[S_ConfigWordX],1,memCODE_W[0x8007]); //"Configuration word %d: 0x%04X\r\n"
+ PrintMessage2(strings[S_ConfigWordX],2,memCODE_W[0x8008]); //"Configuration word %d: 0x%04X\r\n"
+ if((options&0xC)==0&&F18x==0){ //2 config + 2/3 calib words
+ PrintMessage2(strings[S_CalibWordX],1,memCODE_W[0x8009]); //"Calibration word %d: 0x%04X\r\n"
+ PrintMessage2(strings[S_CalibWordX],2,memCODE_W[0x800A]); //"Calibration word %d: 0x%04X\r\n"
+ if(memCODE_W[0x800B]<0x3FFF) PrintMessage2(strings[S_CalibWordX],3,memCODE_W[0x800B]); //"Calibration word %d: 0x%04X\r\n"
+ }
+ else if((options&0xC)==4&&F18x==0){ //3 config + 3 calib words
+ PrintMessage2(strings[S_ConfigWordX],3,memCODE_W[0x8009]); //"Configuration word %d: 0x%04X\r\n"
+ PrintMessage2(strings[S_CalibWordX],1,memCODE_W[0x800A]); //"Calibration word %d: 0x%04X\r\n"
+ PrintMessage2(strings[S_CalibWordX],2,memCODE_W[0x800B]); //"Calibration word %d: 0x%04X\r\n"
+ PrintMessage2(strings[S_CalibWordX],3,memCODE_W[0x800C]); //"Calibration word %d: 0x%04X\r\n"
+ }
+ else if((options&0xC)==8){ //4 config
+ PrintMessage2(strings[S_ConfigWordX],3,memCODE_W[0x8009]); //"Configuration word %d: 0x%04X\r\n"
+ PrintMessage2(strings[S_ConfigWordX],4,memCODE_W[0x800A]); //"Configuration word %d: 0x%04X\r\n"
+ }
+ if(F18x){ //4 calib words @0xE000
+ PrintMessage2(strings[S_CalibWordX],1,memCODE_W[0xE000]); //"Calibration word %d: 0x%04X\r\n"
+ PrintMessage2(strings[S_CalibWordX],2,memCODE_W[0xE001]); //"Calibration word %d: 0x%04X\r\n"
+ PrintMessage2(strings[S_CalibWordX],3,memCODE_W[0xE002]); //"Calibration word %d: 0x%04X\r\n"
+ PrintMessage2(strings[S_CalibWordX],4,memCODE_W[0xE003]); //"Calibration word %d: 0x%04X\r\n"
+ }
+ PrintMessage(strings[S_CodeMem2]); //"\r\nCode memory:\r\n"
+ DisplayCODE16F(dim);
+ if(dim3>15){
+ int valid=0,empty=1;
+ s[0]=0;
+ aux=(char*)malloc(dim3/COL*(16+COL*5));
+ aux[0]=0;
+ empty=1;
+ PrintMessage(strings[S_ConfigResMem]); //"\r\nConfig and reserved memory:\r\n"
+ for(i=0x8000;i<0x8000+dim3;i+=COL){
+ valid=0;
+ for(j=i;j<i+COL&&j<0x8000+dim3;j++){
+ sprintf(t,"%04X ",memCODE_W[j]);
+ strcat(s,t);
+ if(memCODE_W[j]<0x3fff) valid=1;
+ }
+ if(valid){
+ sprintf(t,"%04X: %s\r\n",i,s);
+ empty=0;
+ strcat(aux,t);
+ }
+ s[0]=0;
+ }
+ if(empty) PrintMessage(strings[S_Empty]); //empty
+ else PrintMessage(aux);
+ free(aux);
+ }
+ if(dim2) DisplayEE(); //visualize
+ sprintf(str,strings[S_End],(stop-start)/1000.0); //"\r\nEnd (%.2f s)\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+ PrintStatusClear(); //clear status report
+}
+
+#define LOAD_PC_ADDR 0x80
+#define BULK_ERASE_PROGRAM_MEM 0x18
+#define ROW_ERASE_PROGRAM_MEM 0xF0
+#define LOAD_NVM 0x00
+#define LOAD_NVM_INC 0x02
+#define READ_NVM 0xFC
+#define READ_NVM_INC 0xFE
+#define INC_ADDR8 0xF8
+#define BEGIN_INT_PROG 0xE0
+#define BEGIN_EXT_PROG 0xC0
+#define END_EXT_PROG 0x82
+
+void Read16F18xxx(int dim,int dim2,int dim3,int options)
+// read 14 bit enhanced PIC with new 8b commands
+// dim=program size (up to 0x8000)
+// dim2=if>0 use eeprom, size is automatic when reading DCI
+// dim3=not used
+// options:
+// bit0=0 -> vpp before vdd
+// bit0=1 -> vdd before vpp
+// bit1=1 -> LVP programming
+// bit4=1 -> do not use DIA&DCI
+// DevREV@0x8005 DevID@0x8006
+// Config1@0x8007 Config2@0x8008 ...
+// Device info area @0x8100
+// Device configuration info area @0x8200
+{
+ int k=0,k2=0,z=0,i,j;
+ int useDCI=(options&0x10)==0?1:0;
+ if(FWVersion<0xB00){ //only for 16F18xxx
+ PrintMessage1(strings[S_FWver2old],"0.11.0"); //"This firmware is too old. Version %s is required\r\n"
+ return;
+ }
+ if(!CheckV33Regulator()){
+ PrintMessage(strings[S_noV33reg]); //Can't find 3.3V expansion board
+ return;
+ }
+ char s[256],t[256],*aux;
+ if(dim>0x8000||dim<0){
+ PrintMessage(strings[S_CodeLim]); //"Code size exceeds limits\r\n"
+ return;
+ }
+ if(saveLog){
+ OpenLogFile(); //"Log.txt"
+ fprintf(logfile,"Read16F18xxx(%d,%d,%d,%d)\n",dim,dim2,dim3,options);
+ }
+ if((options&2)==0){ //HV entry
+ if(!StartHVReg(8.5)){
+ PrintMessage(strings[S_HVregErr]); //"HV regulator error\r\n"
+ return;
+ }
+ else hvreg=8.5;
+ }
+ else StartHVReg(-1); //LVP mode, turn off HV
+ sizeW=0x8220;
+ if(memCODE_W) free(memCODE_W);
+ memCODE_W=(WORD*)malloc(sizeof(WORD)*sizeW);
+ for(i=0;i<sizeW;i++) memCODE_W[i]=0x3fff;
+ unsigned int start=GetTickCount();
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T1T2;
+ bufferU[j++]=1; //T1=1u
+ bufferU[j++]=100; //T2=100u
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2000>>8;
+ bufferU[j++]=2000&0xff;
+ bufferU[j++]=EN_VPP_VCC; //enter program mode
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ if((options&2)==0){ //HV entry
+ if((options&1)==0){ //VPP before VDD
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=4; //VPP
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x5; //VDD+VPP
+ }
+ else{ //VDD before VPP without delay
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=1; //VDD
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x5; //VDD+VPP
+ }
+ }
+ else{ //Low voltage programming
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=4; //VPP
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=TX16; //0000 1010 0001 0010 1100 0010 1011 0010 = 0A12C2B2
+ bufferU[j++]=2;
+ bufferU[j++]=0x0A;
+ bufferU[j++]=0x12;
+ bufferU[j++]=0xC2;
+ bufferU[j++]=0xB2;
+ bufferU[j++]=SET_CK_D; //Clock pulse
+ bufferU[j++]=0x4;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+//****************** read code ********************
+ PrintMessage(strings[S_CodeReading1]); //read code ...
+ if(saveLog) fprintf(logfile,"%s\n",strings[S_CodeReading1]); //read code ...
+ PrintStatusSetup();
+ for(i=0,j=0;i<dim;i++){
+ bufferU[j++]=ICSP8_READ;
+ bufferU[j++]=READ_NVM_INC;
+ if((j+1)/2*3+3>DIMBUF||i==dim-1){ //2B cmd -> 3B data
+ bufferU[j++]=FLUSH; //remember: FLUSH generates a response (even empty)!
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ for(z=0;z<DIMBUF-2;z++){
+ if(bufferI[z]==ICSP8_READ){
+ memCODE_W[k++]=(bufferI[z+1]<<8)+bufferI[z+2];
+ z+=2;
+ }
+ }
+ PrintStatus(strings[S_CodeReading],i*100/(dim+dim2+0x60),i); //"Read: %d%%, addr. %03X"
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k,k); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ }
+ }
+ PrintStatusEnd();
+ if(k!=dim){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ReadCodeErr],dim,k); //"Error reading code area, requested %d words, read %d\r\n"
+ }
+ else PrintMessage(strings[S_Compl]);
+//****************** read config area ********************
+ PrintMessage(strings[S_Read_CONFIG_A]); //read config ...
+ if(saveLog) fprintf(logfile,"%s\n",strings[S_Read_CONFIG_A]); //read config ...
+ bufferU[j++]=ICSP8_LOAD; //counter at 0x8000
+ bufferU[j++]=LOAD_PC_ADDR;
+ bufferU[j++]=0x80;
+ bufferU[j++]=0x00;
+ k2=0;
+ for(i=0x8000;i<0x8010;i++){ //Config
+ bufferU[j++]=ICSP8_READ;
+ bufferU[j++]=READ_NVM_INC;
+ if((j+1)/2*3+3>DIMBUF||i==0x800F){ //2B cmd -> 3B data
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ for(z=0;z<DIMBUF-2;z++){
+ if(bufferI[z]==ICSP8_READ){
+ memCODE_W[0x8000+k2++]=(bufferI[z+1]<<8)+bufferI[z+2];
+ z+=2;
+ }
+ }
+ PrintStatus(strings[S_CodeReading],(i-0x8000+dim)*100/(dim+dim2+0x60),i); //"Read: %d%%, addr %03X"
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k2,k2); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ }
+ }
+ if(k2!=0x10){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ConfigErr],0x10,k2); //"Error reading config area, requested %d words, read %d\r\n"
+ }
+ else PrintMessage(strings[S_Compl]);
+//****************** read device info area ********************
+ if(useDCI){ //if not disabled
+ if(saveLog) fprintf(logfile,"Read device info area @0x8100\n");
+ bufferU[j++]=ICSP8_LOAD; //counter at 0x8000
+ bufferU[j++]=LOAD_PC_ADDR;
+ bufferU[j++]=0x81;
+ bufferU[j++]=0x00;
+ k2=0;
+ for(i=0x8100;i<0x8120;i++){ //DIA
+ bufferU[j++]=ICSP8_READ;
+ bufferU[j++]=READ_NVM_INC;
+ if((j+1)/2*3+3>DIMBUF||i==0x811F){ //2B cmd -> 3B data
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ for(z=0;z<DIMBUF-2;z++){
+ if(bufferI[z]==ICSP8_READ){
+ memCODE_W[0x8100+k2++]=(bufferI[z+1]<<8)+bufferI[z+2];
+ z+=2;
+ }
+ }
+ PrintStatus(strings[S_CodeReading],(i-0x8100+dim+0x20)*100/(dim+dim2+0x60),i); //"Read: %d%%, addr %03X"
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k2,k2); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ }
+ }
+ if(k2!=0x20){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ConfigErr],0x20,k2); //"Error reading config area, requested %d words, read %d\r\n"
+ }
+ //****************** read calibration area (Device Configuration Information) ********************
+ if(saveLog) fprintf(logfile,"Read Device Configuration Information @0x8200\n");
+ bufferU[j++]=ICSP8_LOAD; //counter at 0x8200
+ bufferU[j++]=LOAD_PC_ADDR;
+ bufferU[j++]=0x82;
+ bufferU[j++]=0x00;
+ k2=0;
+ for(i=0x8200;i<0x8220;i++){ //DCI
+ bufferU[j++]=ICSP8_READ;
+ bufferU[j++]=READ_NVM_INC;
+ if((j+1)/2*3+3>DIMBUF||i==0x821F){ //2B cmd -> 3B data
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ for(z=0;z<DIMBUF-2;z++){
+ if(bufferI[z]==ICSP8_READ){
+ memCODE_W[0x8200+k2++]=(bufferI[z+1]<<8)+bufferI[z+2];
+ z+=2;
+ }
+ }
+ PrintStatus(strings[S_CodeReading],(i-0x8200+dim+0x40)*100/(dim+dim2+0x60),i); //"Read: %d%%, addr %03X"
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k2,k2); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ }
+ }
+ if(k2!=0x20){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ConfigErr],0x20,k2); //"Error reading config area, requested %d words, read %d\r\n"
+ }
+ }
+//****************** read eeprom ********************
+ if(dim2){ //EEPROM
+ if(useDCI) dim2=memCODE_W[0x8203]; //EEPROM size from DCI
+ if(dim2>0x1000||dim2<0){ //Max 4K
+ PrintMessage(strings[S_EELim]); //"EEPROM size exceeds limits\r\n"
+ return;
+ }
+ sizeEE=dim2;
+ if(memEE) free(memEE);
+ memEE=(unsigned char*)malloc(sizeEE); //EEPROM
+ for(i=0;i<sizeEE;i++) memEE[i]=0xFF;
+ PrintMessage(strings[S_ReadEE]); //Read EEPROM ...
+ if(saveLog) fprintf(logfile,"%s\n",strings[S_ReadEE]); //Read EEPROM ...
+ bufferU[j++]=ICSP8_LOAD; //counter at 0xF000
+ bufferU[j++]=LOAD_PC_ADDR;
+ bufferU[j++]=0xF0;
+ bufferU[j++]=0x00;
+ for(i=k=0;i<dim2;i++){
+ bufferU[j++]=ICSP8_READ;
+ bufferU[j++]=READ_NVM_INC;
+ if((j+1)/2*3+3>DIMBUF||i==dim2-1){ //2B cmd -> 3B answer
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ for(z=0;z<DIMBUF-2;z++){
+ if(bufferI[z]==ICSP8_READ){
+ memEE[k++]=bufferI[z+2]; //LSB
+ z+=2;
+ }
+ }
+ PrintStatus(strings[S_CodeReading],i*100+dim+0x60/(dim+dim2+0x60),i); //"Read: %d%%, addr %03X"
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k,k); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ }
+ }
+ PrintStatusEnd();
+ if(i!=dim2){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ReadEEErr],dim2,i); //"Error reading EE area, ..."
+ for(;i<dim2;i++) memEE[i]=0xff;
+ }
+ else PrintMessage(strings[S_Compl]);
+ }
+/***********************************/
+ bufferU[j++]=NOP; //exit program mode
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=1; //VDD
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ unsigned int stop=GetTickCount();
+ PrintStatusClear(); //clear status report
+//****************** visualize ********************
+ for(i=0;i<4;i+=2){
+ PrintMessage4("ID%d: 0x%04X\tID%d: 0x%04X\r\n",i,memCODE_W[0x8000+i],i+1,memCODE_W[0x8000+i+1]);
+ }
+ PrintMessage1(strings[S_DevID],memCODE_W[0x8006]); //"DevID: 0x%04X\r\n"
+ if(memCODE_W[0x8005]<0x3FFF) PrintMessage1(strings[S_DevREV],memCODE_W[0x8005]); //"DevREV: 0x%04X\r\n"
+ PIC16_ID(memCODE_W[0x8006]);
+ for(i=0;i<5;i++){
+ PrintMessage2(strings[S_ConfigWordX],i+1,memCODE_W[0x8007+i]); //"Configuration word %d: 0x%04X\r\n"
+ }
+ if(useDCI){ //if not disabled
+ PrintMessage("Device Information Area @0x8100\r\n");
+ s[0]=0;
+ for(i=0;i<0x20;i+=COL){
+ sprintf(t,"%04X: ",0x8100+i);
+ strcat(s,t);
+ for(j=i;j<i+COL&&j<0x20;j++){
+ sprintf(t,"%04X ",memCODE_W[0x8100+j]);
+ strcat(s,t);
+ }
+ strcat(s,"\r\n");
+ }
+ PrintMessage(s);
+ PrintMessage("Device Configuration Information @0x8200\r\n");
+ s[0]=0;
+ for(i=0;i<0x20;i+=COL){
+ sprintf(t,"%04X: ",0x8200+i);
+ strcat(s,t);
+ for(j=i;j<i+COL&&j<0x20;j++){
+ sprintf(t,"%04X ",memCODE_W[0x8200+j]);
+ strcat(s,t);
+ }
+ strcat(s,"\r\n");
+ }
+ PrintMessage(s);
+ PrintMessage1("Erase row size: %d words\r\n",memCODE_W[0x8200]);
+ PrintMessage1("Write latches: %d\r\n",memCODE_W[0x8201]);
+ PrintMessage1("User rows: %d\r\n",memCODE_W[0x8202]);
+ PrintMessage1("->%d Flash words\r\n",memCODE_W[0x8200]*memCODE_W[0x8202]);
+ PrintMessage1("EE data memory size: %d\r\n",memCODE_W[0x8203]);
+ PrintMessage1("Pin count: %d\r\n",memCODE_W[0x8204]);
+ if(dim!=memCODE_W[0x8200]*memCODE_W[0x8202]) PrintMessage(strings[S_WarnFlashSize]); //"Warning, flash size is different from the expected value"
+ }
+ PrintMessage(strings[S_CodeMem2]); //"\r\nCode memory:\r\n"
+ DisplayCODE16F(dim);
+ if(dim2) DisplayEE(); //visualize
+ sprintf(str,strings[S_End],(stop-start)/1000.0); //"\r\nEnd (%.2f s)\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+ PrintStatusClear(); //clear status report
+}
+
+void Write12F6xx(int dim,int dim2)
+// write 14 bit PIC
+// dim=program size dim2=eeprom size
+// vpp before vdd
+// DevID@0x2006
+// Config@0x2007
+// Calib1@0x2008 (save)
+// Calib2@0x2009 (save)
+// eeprom@0x2100
+// erase: BULK_ERASE_PROG (1001) +10ms
+// write:LOAD_DATA_PROG (0010) + BEGIN_PROG (1000) + 4ms
+// eeprom: BULK_ERASE_DATA (1011) + 16ms
+// LOAD_DATA_DATA (0011) + BEGIN_PROG (1000) + 8ms
+// verify during write
+{
+ int err=0;
+ WORD devID=0x3fff,calib1=0x3fff,calib2=0x3fff;
+ int k=0,z=0,i,j,w;
+ if(sizeW<0x2007){
+ PrintMessage(strings[S_NoConfigW3]); //"Can't find CONFIG (0x2007)\r\nEnd\r\n"
+ return;
+ }
+ if(load_calibword){
+ if(sizeW>0x2009) load_calibword=2;
+ else if(sizeW>0x2008) load_calibword=1;
+ else{
+ PrintMessage(strings[S_NoCalibW]); //"Can't find calibration data\r\n"
+ load_calibword=0;
+ }
+ }
+ if(dim2){
+ if(sizeW<0x2100){
+ dim2=0;
+ PrintMessage(strings[S_NoEEMem]); //"Can't find EEPROM data\r\n"
+ }
+ else if(dim2>sizeW-0x2100) dim2=sizeW-0x2100;
+ }
+ if(saveLog){
+ OpenLogFile(); //"log.txt"
+ fprintf(logfile,"Write12F6xx(%d,%d)\n",dim,dim2);
+ }
+ for(i=0;i<0x2009&&i<sizeW;i++) memCODE_W[i]&=0x3FFF;
+ unsigned int start=GetTickCount();
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T1T2;
+ bufferU[j++]=1; //T1=1u
+ bufferU[j++]=100; //T2=100u
+ bufferU[j++]=EN_VPP_VCC; //enter program mode
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=EN_VPP_VCC; //VPP
+ bufferU[j++]=0x4;
+ bufferU[j++]=NOP;
+ bufferU[j++]=EN_VPP_VCC; //VDD+VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=NOP;
+ bufferU[j++]=LOAD_CONF; //counter at 0x2000
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=0x06;
+ bufferU[j++]=READ_DATA_PROG; //DevID
+ bufferU[j++]=INC_ADDR;
+ bufferU[j++]=INC_ADDR;
+ bufferU[j++]=READ_DATA_PROG; //Calib1
+ bufferU[j++]=INC_ADDR;
+ bufferU[j++]=READ_DATA_PROG; //Calib2
+ bufferU[j++]=NOP; //exit program mode
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=10000>>8;
+ bufferU[j++]=10000&0xff;
+ bufferU[j++]=WAIT_T3; //delay after exiting prog mode
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(15);
+ for(z=0;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ devID=(bufferI[z+1]<<8)+bufferI[z+2];
+ PrintMessage1(strings[S_DevID],devID); //"DevID: 0x%04X\r\n"
+ PIC16_ID(devID);
+ for(z+=3;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ calib1=(bufferI[z+1]<<8)+bufferI[z+2];
+ if(calib1<0x3fff){
+ PrintMessage1(strings[S_CalibWord1],calib1); //"Calib1: 0x%04X\r\n"
+ }
+ for(z+=3;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ calib2=(bufferI[z+1]<<8)+bufferI[z+2];
+ if(calib2<0x3fff){
+ PrintMessage1(strings[S_CalibWord2],calib2); //"Calib2: 0x%04X\r\n"
+ }
+//****************** erase memory ********************
+ PrintMessage(strings[S_StartErase]); //"Erase ... "
+ j=0;
+ bufferU[j++]=EN_VPP_VCC; //VPP
+ bufferU[j++]=0x4;
+ bufferU[j++]=NOP;
+ bufferU[j++]=EN_VPP_VCC; //VDD+VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=WAIT_T3; //necessary when erasing fully written 16F62xA
+ //not mentioned in the prog spec!
+ if(programID||load_calibword||ICDenable){
+ bufferU[j++]=LOAD_CONF; //counter at 0x2000
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=0xFF; //fake config
+ if(load_calibword){
+ bufferU[j++]=INC_ADDR_N;
+ if(load_calibword==2) bufferU[j++]=0x09;
+ else bufferU[j++]=0x08;
+ }
+ }
+ bufferU[j++]=LOAD_DATA_PROG;
+ bufferU[j++]=0xFF;
+ bufferU[j++]=0xFF;
+ bufferU[j++]=BULK_ERASE_PROG;
+ bufferU[j++]=WAIT_T3; // delay T3=10ms
+ if(dim2){
+ bufferU[j++]=BULK_ERASE_DATA;
+ bufferU[j++]=WAIT_T3; // delay T3=10ms
+ }
+ bufferU[j++]=EN_VPP_VCC; //exit program mode
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=WAIT_T3; // delay T3=10ms
+ bufferU[j++]=EN_VPP_VCC; //enter program mode
+ bufferU[j++]=0x4;
+ bufferU[j++]=NOP;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x5;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=4000>>8;
+ bufferU[j++]=4000&0xff;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(50);
+ PrintMessage(strings[S_Compl]); //"completed\r\n"
+//****************** write code ********************
+ PrintMessage(strings[S_StartCodeProg]); //"Write code ... "
+ PrintStatusSetup();
+ for(w=i=k=0,j=0;i<dim;i++){
+ if(memCODE_W[i]<0x3fff){
+ bufferU[j++]=LOAD_DATA_PROG;
+ bufferU[j++]=memCODE_W[i]>>8; //MSB
+ bufferU[j++]=memCODE_W[i]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG; //internally timed, T=3ms min
+ bufferU[j++]=WAIT_T3; //Tprogram 4ms
+ bufferU[j++]=READ_DATA_PROG;
+ w++;
+ }
+ bufferU[j++]=INC_ADDR;
+ if(j>DIMBUF-12||i==dim-1){
+ PrintStatus(strings[S_CodeWriting],i*100/dim,i); //"Writing: %d%%, add. %03X"
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(w*5+2);
+ w=0;
+ for(z=0;z<DIMBUF-5;z++){
+ if(bufferI[z]==INC_ADDR&&memCODE_W[k]>=0x3fff) k++;
+ else if(bufferI[z]==LOAD_DATA_PROG&&bufferI[z+3]==READ_DATA_PROG){
+ if (memCODE_W[k]!=(bufferI[z+4]<<8)+bufferI[z+5]){
+ PrintMessage("\r\n");
+ PrintMessage3(strings[S_CodeWError2],k,memCODE_W[k],(bufferI[z+4]<<8)+bufferI[z+5]); //"Error writing address %3X: written %04X, read %04X\r\n"
+ err++;
+ if(max_err&&err>max_err){
+ PrintMessage1(strings[S_MaxErr],err); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ PrintMessage(strings[S_IntW]); //"Write interrupted"
+ i=dim;
+ z=DIMBUF;
+ }
+ }
+ k++;
+ z+=6;
+ }
+ }
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,err); //"i=%d, k=%d, errors=%d,\n"
+ }
+ }
+ }
+ err+=i-k;
+ PrintStatusEnd();
+ PrintMessage1(strings[S_ComplErr],err); //"completed, %d errors\r\n"
+//****************** write eeprom ********************
+ if(dim2){
+ int err_e=0;
+ PrintMessage(strings[S_EEAreaW]); //"Writing EEPROM ... "
+ PrintStatusSetup();
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=8000>>8;
+ bufferU[j++]=8000&0xff;
+ bufferU[j++]=BULK_ERASE_DATA;
+ bufferU[j++]=WAIT_T3; // delay T3=8ms
+ bufferU[j++]=LOAD_CONF; //counter at 0x2000
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=INC_ADDR_N; //use only INC_ADDR_N so verification does not look at it
+ bufferU[j++]=1;
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=0x2100-0x2001; //EEPROM area: counter at 0x2100
+ for(w=2,i=k=0x2100;i<0x2100+dim2;i++){
+ if(memCODE_W[i]<0xff){
+ bufferU[j++]=LOAD_DATA_DATA;
+ bufferU[j++]=memCODE_W[i]&0xff;
+ bufferU[j++]=BEGIN_PROG; //internally timed, T=6ms min
+ bufferU[j++]=WAIT_T3; //Tprogram 8ms
+ bufferU[j++]=READ_DATA_DATA;
+ w++;
+ }
+ bufferU[j++]=INC_ADDR;
+ if(j>DIMBUF-12||i==0x2100+dim2-1){
+ PrintStatus(strings[S_CodeWriting],(i-0x2100+dim)*100/(dim+dim2),i); //"Writing: %d%%, add. %03X"
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(w*9+2);
+ w=0;
+ for(z=0;z<DIMBUF-4;z++){
+ if(bufferI[z]==INC_ADDR&&memCODE_W[k]>=0xff) k++;
+ else if(bufferI[z]==LOAD_DATA_DATA&&bufferI[z+3]==READ_DATA_DATA){
+ if (memCODE_W[k]!=bufferI[z+4]){
+ PrintMessage("\r\n");
+ PrintMessage3(strings[S_CodeWError3],k,memCODE_W[k],bufferI[z+4]); //"Error writing address %4X: written %02X, read %02X\r\n"
+ err_e++;
+ if(max_err&&err+err_e>max_err){
+ PrintMessage1(strings[S_MaxErr],err+err_e); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ PrintMessage(strings[S_IntW]); //"Write interrupted"
+ i=0x2200;
+ z=DIMBUF;
+ }
+ }
+ k++;
+ z+=5;
+ }
+ }
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,err); //"i=%d, k=%d, errors=%d \n"
+ }
+ }
+ }
+ err_e+=i-k;
+ err+=err_e;
+ PrintStatusEnd();
+ PrintMessage1(strings[S_ComplErr],err_e); //"completed, %d errors\r\n"
+ }
+//****************** write ID, CONFIG, CALIB ********************
+ PrintMessage(strings[S_ConfigAreaW]); //"Writing CONFIG area ... "
+ int err_c=0;
+ int ICDgoto=0x2800+(ICDaddr&0x7FF); //GOTO ICD routine (0x28xx)
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=4000>>8;
+ bufferU[j++]=4000&0xff;
+ bufferU[j++]=LOAD_CONF; //counter at 0x2000
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=0xFF; //fake config
+ if(programID){
+ for(i=0x2000;i<0x2004;i++){
+ bufferU[j++]=LOAD_DATA_PROG;
+ bufferU[j++]=memCODE_W[i]>>8; //MSB
+ bufferU[j++]=memCODE_W[i]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG; //internally timed, T=3ms min
+ bufferU[j++]=WAIT_T3; //Tprogram 4ms
+ bufferU[j++]=READ_DATA_PROG;
+ bufferU[j++]=INC_ADDR;
+ }
+ }
+ else{
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=4;
+ }
+ if(ICDenable){ //write a GOTO ICD routine (0x28xx)
+ bufferU[j++]=LOAD_DATA_PROG;
+ bufferU[j++]=ICDgoto>>8; //MSB
+ bufferU[j++]=ICDgoto&0xFF; //LSB
+ bufferU[j++]=BEGIN_PROG; //internally timed, T=3ms min
+ bufferU[j++]=WAIT_T3; //Tprogram
+ bufferU[j++]=READ_DATA_PROG;
+ }
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=3;
+ bufferU[j++]=LOAD_DATA_PROG; //Config word 0x2007
+ bufferU[j++]=memCODE_W[0x2007]>>8; //MSB
+ bufferU[j++]=memCODE_W[0x2007]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG; //internally timed, T=3ms min
+ bufferU[j++]=WAIT_T3; //Tprogram 4ms
+ bufferU[j++]=READ_DATA_PROG;
+ bufferU[j++]=INC_ADDR;
+ if(load_calibword){
+ bufferU[j++]=LOAD_DATA_PROG; //Calib word 1
+ bufferU[j++]=memCODE_W[0x2008]>>8; //MSB
+ bufferU[j++]=memCODE_W[0x2008]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG; //internally timed, T=3ms min
+ bufferU[j++]=WAIT_T3; //Tprogram 4ms
+ bufferU[j++]=READ_DATA_PROG;
+ bufferU[j++]=INC_ADDR;
+ bufferU[j++]=LOAD_DATA_PROG; //Calib word 2
+ bufferU[j++]=memCODE_W[0x2009]>>8; //MSB
+ bufferU[j++]=memCODE_W[0x2009]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG; //internally timed, T=3ms min
+ bufferU[j++]=WAIT_T3; //Tprogram 4ms
+ bufferU[j++]=READ_DATA_PROG;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(35);
+ for(i=0,z=0;programID&&i<4;i++){
+ for(;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if (memCODE_W[0x2000+i]!=(bufferI[z+1]<<8)+bufferI[z+2]){
+ PrintMessage("\r\n");
+ PrintMessage3(strings[S_IDErr],i,memCODE_W[0x2000+i],(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing ID%d: written %04X, read %04X\r\n"
+ err_c++;
+ }
+ z+=6;
+ }
+ if(ICDenable){
+ for(;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if (ICDgoto!=(bufferI[z+1]<<8)+bufferI[z+2]){
+ PrintMessage4(strings[S_ICDErr],0x2004,i,ICDgoto,(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing ICD (0x%X): written %04X, read %04X\r\n"
+ err_c++;
+ }
+ z+=6;
+ }
+ for(;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if(~memCODE_W[0x2007]&((bufferI[z+1]<<8)+bufferI[z+2])){ //error if written 0 and read 1 (~W&R)
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ConfigWErr3],memCODE_W[0x2007],(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing config area: written %04X, read %04X\r\n"
+ err_c++;
+ }
+ if(load_calibword){
+ for(z+=6;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if (memCODE_W[0x2008]!=(bufferI[z+1]<<8)+bufferI[z+2]){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_Calib1Err],memCODE_W[0x2008],(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing Calib1: written %04X, read %04X\r\n"
+ err_c++;
+ }
+ if(load_calibword==2){
+ for(z+=6;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if (memCODE_W[0x2009]!=(bufferI[z+1]<<8)+bufferI[z+2]){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_Calib2Err],memCODE_W[0x2009],(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing Calib2: written %04X, read %04X\r\n"
+ err_c++;
+ }
+ }
+ }
+ err+=err_c;
+ PrintMessage1(strings[S_ComplErr],err_c); //"completed, %d errors\r\n"
+ if(saveLog){
+ fprintf(logfile,strings[S_Log9],err); //"Area config. errors=%d \n"
+ }
+//****************** exit ********************
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2000>>8;
+ bufferU[j++]=2000&0xff;
+ bufferU[j++]=NOP; //exit program mode
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ unsigned int stop=GetTickCount();
+ sprintf(str,strings[S_EndErr],(stop-start)/1000.0,err,err!=1?strings[S_ErrPlur]:strings[S_ErrSing]); //"\r\nEnd (%.2f s) %d %s\r\n\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+ PrintStatusClear(); //clear status report
+}
+
+void Write16F8x (int dim,int dim2)
+// write 14 bit PIC
+// dim=program size dim2=eeprom size
+// vdd + 50ms + vdd&vpp
+// DevID@0x2006
+// Config@0x2007
+// eeprom@0x2100
+// erase if protected:
+// LOAD_CONF (0)(0x3FFF) + CUST_CMD (0001) + CUST_CMD (0111)
+// + BEGIN_PROG (1000) + 10ms
+// + CUST_CMD (0001) + CUST_CMD (0111)
+// erase if not protected and DevID=16F84A:
+// LOAD_DATA_PROG (0010)(0x3FFF) + BULK_ERASE_PROG (1001) +10ms
+// LOAD_DATA_DATA (0011)(0xFF) + BULK_ERASE_DATA (1011) + BEGIN_PROG (1000) + 10ms
+// erase if not protected and DevID!=16F84A:
+// LOAD_DATA_PROG (0010)(0x3FFF) + CUST_CMD (0001) + CUST_CMD (0111)
+// + BEGIN_PROG (1000) + 10ms + CUST_CMD (0001) + CUST_CMD (0111)
+// LOAD_DATA_DATA (0011)(0xFF) + CUST_CMD (0001) + CUST_CMD (0111)
+// + BEGIN_PROG (1000) + 10ms + CUST_CMD (0001) + CUST_CMD (0111)
+// write: LOAD_DATA_PROG (0010) + BEGIN_PROG (1000) + 20ms or 8ms(16F84A)
+// write eeprom: LOAD_DATA_DATA (0011) + BEGIN_PROG (1000) + 20ms or 8ms(16F84A)
+// verify during write
+{
+ int err=0;
+ WORD devID,config;
+ int k=0,z=0,i,j,w,r;
+ if(sizeW<0x2007){
+ PrintMessage(strings[S_NoConfigW3]); //"Can't find CONFIG (0x2007)\r\nEnd\r\n"
+ return;
+ }
+ if(dim2){
+ if(sizeW<0x2100){
+ dim2=0;
+ PrintMessage(strings[S_NoEEMem]); //"Can't find EEPROM data\r\n"
+ }
+ else if(dim2>sizeW-0x2100) dim2=sizeW-0x2100;
+ }
+ if(saveLog){
+ OpenLogFile(); //"log.txt"
+ fprintf(logfile,"Write16F8x(%d,%d)\n",dim,dim2);
+ }
+ for(i=0;i<0x2009&&i<sizeW;i++) memCODE_W[i]&=0x3FFF;
+ unsigned int start=GetTickCount();
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T1T2;
+ bufferU[j++]=1; //T1=1u
+ bufferU[j++]=100; //T2=100u
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=25000>>8;
+ bufferU[j++]=25000&0xff;
+ bufferU[j++]=EN_VPP_VCC; //enter program mode
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=EN_VPP_VCC; //VDD+VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=NOP;
+ bufferU[j++]=LOAD_CONF; //counter at 0x2000
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=0x06;
+ bufferU[j++]=READ_DATA_PROG; //DevID
+ bufferU[j++]=INC_ADDR;
+ bufferU[j++]=READ_DATA_PROG; //Config
+ bufferU[j++]=NOP; //exit program mode
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=WAIT_T3; //delay after exiting prog mode
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=WAIT_T3; //50ms
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=EN_VPP_VCC; //VDD+VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=NOP;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(140);
+ for(z=0;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ devID=(bufferI[z+1]<<8)+bufferI[z+2];
+ PrintMessage1(strings[S_DevID],devID); //"DevID: 0x%04X\r\n"
+ PIC16_ID(devID);
+ for(z+=3;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ config=(bufferI[z+1]<<8)+bufferI[z+2];
+ PrintMessage1(strings[S_ConfigWord],config); //"Config word: 0x%04X\r\n"
+//****************** erase memory ********************
+ PrintMessage(strings[S_StartErase]); //"Erase ... "
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=10000>>8;
+ bufferU[j++]=10000&0xff;
+ if(config<0x3FF0){
+ PrintMessage(strings[S_ProtErase]); //"Override write protection\r\n"
+ bufferU[j++]=LOAD_CONF; //counter at 0x2000
+ bufferU[j++]=0x3F; //fake config
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=0x07;
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x01;
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x07;
+ bufferU[j++]=BEGIN_PROG;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x01;
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x07;
+ }
+ else if(devID>>5==0x2B){ //16F84A
+ bufferU[j++]=LOAD_DATA_PROG;
+ bufferU[j++]=0x3f; //MSB
+ bufferU[j++]=0xff; //LSB
+ bufferU[j++]=BULK_ERASE_PROG;
+ bufferU[j++]=BEGIN_PROG;
+ bufferU[j++]=WAIT_T3;
+ if(dim2){
+ bufferU[j++]=LOAD_DATA_DATA;
+ bufferU[j++]=0xff; //LSB
+ bufferU[j++]=BULK_ERASE_DATA;
+ bufferU[j++]=BEGIN_PROG;
+ bufferU[j++]=WAIT_T3;
+ }
+ }
+ else{ //altri
+ bufferU[j++]=LOAD_DATA_PROG;
+ bufferU[j++]=0x3f; //MSB
+ bufferU[j++]=0xff; //LSB
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x01;
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x07;
+ bufferU[j++]=BEGIN_PROG;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x01;
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x07;
+ if(dim2){
+ bufferU[j++]=LOAD_DATA_DATA; //EEPROM: spec error?
+ bufferU[j++]=0xff; //LSB
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x01;
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x07;
+ bufferU[j++]=BEGIN_PROG;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x01;
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x07;
+ }
+ }
+ if(!programID){ //back to program memory
+ bufferU[j++]=NOP; //exit program mode
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=WAIT_T3; //delay after exiting prog mode
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=WAIT_T3; //50ms
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=EN_VPP_VCC; //VDD+VPP
+ bufferU[j++]=0x5;
+ }
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ r=(devID>>5==0x2B)?8000:20000;
+ bufferU[j++]=r>>8;
+ bufferU[j++]=r&0xff;
+ bufferU[j++]=FLUSH;
+ r/=1000;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(!programID?140:60);
+ PrintMessage(strings[S_Compl]); //"completed\r\n"
+//****************** write code ********************
+ PrintMessage(strings[S_StartCodeProg]); //"Write code ... "
+ PrintStatusSetup();
+ for(w=i=k=0,j=0;i<dim;i++){
+ if(memCODE_W[i]<0x3fff){
+ bufferU[j++]=LOAD_DATA_PROG;
+ bufferU[j++]=memCODE_W[i]>>8; //MSB
+ bufferU[j++]=memCODE_W[i]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG; //internally timed
+ bufferU[j++]=WAIT_T3; //Tprogram
+ bufferU[j++]=READ_DATA_PROG;
+ w++;
+ }
+ bufferU[j++]=INC_ADDR;
+ if(j>DIMBUF-10||i==dim-1){
+ PrintStatus(strings[S_CodeWriting],i*100/dim,i); //"Writing: %d%%, add. %03X"
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(w*r+4);
+ w=0;
+ for(z=0;z<DIMBUF-5;z++){
+ if(bufferI[z]==INC_ADDR&&memCODE_W[k]>=0x3fff) k++;
+ else if(bufferI[z]==LOAD_DATA_PROG&&bufferI[z+3]==READ_DATA_PROG){
+ if (memCODE_W[k]!=(bufferI[z+4]<<8)+bufferI[z+5]){
+ PrintMessage("\r\n");
+ PrintMessage3(strings[S_CodeWError2],k,memCODE_W[k],(bufferI[z+4]<<8)+bufferI[z+5]); //"Error writing address %3X: written %04X, read %04X\r\n"
+ err++;
+ if(max_err&&err>max_err){
+ PrintMessage1(strings[S_MaxErr],err); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ PrintMessage(strings[S_IntW]); //"Write interrupted"
+ i=dim;
+ z=DIMBUF;
+ }
+ }
+ k++;
+ z+=6;
+ }
+ }
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,err); //"i=%d, k=%d, errors=%d \n"
+ }
+ }
+ }
+ err+=i-k;
+ PrintStatusEnd();
+ PrintMessage1(strings[S_ComplErr],err); //"completed, %d errors\r\n"
+//****************** write eeprom ********************
+ if(dim2){
+ PrintMessage(strings[S_EEAreaW]); //"Writing EEPROM ... "
+ PrintStatusSetup();
+ j=0;
+ bufferU[j++]=LOAD_CONF; //counter at 0x2000
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=INC_ADDR_N; //use only INC_ADDR_N so verification does not look at it
+ bufferU[j++]=0xFF;
+ bufferU[j++]=INC_ADDR_N; //EEPROM: counter at 0x2100
+ bufferU[j++]=1;
+ for(w=0,i=k=0x2100;i<0x2100+dim2;i++){
+ if(memCODE_W[i]<0xff){
+ bufferU[j++]=LOAD_DATA_DATA;
+ bufferU[j++]=memCODE_W[i]&0xff;
+ bufferU[j++]=BEGIN_PROG; //internally timed
+ bufferU[j++]=WAIT_T3; //Tprogram
+ bufferU[j++]=READ_DATA_DATA;
+ w++;
+ }
+ bufferU[j++]=INC_ADDR;
+ if(j>DIMBUF-10||i==0x2100+dim2-1){
+ PrintStatus(strings[S_CodeWriting],(i-0x2100+dim)*100/(dim+dim2),i); //"Writing: %d%%, add. %03X"
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(w*r+5);
+ w=0;
+ for(z=0;z<DIMBUF-4;z++){
+ if(bufferI[z]==INC_ADDR&&memCODE_W[k]>=0xff) k++;
+ else if(bufferI[z]==LOAD_DATA_DATA&&bufferI[z+3]==READ_DATA_DATA){
+ if (memCODE_W[k]!=bufferI[z+4]){
+ PrintMessage("\r\n");
+ PrintMessage3(strings[S_CodeWError3],k,memCODE_W[k],bufferI[z+4]); //"Error writing address %4X: written %02X, read %02X\r\n"
+ err++;
+ if(max_err&&err>max_err){
+ PrintMessage1(strings[S_MaxErr],err); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ PrintMessage(strings[S_IntW]); //"Write interrupted"
+ i=0x2200;
+ z=DIMBUF;
+ }
+ }
+ k++;
+ z+=5;
+ }
+ }
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,err); //"i=%d, k=%d, errors=%d \n"
+ }
+ }
+ }
+ err+=i-k;
+ PrintStatusEnd();
+ PrintMessage1(strings[S_ComplErr],i-k); //"completed, %d errors\r\n"
+ }
+//****************** write ID, CONFIG ********************
+ PrintMessage(strings[S_ConfigAreaW]); //"Writing CONFIG area ... "
+ int err_c=0;
+ bufferU[j++]=LOAD_CONF; //counter at 0x2000
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=0xFF; //fake config
+ if(programID){
+ for(i=0x2000;i<0x2004;i++){
+ bufferU[j++]=LOAD_DATA_PROG;
+ bufferU[j++]=memCODE_W[i]>>8; //MSB
+ bufferU[j++]=memCODE_W[i]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG; //internally timed
+ bufferU[j++]=WAIT_T3; //Tprogram
+ bufferU[j++]=READ_DATA_PROG;
+ bufferU[j++]=INC_ADDR;
+ }
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=3;
+ }
+ else{
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=7;
+ }
+ bufferU[j++]=LOAD_DATA_PROG; //Config word 0x2007
+ bufferU[j++]=memCODE_W[0x2007]>>8; //MSB
+ bufferU[j++]=memCODE_W[0x2007]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG; //internally timed
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=READ_DATA_PROG;
+ bufferU[j++]=INC_ADDR;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(programID?125:35);
+ for(i=0,z=0;programID&&i<4;i++){
+ for(;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if (memCODE_W[0x2000+i]!=(bufferI[z+1]<<8)+bufferI[z+2]){
+ PrintMessage("\r\n");
+ PrintMessage3(strings[S_IDErr],i,memCODE_W[0x2000+i],(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing ID%d: written %04X, read %04X\r\n"
+ err_c++;
+ }
+ z+=6;
+ }
+ for(;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if(~memCODE_W[0x2007]&((bufferI[z+1]<<8)+bufferI[z+2])){ //error if written 0 and read 1 (~W&R)
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ConfigWErr3],memCODE_W[0x2007],(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing config area: written %04X, read %04X\r\n"
+ err_c++;
+ }
+ err+=err_c;
+ PrintMessage1(strings[S_ComplErr],err_c); //"completed, %d errors\r\n"
+ if(saveLog){
+ fprintf(logfile,strings[S_Log9],err); //"Area config. errors=%d \n"
+ }
+//****************** exit ********************
+ j=0;
+ bufferU[j++]=NOP; //exit program mode
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2000>>8;
+ bufferU[j++]=2000&0xff;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ unsigned int stop=GetTickCount();
+ sprintf(str,strings[S_EndErr],(stop-start)/1000.0,err,err!=1?strings[S_ErrPlur]:strings[S_ErrSing]); //"\r\nEnd (%.2f s) %d %s\r\n\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+ PrintStatusClear(); //clear status report
+}
+
+void Write16F62x (int dim,int dim2)
+// write 14 bit PIC
+// dim=program size dim2=eeprom size
+// vpp before vdd
+// DevID@0x2006
+// Config@0x2007
+// eeprom@0x2200
+// erase if protected:
+// LOAD_CONF (0000)(0) + CUST_CMD (0001) + CUST_CMD (0111)
+// + BEGIN_PROG (1000) + 15ms + CUST_CMD (0001) + CUST_CMD (0111)
+// erase if not protected:
+// LOAD_DATA_PROG (0010)(0x3FFF) + BULK_ERASE_PROG (1001) +5ms
+// LOAD_DATA_DATA (0011)(0xFF) + BULK_ERASE_DATA (1011) + BEGIN_PROG (1000) + 5ms
+// write: LOAD_DATA_PROG (0010) + BEGIN_PROG2 (11000) + 8ms
+// write ID: LOAD_DATA_PROG (0010) + BEGIN_PROG (1000) + 16ms
+// write CONFIG: LOAD_DATA_PROG (0010) + BEGIN_PROG2 (11000) + 8ms
+// eeprom: LOAD_DATA_DATA (0011) + BEGIN_PROG2 (11000) + 8ms
+// verify during write
+{
+ int err=0;
+ WORD devID,config;
+ int k=0,z=0,i,j,w;
+ if(sizeW<0x2007){
+ PrintMessage(strings[S_NoConfigW3]); //"Can't find CONFIG (0x2007)\r\nEnd\r\n"
+ return;
+ }
+ if(dim2){
+ if(sizeW<0x2100){
+ dim2=0;
+ PrintMessage(strings[S_NoEEMem]); //"Can't find EEPROM data\r\n"
+ }
+ else if(dim2>sizeW-0x2100) dim2=sizeW-0x2100;
+ }
+ if(saveLog){
+ OpenLogFile(); //"log.txt"
+ fprintf(logfile,"Write16F62x(%d,%d)\n",dim,dim2);
+ }
+ for(i=0;i<0x2009&&i<sizeW;i++) memCODE_W[i]&=0x3FFF;
+ unsigned int start=GetTickCount();
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T1T2;
+ bufferU[j++]=1; //T1=1u
+ bufferU[j++]=100; //T2=100u
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=10000>>8;
+ bufferU[j++]=10000&0xff;
+ bufferU[j++]=EN_VPP_VCC; //enter program mode
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=EN_VPP_VCC; //VPP
+ bufferU[j++]=0x4;
+ bufferU[j++]=EN_VPP_VCC; //VDD+VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=NOP;
+ bufferU[j++]=LOAD_CONF; //counter at 0x2000
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=0x06;
+ bufferU[j++]=READ_DATA_PROG; //DevID
+ bufferU[j++]=INC_ADDR;
+ bufferU[j++]=READ_DATA_PROG; //Config
+ bufferU[j++]=EN_VPP_VCC; //VPP
+ bufferU[j++]=0x4;
+ bufferU[j++]=EN_VPP_VCC; //0
+ bufferU[j++]=0x0;
+ bufferU[j++]=WAIT_T3; //delay exit-enter prog mode
+ bufferU[j++]=EN_VPP_VCC; //VPP
+ bufferU[j++]=0x4;
+ bufferU[j++]=EN_VPP_VCC; //VDD+VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(12);
+ for(z=0;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ devID=(bufferI[z+1]<<8)+bufferI[z+2];
+ PrintMessage1(strings[S_DevID],devID); //"DevID: 0x%04X\r\n"
+ PIC16_ID(devID);
+ for(z+=3;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ config=(bufferI[z+1]<<8)+bufferI[z+2];
+ PrintMessage1(strings[S_ConfigWord],config); //"Config word: 0x%04X\r\n"
+//****************** erase memory ********************
+ PrintMessage(strings[S_StartErase]); //"Erase ... "
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=5000>>8;
+ bufferU[j++]=5000&0xff;
+ if(config<0x3C00){
+ PrintMessage(strings[S_ProtErase]); //"Override write protection\r\n"
+ bufferU[j++]=LOAD_CONF; //counter at 0x2000
+ bufferU[j++]=0x3F; //fake config spec ERROR!!! is written data=0!!
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=0x07;
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x01;
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x07;
+ bufferU[j++]=BEGIN_PROG; //Tera+Tprog=5+8 ms
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x01;
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x07;
+ }
+ else{
+ bufferU[j++]=LOAD_DATA_PROG;
+ bufferU[j++]=0x3f; //MSB
+ bufferU[j++]=0xff; //LSB
+ bufferU[j++]=BULK_ERASE_PROG;
+ bufferU[j++]=BEGIN_PROG; //Tera=5ms
+ bufferU[j++]=WAIT_T3;
+ if(dim2){
+ bufferU[j++]=LOAD_DATA_DATA;
+ bufferU[j++]=0xff; //LSB
+ bufferU[j++]=BULK_ERASE_DATA;
+ bufferU[j++]=BEGIN_PROG; //Tera=5ms
+ bufferU[j++]=WAIT_T3;
+ }
+ }
+ bufferU[j++]=NOP; //exit program mode
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=WAIT_T3; //delay after exiting prog mode
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x4;
+ bufferU[j++]=EN_VPP_VCC; //VDD+VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=8000>>8;
+ bufferU[j++]=8000&0xff;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(60);
+ PrintMessage(strings[S_Compl]); //"completed\r\n"
+//****************** write code ********************
+ PrintMessage(strings[S_StartCodeProg]); //"Write code ... "
+ PrintStatusSetup();
+ for(w=i=k=0,j=0;i<dim;i++){
+ if(memCODE_W[i]<0x3fff){
+ bufferU[j++]=LOAD_DATA_PROG;
+ bufferU[j++]=memCODE_W[i]>>8; //MSB
+ bufferU[j++]=memCODE_W[i]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG2; //program only, internally timed
+ bufferU[j++]=WAIT_T3; //Tprogram=8ms
+ bufferU[j++]=READ_DATA_PROG;
+ w++;
+ }
+ bufferU[j++]=INC_ADDR;
+ if(j>DIMBUF-10||i==dim-1){
+ PrintStatus(strings[S_CodeWriting],i*100/dim,i); //"Writing: %d%%, add. %03X"
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(w*9+2);
+ w=0;
+ for(z=0;z<DIMBUF-5;z++){
+ if(bufferI[z]==INC_ADDR&&memCODE_W[k]>=0x3fff) k++;
+ else if(bufferI[z]==LOAD_DATA_PROG&&bufferI[z+3]==READ_DATA_PROG){
+ if (memCODE_W[k]!=(bufferI[z+4]<<8)+bufferI[z+5]){
+ PrintMessage("\r\n");
+ PrintMessage3(strings[S_CodeWError2],k,memCODE_W[k],(bufferI[z+4]<<8)+bufferI[z+5]); //"Error writing address %3X: written %04X, read %04X\r\n"
+ err++;
+ if(max_err&&err>max_err){
+ PrintMessage1(strings[S_MaxErr],err); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ PrintMessage(strings[S_IntW]); //"Write interrupted"
+ i=dim;
+ z=DIMBUF;
+ }
+ }
+ k++;
+ z+=6;
+ }
+ }
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,err); //"i=%d, k=%d, errors=%d \n"
+ }
+ }
+ }
+ err+=i-k;
+ PrintStatusEnd();
+ PrintMessage1(strings[S_ComplErr],err); //"completed, %d errors\r\n"
+//****************** write eeprom ********************
+ if(dim2){
+ PrintMessage(strings[S_EEAreaW]); //"Writing EEPROM ... "
+ PrintStatusSetup();
+ j=0;
+ bufferU[j++]=LOAD_CONF; //counter at 0x2000
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=INC_ADDR_N; //use only INC_ADDR_N so verification does not look at it
+ bufferU[j++]=0xFF; //20FF
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=0xFF; //21FE
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=0x2; //EEPROM: counter at 0x2200
+ for(w=0,i=k=0x2100;i<0x2100+dim2;i++){
+ if(memCODE_W[i]<0xff){
+ bufferU[j++]=LOAD_DATA_DATA;
+ bufferU[j++]=memCODE_W[i]&0xff;
+ bufferU[j++]=BEGIN_PROG2; //internally timed
+ bufferU[j++]=WAIT_T3; //Tprogram=8ms
+ bufferU[j++]=READ_DATA_DATA;
+ w++;
+ }
+ bufferU[j++]=INC_ADDR;
+ if(j>DIMBUF-10||i==0x2100+dim2-1){
+ PrintStatus(strings[S_CodeWriting],(i-0x2100+dim)*100/(dim+dim2),i); //"Writing: %d%%, add. %03X"
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(w*14+1);
+ w=0;
+ for(z=0;z<DIMBUF-4;z++){
+ if(bufferI[z]==INC_ADDR&&memCODE_W[k]>=0xff) k++;
+ else if(bufferI[z]==LOAD_DATA_DATA&&bufferI[z+3]==READ_DATA_DATA){
+ if (memCODE_W[k]!=bufferI[z+4]){
+ PrintMessage("\r\n");
+ PrintMessage3(strings[S_CodeWError3],k,memCODE_W[k],bufferI[z+4]); //"Error writing address %4X: written %02X, read %02X\r\n"
+ err++;
+ if(max_err&&err>max_err){
+ PrintMessage1(strings[S_MaxErr],err); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ PrintMessage(strings[S_IntW]); //"Write interrupted"
+ i=0x2200;
+ z=DIMBUF;
+ }
+ }
+ k++;
+ z+=5;
+ }
+ }
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,err); //"i=%d, k=%d, errors=%d \n"
+ }
+ }
+ }
+ err+=i-k;
+ PrintStatusEnd();
+ PrintMessage1(strings[S_ComplErr],i-k); //"completed, %d errors\r\n"
+ }
+//****************** write ID, CONFIG ********************
+ PrintMessage(strings[S_ConfigAreaW]); //"Writing CONFIG area ... "
+ int err_c=0;
+ bufferU[j++]=LOAD_CONF; //counter at 0x2000
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=0xFF; //fake config
+ if(programID){
+ for(i=0x2000;i<0x2004;i++){
+ bufferU[j++]=LOAD_DATA_PROG;
+ bufferU[j++]=memCODE_W[i]>>8; //MSB
+ bufferU[j++]=memCODE_W[i]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG; //erase + prog internally timed, T=8+5 ms
+ bufferU[j++]=WAIT_T3; //Tprogram
+ bufferU[j++]=WAIT_T3; //Tprogram
+ bufferU[j++]=READ_DATA_PROG;
+ bufferU[j++]=INC_ADDR;
+ }
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=3;
+ }
+ else{
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=7;
+ }
+ bufferU[j++]=LOAD_DATA_PROG; //Config word 0x2007
+ bufferU[j++]=memCODE_W[0x2007]>>8; //MSB
+ bufferU[j++]=memCODE_W[0x2007]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG2; //prog only, internally timed, T=8 ms
+ bufferU[j++]=WAIT_T3; //Tprogram 8ms
+ bufferU[j++]=READ_DATA_PROG;
+ bufferU[j++]=INC_ADDR;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(programID?125:35);
+ for(i=0,z=0;programID&&i<4;i++){
+ for(;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if (memCODE_W[0x2000+i]!=(bufferI[z+1]<<8)+bufferI[z+2]){
+ PrintMessage3(strings[S_IDErr],i,memCODE_W[0x2000+i],(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing ID%d: written %04X, read %04X\r\n"
+ err_c++;
+ }
+ z+=6;
+ }
+ for(;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if(~memCODE_W[0x2007]&((bufferI[z+1]<<8)+bufferI[z+2])){ //error if written 0 and read 1 (~W&R)
+ PrintMessage2(strings[S_ConfigWErr3],memCODE_W[0x2007],(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing config area: written %04X, read %04X\r\n"
+ err_c++;
+ }
+ err+=err_c;
+ PrintMessage1(strings[S_ComplErr],err_c); //"completed, %d errors\n"
+ if(saveLog){
+ fprintf(logfile,strings[S_Log9],err); //"Area config. errors=%d\n"
+ }
+//****************** exit ********************
+ j=0;
+ bufferU[j++]=NOP; //exit program mode
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2000>>8;
+ bufferU[j++]=2000&0xff;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ unsigned int stop=GetTickCount();
+ sprintf(str,strings[S_EndErr],(stop-start)/1000.0,err,err!=1?strings[S_ErrPlur]:strings[S_ErrSing]); //"\r\nEnd (%.2f s) %d %s\r\n\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+ PrintStatusClear(); //clear status report
+}
+
+void Write12F62x(int dim,int dim2)
+// write 14 bit PIC
+// dim=program size dim2=eeprom size
+// vpp before vdd
+// save OSCCAL @ dim-1
+// CONFIG@0x2007 includes 2 calibration bits
+// DevID@0x2006
+// eeprom@0x2100
+// erase: BULK_ERASE_PROG (1001) +10ms
+// write: LOAD_DATA_PROG (0010) + BEGIN_PROG (1000) + 3ms
+// eeprom: BULK_ERASE_DATA (1011) + 9ms
+// LOAD_DATA_DATA (0011) + BEGIN_PROG (1000) + 6ms
+// verify during write
+{
+ int err=0;
+ WORD devID,config,osccal;
+ int k=0,z=0,i,j,w;
+ if(sizeW<0x2007){
+ PrintMessage(strings[S_NoConfigW3]); //"Can't find CONFIG (0x2007)\r\nEnd\r\n"
+ return;
+ }
+ if(dim2){
+ if(sizeW<0x2100){
+ dim2=0;
+ PrintMessage(strings[S_NoEEMem]); //"Can't find EEPROM data\r\n"
+ }
+ else if(dim2>sizeW-0x2100) dim2=sizeW-0x2100;
+ }
+ if(saveLog){
+ OpenLogFile(); //"log.txt"
+ fprintf(logfile,"Write12F62x(%d,%d)\n",dim,dim2);
+ }
+ for(i=0;i<sizeW;i++) memCODE_W[i]&=0x3FFF;
+ unsigned int start=GetTickCount();
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T1T2;
+ bufferU[j++]=1; //T1=1u
+ bufferU[j++]=100; //T2=100u
+ bufferU[j++]=EN_VPP_VCC; //enter program mode
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=EN_VPP_VCC; //VPP
+ bufferU[j++]=0x4;
+ bufferU[j++]=NOP;
+ bufferU[j++]=EN_VPP_VCC; //VDD+VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=NOP;
+ for(i=0;i<dim-0xff;i+=0xff){
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=0xff;
+ }
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=dim-1-i;
+ bufferU[j++]=READ_DATA_PROG; // OSCCAL
+ bufferU[j++]=LOAD_CONF; //counter at 0x2000
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=0x06;
+ bufferU[j++]=READ_DATA_PROG; //DevID
+ bufferU[j++]=INC_ADDR;
+ bufferU[j++]=READ_DATA_PROG; //Config
+ bufferU[j++]=NOP; //exit program mode
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=10000>>8;
+ bufferU[j++]=10000&0xff;
+ bufferU[j++]=WAIT_T3; //delay after exiting prog mode
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(15);
+ for(z=0;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ osccal=(bufferI[z+1]<<8)+bufferI[z+2];
+ for(z+=3;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ devID=(bufferI[z+1]<<8)+bufferI[z+2];
+ for(z+=3;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ config=(bufferI[z+1]<<8)+bufferI[z+1];
+ PrintMessage1(strings[S_DevID],devID); //"DevID: 0x%04X\r\n"
+ PIC16_ID(devID);
+//****************** erase memory ********************
+ PrintMessage(strings[S_StartErase]); //"Erase ... "
+ j=0;
+ bufferU[j++]=EN_VPP_VCC; //enter program mode
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=EN_VPP_VCC; //VPP
+ bufferU[j++]=0x4;
+ bufferU[j++]=NOP;
+ bufferU[j++]=EN_VPP_VCC; //VDD+VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=NOP;
+ if(programID){
+ bufferU[j++]=LOAD_CONF; //counter at 0x2000
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=0xFF; //fake config
+ }
+ bufferU[j++]=BULK_ERASE_PROG;
+ bufferU[j++]=WAIT_T3; // delay T3=10ms
+ bufferU[j++]=EN_VPP_VCC; //exit program mode
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=WAIT_T3; // delay T3=10ms after exiting program mode
+ bufferU[j++]=EN_VPP_VCC; //enter program mode
+ bufferU[j++]=0x4;
+ bufferU[j++]=NOP;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x5;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=3000>>8;
+ bufferU[j++]=3000&0xff;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(40);
+ PrintMessage(strings[S_Compl]); //"completed\r\n"
+//****************** write code ********************
+ PrintMessage(strings[S_StartCodeProg]); //"Write code ... "
+ PrintStatusSetup();
+ if(!load_osccal) memCODE_W[dim-1]=osccal; //backup osccal
+ for(w=i=k=0,j=0;i<dim;i++){
+ if(memCODE_W[i]<0x3fff){
+ bufferU[j++]=LOAD_DATA_PROG;
+ bufferU[j++]=memCODE_W[i]>>8; //MSB
+ bufferU[j++]=memCODE_W[i]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG; //internally timed, T=3ms
+ bufferU[j++]=WAIT_T3; //Tprogram 3ms
+ bufferU[j++]=READ_DATA_PROG;
+ w++;
+ }
+ bufferU[j++]=INC_ADDR;
+ if(j>DIMBUF-10||i==dim-1){
+ PrintStatus(strings[S_CodeWriting],i*100/dim,i); //"Writing: %d%%, add. %03X"
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(w*6.5+j*0.1);
+ w=0;
+ for(z=0;z<DIMBUF-5;z++){
+ if(bufferI[z]==INC_ADDR&&memCODE_W[k]>=0x3fff) k++;
+ else if(bufferI[z]==LOAD_DATA_PROG&&bufferI[z+3]==READ_DATA_PROG){
+ if (memCODE_W[k]!=(bufferI[z+4]<<8)+bufferI[z+5]){
+ PrintMessage("\r\n");
+ PrintMessage3(strings[S_CodeWError2],k,memCODE_W[k],(bufferI[z+4]<<8)+bufferI[z+5]); //"Error writing address %3X: written %04X, read %04X\r\n"
+ err++;
+ if(max_err&&err>max_err){
+ PrintMessage1(strings[S_MaxErr],err); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ PrintMessage(strings[S_IntW]); //"Write interrupted"
+ i=dim;
+ z=DIMBUF;
+ }
+ }
+ k++;
+ z+=6;
+ }
+ }
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,err); //"i=%d, k=%d, errors=%d \n"
+ }
+ }
+ }
+ PrintStatusEnd();
+ err+=i-k;
+ PrintMessage1(strings[S_ComplErr],err); //"completed, %d errors\r\n"
+//****************** write eeprom ********************
+ if(dim2){
+ PrintMessage(strings[S_EEAreaW]); //"Writing EEPROM ... "
+ PrintStatusSetup();
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=6000>>8;
+ bufferU[j++]=6000&0xff;
+ bufferU[j++]=LOAD_CONF; //counter at 0x2000
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=INC_ADDR_N; //use only INC_ADDR_N so verification does not look at it
+ bufferU[j++]=0xFF;
+ bufferU[j++]=INC_ADDR_N; //EEPROM: counter at 0x2100
+ bufferU[j++]=1;
+ bufferU[j++]=BULK_ERASE_DATA;
+ bufferU[j++]=WAIT_T3; // delay=12ms
+ bufferU[j++]=WAIT_T3;
+ for(w=3,i=k=0x2100;i<0x2100+dim2;i++){
+ if(memCODE_W[i]<0xff){
+ bufferU[j++]=LOAD_DATA_DATA;
+ bufferU[j++]=memCODE_W[i]&0xff;
+ bufferU[j++]=BEGIN_PROG; //internally timed, T=6ms
+ bufferU[j++]=WAIT_T3; //Tprogram 6ms
+ bufferU[j++]=READ_DATA_DATA;
+ w++;
+ }
+ bufferU[j++]=INC_ADDR;
+ if(j>DIMBUF-10||i==0x2100+dim2-1){
+ PrintStatus(strings[S_CodeWriting],(i-0x2100+dim)*100/(dim+dim2),i); //"Writing: %d%%, add. %03X"
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(w*7+2);
+ w=0;
+ for(z=0;z<DIMBUF-4;z++){
+ if(bufferI[z]==INC_ADDR&&memCODE_W[k]>=0xff) k++;
+ else if(bufferI[z]==LOAD_DATA_DATA&&bufferI[z+3]==READ_DATA_DATA){
+ if (memCODE_W[k]!=bufferI[z+4]){
+ PrintMessage("\r\n");
+ PrintMessage3(strings[S_CodeWError3],k,memCODE_W[k],bufferI[z+4]); //"Error writing address %4X: written %02X, read %02X\r\n"
+ err++;
+ if(max_err&&err>max_err){
+ PrintMessage1(strings[S_MaxErr],err); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ PrintMessage(strings[S_IntW]); //"Write interrupted"
+ i=0x2200;
+ z=DIMBUF;
+ }
+ }
+ k++;
+ z+=5;
+ }
+ }
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,err); //"i=%d, k=%d, errors=%d \n"
+ }
+ }
+ }
+ err+=i-k;
+ PrintStatusEnd();
+ PrintMessage1(strings[S_ComplErr],i-k); //"completed, %d errors\r\n"
+ }
+//****************** write ID, CONFIG, CALIB ********************
+ PrintMessage(strings[S_ConfigAreaW]); //"Writing CONFIG area ... "
+ int err_c=0;
+ bufferU[j++]=LOAD_CONF; //counter at 0x2000
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=0xFF; //fake config
+ if(programID){
+ for(i=0x2000;i<0x2004;i++){
+ bufferU[j++]=LOAD_DATA_PROG;
+ bufferU[j++]=memCODE_W[i]>>8; //MSB
+ bufferU[j++]=memCODE_W[i]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG; //internally timed, T=3ms
+ bufferU[j++]=WAIT_T3; //Tprogram 3ms
+ bufferU[j++]=READ_DATA_PROG;
+ bufferU[j++]=INC_ADDR;
+ }
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=3;
+ }
+ else{
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=7;
+ }
+ if(!load_calibword) memCODE_W[0x2007]=(memCODE_W[0x2007]&0xfff)+(config&0x3000);
+ bufferU[j++]=LOAD_DATA_PROG; //Config word 0x2007
+ bufferU[j++]=memCODE_W[0x2007]>>8; //MSB
+ bufferU[j++]=memCODE_W[0x2007]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG; //internally timed, T=3ms
+ bufferU[j++]=WAIT_T3; //Tprogram 3ms
+ bufferU[j++]=READ_DATA_PROG;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(35);
+ for(i=0,z=0;programID&&i<4;i++){
+ for(;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if (memCODE_W[0x2000+i]!=(bufferI[z+1]<<8)+bufferI[z+2]){
+ PrintMessage3(strings[S_IDErr],i,memCODE_W[0x2000+i],(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing ID%d: written %04X, read %04X\r\n"
+ err_c++;
+ }
+ z+=6;
+ }
+ for(;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if(~memCODE_W[0x2007]&((bufferI[z+1]<<8)+bufferI[z+2])){ //error if written 0 and read 1 (~W&R)
+ PrintMessage2(strings[S_ConfigWErr3],memCODE_W[0x2007],(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing config area: written %04X, read %04X\r\n"
+ err_c++;
+ }
+ err+=err_c;
+ PrintMessage1(strings[S_ComplErr],err_c); //"completed, %d errors\r\n"
+ if(saveLog){
+ fprintf(logfile,strings[S_Log9],err); //"Area config. errors=%d \n"
+ }
+//****************** exit ********************
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2000>>8;
+ bufferU[j++]=2000&0xff;
+ bufferU[j++]=EN_VPP_VCC; //exit program mode
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ unsigned int stop=GetTickCount();
+ sprintf(str,strings[S_EndErr],(stop-start)/1000.0,err,err!=1?strings[S_ErrPlur]:strings[S_ErrSing]); //"\r\nEnd (%.2f s) %d %s\r\n\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+ PrintStatusClear(); //clear status report
+}
+
+void Write16F87x (int dim,int dim2)
+// write 14 bit PIC
+// dim=program size dim2=eeprom size
+// dim2<0 -> eeprom @ 0x2200
+// vdd + (50ms?) + vdd&vpp
+// DevID@0x2006
+// Config@0x2007
+// eeprom@0x2100
+// erase if protected:
+// LOAD_CONF (0000)(0x3FFF) + CUST_CMD (0001) + CUST_CMD (0111)
+// + BEGIN_PROG (1000) + 8ms
+// + CUST_CMD (0001) + CUST_CMD (0111)
+// erase if not protected:
+// LOAD_DATA_PROG (0010)(0x3FFF) + CUST_CMD (0001) + CUST_CMD (0111)
+// + BEGIN_PROG (1000) + 8ms + CUST_CMD (0001) + CUST_CMD (0111)
+// LOAD_DATA_DATA (0011)(0xFF) + CUST_CMD (0001) + CUST_CMD (0111)
+// + BEGIN_PROG (1000) + 8ms + CUST_CMD (0001) + CUST_CMD (0111)
+// write: LOAD_DATA_PROG (0010) + BEGIN_PROG2 (11000) + 4ms
+// write eeprom: LOAD_DATA_DATA (0011) + BEGIN_PROG (1000) + 8ms
+// verify during write
+{
+ int err=0;
+ WORD devID,config;
+ int k=0,z=0,i,j,w,ee2200=0;
+ if(dim2<0){
+ dim2=-dim2;
+ ee2200=1;
+ }
+ if(sizeW<0x2007){
+ PrintMessage(strings[S_NoConfigW3]); //"Can't find CONFIG (0x2007)\r\nEnd\r\n"
+ return;
+ }
+ if(dim2){
+ if(sizeW<0x2100){
+ dim2=0;
+ PrintMessage(strings[S_NoEEMem]); //"Can't find EEPROM data\r\n"
+ }
+ else if(dim2>sizeW-0x2100) dim2=sizeW-0x2100;
+ }
+ if(saveLog){
+ OpenLogFile(); //"log.txt"
+ fprintf(logfile,"Write16F87x(%d,%d)\n",dim,dim2);
+ }
+ for(i=0;i<sizeW;i++) memCODE_W[i]&=0x3FFF;
+ unsigned int start=GetTickCount();
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T1T2;
+ bufferU[j++]=1; //T1=1u
+ bufferU[j++]=100; //T2=100u
+ bufferU[j++]=EN_VPP_VCC; //enter program mode
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC; //VDD+VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=NOP;
+ bufferU[j++]=LOAD_CONF; //counter at 0x2000
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=0x06;
+ bufferU[j++]=READ_DATA_PROG; //DevID
+ bufferU[j++]=INC_ADDR;
+ bufferU[j++]=READ_DATA_PROG; //Config
+ bufferU[j++]=NOP; //exit program mode
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=WAIT_T3; //delay after exiting prog mode
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC; //VDD+VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(60);
+ for(z=0;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ devID=(bufferI[z+1]<<8)+bufferI[z+2];
+ PrintMessage1(strings[S_DevID],devID); //"DevID: 0x%04X\r\n"
+ PIC16_ID(devID);
+ for(z+=3;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ config=(bufferI[z+1]<<8)+bufferI[z+2];
+ PrintMessage1(strings[S_ConfigWord],config); //"Config word: 0x%04X\r\n"
+//****************** erase memory ********************
+ PrintMessage(strings[S_StartErase]); //"Erase ... "
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=8000>>8;
+ bufferU[j++]=8000&0xff;
+ if((config&0x3130)!=0x3130){
+ PrintMessage(strings[S_ProtErase]); //"override write protection\r\n"
+ bufferU[j++]=LOAD_CONF; //counter at 0x2000
+ bufferU[j++]=0x3F; //fake config
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=0x07;
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x01;
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x07;
+ bufferU[j++]=BEGIN_PROG;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x01;
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x07;
+ bufferU[j++]=NOP; //exit program mode
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=WAIT_T3; //delay after exiting prog mode
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC; //VDD+VPP
+ bufferU[j++]=0x5;
+ }
+ else{
+ if(ICDenable||programID){ //erase 0x2000-2004 also
+ bufferU[j++]=LOAD_CONF; //counter at 0x2000
+ bufferU[j++]=0x3F; //fake config
+ bufferU[j++]=0xFF; //fake config
+ }
+ bufferU[j++]=LOAD_DATA_PROG;
+ bufferU[j++]=0x3f; //MSB
+ bufferU[j++]=0xff; //LSB
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x01;
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x07;
+ bufferU[j++]=BEGIN_PROG;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x01;
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x07;
+ if(dim2){
+ bufferU[j++]=LOAD_DATA_DATA; //EEPROM: spec error?
+ bufferU[j++]=0xff; //LSB
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x01;
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x07;
+ bufferU[j++]=BEGIN_PROG;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x01;
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x07;
+ }
+ if(ICDenable||programID){ //back to addr 0
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=WAIT_T3; //delay after exiting prog mode
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC; //VDD+VPP
+ bufferU[j++]=0x5;
+ }
+ }
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=4000>>8;
+ bufferU[j++]=4000&0xff;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(60);
+ PrintMessage(strings[S_Compl]); //"completed\r\n"
+//****************** write code ********************
+ PrintMessage(strings[S_StartCodeProg]); //"Write code ... "
+ PrintStatusSetup();
+ for(w=i=k=0,j=0;i<dim;i++){
+ if(memCODE_W[i]<0x3fff){
+ bufferU[j++]=LOAD_DATA_PROG;
+ bufferU[j++]=memCODE_W[i]>>8; //MSB
+ bufferU[j++]=memCODE_W[i]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG2; //internally timed
+ bufferU[j++]=WAIT_T3; //Tprogram
+ bufferU[j++]=READ_DATA_PROG;
+ w++;
+ }
+ bufferU[j++]=INC_ADDR;
+ if(j>DIMBUF-10||i==dim-1){
+ PrintStatus(strings[S_CodeWriting],i*100/dim,i); //"Writing: %d%%, add. %03X"
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(w*5+2);
+ w=0;
+ for(z=0;z<DIMBUF-5;z++){
+ if(bufferI[z]==INC_ADDR&&memCODE_W[k]>=0x3fff) k++;
+ else if(bufferI[z]==LOAD_DATA_PROG&&bufferI[z+3]==READ_DATA_PROG){
+ if (memCODE_W[k]!=(bufferI[z+4]<<8)+bufferI[z+5]){
+ PrintMessage("\r\n");
+ PrintMessage3(strings[S_CodeWError2],k,memCODE_W[k],(bufferI[z+4]<<8)+bufferI[z+5]); //"Error writing address %3X: written %04X, read %04X\r\n"
+ err++;
+ if(max_err&&err>max_err){
+ PrintMessage1(strings[S_MaxErr],err); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ PrintMessage(strings[S_IntW]); //"Write interrupted"
+ i=dim;
+ z=DIMBUF;
+ }
+ }
+ k++;
+ z+=6;
+ }
+ }
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,err); //"i=%d, k=%d, errors=%d \n"
+ }
+ }
+ }
+ err+=i-k;
+ PrintStatusEnd();
+ PrintMessage1(strings[S_ComplErr],err); //"completed, %d errors\r\n"
+//****************** write eeprom ********************
+ if(dim2){
+ int err_e=0;
+ PrintMessage(strings[S_EEAreaW]); //"Writing EEPROM ... "
+ PrintStatusSetup();
+ j=0;
+ bufferU[j++]=LOAD_CONF; //counter at 0x2000
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=INC_ADDR_N; //use only INC_ADDR_N so verification does not look at it
+ bufferU[j++]=0xFF;
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=1; //EEPROM: counter at 0x2100
+ if(ee2200){ //eeprom at 0x2200
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=0xFF;
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=1;
+ }
+ for(w=0,i=k=0x2100;i<0x2100+dim2;i++){
+ if(memCODE_W[i]<0xff){
+ bufferU[j++]=LOAD_DATA_DATA;
+ bufferU[j++]=memCODE_W[i]&0xff;
+ bufferU[j++]=BEGIN_PROG2; //internally timed ?????
+ bufferU[j++]=WAIT_T3; //Tprogram ?????
+ bufferU[j++]=READ_DATA_DATA;
+ w++;
+ }
+ bufferU[j++]=INC_ADDR;
+ if(j>DIMBUF-10||i==0x2100+dim2-1){
+ PrintStatus(strings[S_CodeWriting],(i-0x2100+dim)*100/(dim+dim2),i); //"Writing: %d%%, add. %03X"
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(w*8+5);
+ w=0;
+ for(z=0;z<DIMBUF;z++){
+ if(bufferI[z]==INC_ADDR&&memCODE_W[k]>=0xff) k++;
+ else if(bufferI[z]==LOAD_DATA_DATA&&bufferI[z+3]==READ_DATA_DATA){
+ if (memCODE_W[k]!=bufferI[z+4]){
+ PrintMessage("\r\n");
+ PrintMessage3(strings[S_CodeWError3],k,memCODE_W[k],bufferI[z+4]); //"Error writing address %4X: written %02X, read %02X\r\n"
+ err_e++;
+ if(max_err&&err+err_e>max_err){
+ PrintMessage1(strings[S_MaxErr],err+err_e); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ PrintMessage(strings[S_IntW]); //"Write interrupted"
+ i=0x2200;
+ z=DIMBUF;
+ }
+ }
+ k++;
+ z+=5;
+ }
+ }
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,err); //"i=%d, k=%d, errors=%d \n"
+ }
+ }
+ }
+ err_e+=i-k;
+ err+=err_e;
+ PrintStatusEnd();
+ PrintMessage1(strings[S_ComplErr],err_e); //"completed, %d errors\r\n"
+ }
+//****************** write ID, CONFIG, CALIB ********************
+ PrintMessage(strings[S_ConfigAreaW]); //"Writing CONFIG area ... "
+ int err_c=0;
+ int ICDgoto=0x2800+(ICDaddr&0x7FF); //GOTO ICD routine (0x28xx)
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=8000>>8;
+ bufferU[j++]=8000&0xff;
+ bufferU[j++]=LOAD_CONF; //counter at 0x2000
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=0xFF; //fake config
+ if(programID){
+ for(i=0x2000;i<0x2004;i++){
+ bufferU[j++]=LOAD_DATA_PROG;
+ bufferU[j++]=memCODE_W[i]>>8; //MSB
+ bufferU[j++]=memCODE_W[i]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG2; //internally timed
+ bufferU[j++]=WAIT_T3; //Tprogram
+ bufferU[j++]=READ_DATA_PROG;
+ bufferU[j++]=INC_ADDR;
+ }
+ }
+ else{
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=4;
+ }
+ if(ICDenable){ //write a GOTO ICD routine (0x28xx)
+ bufferU[j++]=LOAD_DATA_PROG;
+ bufferU[j++]=ICDgoto>>8; //MSB
+ bufferU[j++]=ICDgoto&0xFF; //LSB
+ bufferU[j++]=BEGIN_PROG2; //internally timed
+ bufferU[j++]=WAIT_T3; //Tprogram
+ bufferU[j++]=READ_DATA_PROG;
+ }
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=3;
+ bufferU[j++]=LOAD_DATA_PROG; //Config word 0x2007
+ bufferU[j++]=memCODE_W[0x2007]>>8; //MSB
+ bufferU[j++]=memCODE_W[0x2007]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG2; //internally timed
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=READ_DATA_PROG;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(programID?125:35);
+ for(i=0,z=0;programID&&i<4;i++){
+ for(;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if (memCODE_W[0x2000+i]!=(bufferI[z+1]<<8)+bufferI[z+2]){
+ PrintMessage3(strings[S_IDErr],i,memCODE_W[0x2000+i],(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing ID%d: written %04X, read %04X\r\n"
+ err_c++;
+ }
+ z+=6;
+ }
+ if(ICDenable){
+ for(;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if (ICDgoto!=(bufferI[z+1]<<8)+bufferI[z+2]){
+ PrintMessage4(strings[S_ICDErr],0x2004,i,ICDgoto,(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing ICD (0x%X): written %04X, read %04X\r\n"
+ err_c++;
+ }
+ z+=6;
+ }
+ for(;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if(~memCODE_W[0x2007]&((bufferI[z+1]<<8)+bufferI[z+2])){ //error if written 0 and read 1 (~W&R)
+ PrintMessage2(strings[S_ConfigWErr3],memCODE_W[0x2007],(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing config area: written %04X, read %04X\r\n"
+ err_c++;
+ }
+ err+=err_c;
+ PrintMessage1(strings[S_ComplErr],err_c); //"completed, %d errors\r\n"
+ if(saveLog){
+ fprintf(logfile,strings[S_Log9],err); //"Area config. errors=%d \n"
+ }
+//****************** exit ********************
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2000>>8;
+ bufferU[j++]=2000&0xff;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ unsigned int stop=GetTickCount();
+ sprintf(str,strings[S_EndErr],(stop-start)/1000.0,err,err!=1?strings[S_ErrPlur]:strings[S_ErrSing]); //"\r\nEnd (%.2f s) %d %s\r\n\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+ PrintStatusClear(); //clear status report
+}
+
+void Write16F87xA (int dim,int dim2,int seq)
+// write 14 bit PIC
+// dim=program size dim2=eeprom size
+// seq=0: vdd + (50ms) + vdd&vpp
+// seq=1: vdd + (50us) + vdd&vpp
+// DevID@0x2006
+// Config@0x2007
+// write CONFIG2@0x2008 if different from 3FFF
+// eeprom@0x2100
+// erase:
+// CHIP ERASE (11111) + 15ms
+// write: LOAD_DATA_PROG (0010) + BEGIN_PROG2 (11000) + 1.2ms + END_PROGX (10111)
+// write eeprom: LOAD_DATA_DATA (0011) + BEGIN_PROG (1000) + 12ms
+// verify during write
+{
+ int err=0;
+ WORD devID,config;
+ int k=0,z=0,i,j,w;
+ if(sizeW<0x2007){
+ PrintMessage(strings[S_NoConfigW3]); //"Can't find CONFIG (0x2007)\r\nEnd\r\n"
+ return;
+ }
+ if(dim2){
+ if(sizeW<0x2100){
+ dim2=0;
+ PrintMessage(strings[S_NoEEMem]); //"Can't find EEPROM data\r\n"
+ }
+ else if(dim2>sizeW-0x2100) dim2=sizeW-0x2100;
+ }
+ if(saveLog){
+ OpenLogFile(); //"log.txt"
+ fprintf(logfile,"Write16F87xA(%d,%d,%d)\n",dim,dim2,seq);
+ }
+ for(i=0;i<sizeW;i++) memCODE_W[i]&=0x3FFF;
+ unsigned int start=GetTickCount();
+ bufferU[0]=0;
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T1T2;
+ bufferU[j++]=1; //T1=1u
+ bufferU[j++]=100; //T2=100u
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=25000>>8;
+ bufferU[j++]=25000&0xff;
+ bufferU[j++]=EN_VPP_VCC; //enter program mode
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ if(seq==0){
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=WAIT_T3;
+ }
+ bufferU[j++]=EN_VPP_VCC; //VDD+VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=NOP;
+ bufferU[j++]=LOAD_CONF; //counter at 0x2000
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=0x06;
+ bufferU[j++]=READ_DATA_PROG; //DevID
+ bufferU[j++]=INC_ADDR;
+ bufferU[j++]=READ_DATA_PROG; //Config
+ bufferU[j++]=EN_VPP_VCC; //exit program mode
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=WAIT_T3; //delay after exiting prog mode
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC; //VDD+VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(seq==0?90:40);
+ for(z=0;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ devID=(bufferI[z+1]<<8)+bufferI[z+2];
+ PrintMessage1(strings[S_DevID],devID); //"DevID: 0x%04X\r\n"
+ PIC16_ID(devID);
+ for(z+=3;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ config=(bufferI[z+1]<<8)+bufferI[z+2];
+ PrintMessage1(strings[S_ConfigWord],config); //"Config word: 0x%04X\r\n"
+//****************** erase memory ********************
+ PrintMessage(strings[S_StartErase]); //"Erase ... "
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=15000>>8;
+ bufferU[j++]=15000&0xff;
+ if(ICDenable||programID){ //erase 0x2000-2004 also
+ bufferU[j++]=LOAD_CONF; //counter at 0x2000
+ bufferU[j++]=0x3F; //fake config
+ bufferU[j++]=0xFF; //fake config
+ }
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x1F; // CHIP_ERASE (11111)
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=EN_VPP_VCC; //exit program mode
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=WAIT_T3; //delay after exiting prog mode
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC; //VDD+VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=1200>>8;
+ bufferU[j++]=1200&0xff;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(60);
+ PrintMessage(strings[S_Compl]); //"completed\r\n"
+//****************** write code ********************
+ PrintMessage(strings[S_StartCodeProg]); //"Write code ... "
+ PrintStatusSetup();
+ for(w=i=k=0,j=0;i<dim;i++){
+ if(memCODE_W[i]<0x3fff){
+ bufferU[j++]=LOAD_DATA_PROG;
+ bufferU[j++]=memCODE_W[i]>>8; //MSB
+ bufferU[j++]=memCODE_W[i]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG2; //externally timed
+ bufferU[j++]=WAIT_T3; //Tprogram
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x17; //END_PROGX (10111)
+ bufferU[j++]=READ_DATA_PROG;
+ w++;
+ }
+ bufferU[j++]=INC_ADDR;
+ if(j>DIMBUF-11||i==dim-1){
+ PrintStatus(strings[S_CodeWriting],i*100/dim,i); //"Writing: %d%%, add. %03X"
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(w*1.5+(6-w)*0.2+2);
+ w=0;
+ for(z=0;z<DIMBUF-6;z++){
+ if(bufferI[z]==INC_ADDR&&memCODE_W[k]>=0x3fff) k++;
+ else if(bufferI[z]==LOAD_DATA_PROG&&bufferI[z+4]==READ_DATA_PROG){
+ if (memCODE_W[k]!=(bufferI[z+5]<<8)+bufferI[z+6]){
+ PrintMessage("\r\n");
+ PrintMessage3(strings[S_CodeWError2],k,memCODE_W[k],(bufferI[z+5]<<8)+bufferI[z+6]); //"Error writing address %3X: written %04X, read %04X\r\n"
+ err++;
+ if(max_err&&err>max_err){
+ PrintMessage1(strings[S_MaxErr],err); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ PrintMessage(strings[S_IntW]); //"Write interrupted"
+ i=dim;
+ z=DIMBUF;
+ }
+ }
+ k++;
+ z+=7;
+ }
+ }
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,err); //"i=%d, k=%d, errors=%d \n"
+ }
+ }
+ }
+ err+=i-k;
+ PrintStatusEnd();
+ PrintMessage1(strings[S_ComplErr],err); //"completed, %d errors\r\n"
+//****************** write eeprom ********************
+ if(dim2){
+ int err_e=0;
+ PrintMessage(strings[S_EEAreaW]); //"Writing EEPROM ... "
+ PrintStatusSetup();
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=12000>>8;
+ bufferU[j++]=12000&0xff;
+ bufferU[j++]=LOAD_CONF; //counter at 0x2000
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=INC_ADDR_N; //use only INC_ADDR_N so verification does not look at it
+ bufferU[j++]=0xFF;
+ bufferU[j++]=INC_ADDR_N; //EEPROM: counter at 0x2100
+ bufferU[j++]=1;
+ for(w=0,i=k=0x2100;i<0x2100+dim2;i++){
+ if(memCODE_W[i]<0xff){
+ bufferU[j++]=LOAD_DATA_DATA;
+ bufferU[j++]=memCODE_W[i]&0xff;
+ bufferU[j++]=BEGIN_PROG; //internally timed
+ bufferU[j++]=WAIT_T3; //Tprogram 8ms
+ bufferU[j++]=READ_DATA_DATA;
+ w++;
+ }
+ bufferU[j++]=INC_ADDR;
+ if(j>DIMBUF-10||i==0x2100+dim2-1){
+ PrintStatus(strings[S_CodeWriting],(i-0x2100+dim)*100/(dim+dim2),i); //"Writing: %d%%, add. %03X"
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(w*12.5+5);
+ w=0;
+ for(z=0;z<DIMBUF-4;z++){
+ if(bufferI[z]==INC_ADDR&&memCODE_W[k]>=0xff) k++;
+ else if(bufferI[z]==LOAD_DATA_DATA&&bufferI[z+3]==READ_DATA_DATA){
+ if (memCODE_W[k]!=bufferI[z+4]){
+ PrintMessage("\r\n");
+ PrintMessage3(strings[S_CodeWError3],k,memCODE_W[k],bufferI[z+4]); //"Error writing address %4X: written %02X, read %02X\r\n"
+ err_e++;
+ if(max_err&&err>max_err){
+ PrintMessage1(strings[S_MaxErr],err); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ PrintMessage(strings[S_IntW]); //"Write interrupted"
+ i=0x2200;
+ z=DIMBUF;
+ }
+ }
+ k++;
+ z+=5;
+ }
+ }
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,err); //"i=%d, k=%d, errors=%d \n"
+ }
+ }
+ }
+ err_e+=i-k;
+ err+=err_e;
+ PrintStatusEnd();
+ PrintMessage1(strings[S_ComplErr],err_e); //"completed, %d errors\r\n"
+ }
+//****************** write ID, CONFIG, CALIB ********************
+ PrintMessage(strings[S_ConfigAreaW]); //"Writing CONFIG area ... "
+ int err_c=0;
+ int ICDgoto=0x2800+(ICDaddr&0x7FF); //GOTO ICD routine (0x28xx)
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=12000>>8;
+ bufferU[j++]=12000&0xff;
+ bufferU[j++]=LOAD_CONF; //counter at 0x2000
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=0xFF; //fake config
+ if(programID){
+ for(i=0x2000;i<0x2004;i++){
+ bufferU[j++]=LOAD_DATA_PROG;
+ bufferU[j++]=memCODE_W[i]>>8; //MSB
+ bufferU[j++]=memCODE_W[i]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG; //internally timed
+ bufferU[j++]=WAIT_T3; //Tprogram
+ bufferU[j++]=READ_DATA_PROG;
+ bufferU[j++]=INC_ADDR;
+ }
+ }
+ else{
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=4;
+ }
+ if(ICDenable){ //write a GOTO ICD routine (0x28xx)
+ bufferU[j++]=LOAD_DATA_PROG;
+ bufferU[j++]=ICDgoto>>8; //MSB
+ bufferU[j++]=ICDgoto&0xFF; //LSB
+ bufferU[j++]=BEGIN_PROG; //internally timed
+ bufferU[j++]=WAIT_T3; //Tprogram
+ bufferU[j++]=READ_DATA_PROG;
+ }
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=3;
+ bufferU[j++]=LOAD_DATA_PROG; //Config word 0x2007
+ bufferU[j++]=memCODE_W[0x2007]>>8; //MSB
+ bufferU[j++]=memCODE_W[0x2007]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG; //internally timed
+ bufferU[j++]=WAIT_T3; //Tprogram
+ bufferU[j++]=READ_DATA_PROG;
+ bufferU[j++]=INC_ADDR;
+ if(sizeW>0x2008&&memCODE_W[0x2008]!=0x3fff){
+ bufferU[j++]=LOAD_DATA_PROG; //Config word2 0x2008
+ bufferU[j++]=memCODE_W[0x2008]>>8; //MSB
+ bufferU[j++]=memCODE_W[0x2008]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG; //internally timed
+ bufferU[j++]=WAIT_T3; //Tprogram
+ bufferU[j++]=READ_DATA_PROG;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ i=28;
+ if(programID) i+=50;
+ if(ICDenable) i+=13;
+ PacketIO(i);
+ for(i=0,z=0;programID&&i<4;i++){
+ for(;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if (memCODE_W[0x2000+i]!=(bufferI[z+1]<<8)+bufferI[z+2]){
+ PrintMessage3(strings[S_IDErr],i,memCODE_W[0x2000+i],(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing ID%d: written %04X, read %04X\r\n"
+ err_c++;
+ }
+ z+=6;
+ }
+ if(ICDenable){
+ for(;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if (ICDgoto!=(bufferI[z+1]<<8)+bufferI[z+2]){
+ PrintMessage4(strings[S_ICDErr],0x2004,i,ICDgoto,(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing ICD (0x%X): written %04X, read %04X\r\n"
+ err_c++;
+ }
+ z+=6;
+ }
+ for(;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if(~memCODE_W[0x2007]&((bufferI[z+1]<<8)+bufferI[z+2])){ //error if written 0 and read 1 (~W&R)
+ PrintMessage2(strings[S_ConfigWErr3],memCODE_W[0x2007],(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing config area: written %04X, read %04X\r\n"
+ err_c++;
+ }
+ if(sizeW>0x2008&&memCODE_W[0x2008]!=0x3fff){
+ for(z+=6;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if(~memCODE_W[0x2008]&((bufferI[z+1]<<8)+bufferI[z+2])){ //error if written 0 and read 1 (~W&R)
+ PrintMessage2(strings[S_ConfigWErr3],memCODE_W[0x2008],(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing config area: written %04X, read %04X\r\n"
+ err_c++;
+ }
+ }
+ err+=err_c;
+ PrintMessage1(strings[S_ComplErr],err_c); //"completed, %d errors\r\n"
+ if(saveLog){
+ fprintf(logfile,strings[S_Log9],err); //"Area config. errors=%d \n"
+ }
+//****************** exit ********************
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2000>>8;
+ bufferU[j++]=2000&0xff;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ unsigned int stop=GetTickCount();
+ sprintf(str,strings[S_EndErr],(stop-start)/1000.0,err,err!=1?strings[S_ErrPlur]:strings[S_ErrSing]); //"\r\nEnd (%.2f s) %d %s\r\n\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+ PrintStatusClear(); //clear status report
+}
+
+void Write16F81x (int dim,int dim2)
+// write 14 bit PIC
+// dim=program size dim2=eeprom size
+// seq=0: vdd + (50ms) + vdd&vpp
+// seq=1: vdd + (50us) + vdd&vpp
+// DevID@0x2006
+// Config@0x2007
+// write CONFIG2@0x2008 if different from 3FFF
+// erase if protected: CHIP ERASE (11111) + 8ms
+// erase if not protected:
+// BULK_ERASE_PROG (1001) + BEGIN_PROG (1001) + 2ms + END_PROGX (10111)
+// BULK_ERASE_DATA (1011) + BEGIN_PROG (1001) + 2ms + END_PROGX (10111)
+// write: LOAD_DATA_PROG (0010) + BEGIN_PROG2 (11000) + 1.5ms + END_PROGX (10111)
+// write eeprom: LOAD_DATA_DATA (0011) + BEGIN_PROG2 (11000) + 1.5ms + END_PROGX (10111)
+// verify during write
+{
+ int err=0;
+ WORD devID,config;
+ int k=0,z=0,i,j,w;
+ if(sizeW<0x2007){
+ PrintMessage(strings[S_NoConfigW3]); //"Can't find CONFIG (0x2007)\r\nEnd\r\n"
+ return;
+ }
+ if(dim2){
+ if(sizeW<0x2100){
+ dim2=0;
+ PrintMessage(strings[S_NoEEMem]); //"Can't find EEPROM data\r\n"
+ }
+ else if(dim2>sizeW-0x2100) dim2=sizeW-0x2100;
+ }
+ if(saveLog){
+ OpenLogFile(); //"log.txt"
+ fprintf(logfile,"Write16F81x(%d,%d)\n",dim,dim2);
+ }
+ for(i=0;i<sizeW;i++) memCODE_W[i]&=0x3FFF;
+ unsigned int start=GetTickCount();
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T1T2;
+ bufferU[j++]=1; //T1=1u
+ bufferU[j++]=100; //T2=100u
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=25000>>8;
+ bufferU[j++]=25000&0xff;
+ bufferU[j++]=EN_VPP_VCC; //enter program mode
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC; //VDD+VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=NOP;
+ bufferU[j++]=LOAD_CONF; //counter at 0x2000
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=0x06;
+ bufferU[j++]=READ_DATA_PROG; //DevID
+ bufferU[j++]=INC_ADDR;
+ bufferU[j++]=READ_DATA_PROG; //Config
+ bufferU[j++]=NOP; //exit program mode
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=WAIT_T3; //delay after exiting prog mode
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC; //VDD+VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(40);
+ for(z=0;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ devID=(bufferI[z+1]<<8)+bufferI[z+2];
+ PrintMessage1(strings[S_DevID],devID); //"DevID: 0x%04X\r\n"
+ PIC16_ID(devID);
+ for(z+=3;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ config=(bufferI[z+1]<<8)+bufferI[z+2];
+ PrintMessage1(strings[S_ConfigWord],config); //"Config word: 0x%04X\r\n"
+//****************** erase memory ********************
+ PrintMessage(strings[S_StartErase]); //"Erase ... "
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2000>>8;
+ bufferU[j++]=2000&0xff;
+ if(programID||ICDenable){
+ bufferU[j++]=LOAD_CONF; //counter at 0x2000
+ bufferU[j++]=0x3F; //fake config
+ bufferU[j++]=0xFF; //fake config
+ }
+ if((config&0x2100)!=0x2100){
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x1F; // CHIP_ERASE (11111)
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=WAIT_T3;
+ }
+ else{
+ bufferU[j++]=BULK_ERASE_PROG;
+ bufferU[j++]=BEGIN_PROG;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x17; //END_PROGX (10111)
+ }
+ bufferU[j++]=NOP; //exit program mode
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=WAIT_T3; //delay after exiting prog mode
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC; //VDD+VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(15);
+ PrintMessage(strings[S_Compl]); //"completed\r\n"
+//****************** write code ********************
+ PrintMessage(strings[S_StartCodeProg]); //"Write code ... "
+ PrintStatusSetup();
+ for(w=i=k=0,j=0;i<dim;i++){
+ if(memCODE_W[i]<0x3fff){
+ bufferU[j++]=LOAD_DATA_PROG;
+ bufferU[j++]=memCODE_W[i]>>8; //MSB
+ bufferU[j++]=memCODE_W[i]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG2; //externally timed
+ bufferU[j++]=WAIT_T3; //Tprogram
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x17; //END_PROGX (10111)
+ bufferU[j++]=READ_DATA_PROG;
+ w++;
+ }
+ bufferU[j++]=INC_ADDR;
+ if(j>DIMBUF-11||i==dim-1){
+ PrintStatus(strings[S_CodeWriting],i*100/dim,i); //"Writing: %d%%, add. %03X"
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(w*2.5+3);
+ w=0;
+ for(z=0;z<DIMBUF-6;z++){
+ if(bufferI[z]==INC_ADDR&&memCODE_W[k]>=0x3fff) k++;
+ else if(bufferI[z]==LOAD_DATA_PROG&&bufferI[z+4]==READ_DATA_PROG){
+ if (memCODE_W[k]!=(bufferI[z+5]<<8)+bufferI[z+6]){
+ PrintMessage("\r\n");
+ PrintMessage3(strings[S_CodeWError2],k,memCODE_W[k],(bufferI[z+5]<<8)+bufferI[z+6]); //"Error writing address %3X: written %04X, read %04X\r\n"
+ err++;
+ if(max_err&&err>max_err){
+ PrintMessage1(strings[S_MaxErr],err); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ PrintMessage(strings[S_IntW]); //"Write interrupted"
+ i=dim;
+ z=DIMBUF;
+ }
+ }
+ k++;
+ z+=7;
+ }
+ }
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,err); //"i=%d, k=%d, errors=%d \n"
+ }
+ }
+ }
+ err+=i-k;
+ PrintStatusEnd();
+ PrintMessage1(strings[S_ComplErr],err); //"completed, %d errors\r\n"
+//****************** write eeprom ********************
+ if(dim2){
+ int err_e=0;
+ PrintMessage(strings[S_EEAreaW]); //"Writing EEPROM ... "
+ PrintStatusSetup();
+ j=0;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=WAIT_T3; //delay after exiting prog mode
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC; //VDD+VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=LOAD_DATA_DATA;
+ bufferU[j++]=0x01;
+ bufferU[j++]=BULK_ERASE_DATA;
+ bufferU[j++]=BEGIN_PROG;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x17; //END_PROGX (10111)
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ j=0;
+ for(w=0,i=k=0x2100;i<0x2100+dim2;i++){
+ if(memCODE_W[i]<0xff){
+ bufferU[j++]=LOAD_DATA_DATA;
+ bufferU[j++]=memCODE_W[i]&0xff;
+ bufferU[j++]=BEGIN_PROG2; //externally timed
+ bufferU[j++]=WAIT_T3; //Tprogram
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x17; //END_PROGX (10111)
+ bufferU[j++]=READ_DATA_DATA;
+ w++;
+ }
+ bufferU[j++]=INC_ADDR;
+ if(j>DIMBUF-10||i==0x2100+dim2-1){
+ PrintStatus(strings[S_CodeWriting],(i-0x2100+dim)*100/(dim+dim2),i); //"Writing: %d%%, add. %03X"
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(w*2.5+5);
+ w=0;
+ for(z=0;z<DIMBUF-5;z++){
+ if(bufferI[z]==INC_ADDR&&memCODE_W[k]>=0xff) k++;
+ else if(bufferI[z]==LOAD_DATA_DATA&&bufferI[z+4]==READ_DATA_DATA){
+ if (memCODE_W[k]!=bufferI[z+5]){
+ PrintMessage("\r\n");
+ PrintMessage3(strings[S_CodeWError3],k,memCODE_W[k],bufferI[z+5]); //"Error writing address %4X: written %02X, read %02X\r\n"
+ err_e++;
+ if(max_err&&err>max_err){
+ PrintMessage1(strings[S_MaxErr],err); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ PrintMessage(strings[S_IntW]); //"Write interrupted"
+ i=0x2200;
+ z=DIMBUF;
+ }
+ }
+ k++;
+ z+=6;
+ }
+ }
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,err); //"i=%d, k=%d, errors=%d \n"
+ }
+ }
+ }
+ err_e+=i-k;
+ err+=err_e;
+ PrintStatusEnd();
+ PrintMessage1(strings[S_ComplErr],err_e); //"completed, %d errors\r\n"
+ }
+//****************** write ID, CONFIG, CALIB ********************
+ PrintMessage(strings[S_ConfigAreaW]); //"Writing CONFIG area ... "
+ int err_c=0;
+ int ICDgoto=0x2800+(ICDaddr&0x7FF); //GOTO ICD routine (0x28xx)
+ bufferU[j++]=LOAD_CONF; //counter at 0x2000
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=0xFF; //fake config
+ if(programID){
+ for(i=0x2000;i<0x2004;i++){
+ bufferU[j++]=LOAD_DATA_PROG;
+ bufferU[j++]=memCODE_W[i]>>8; //MSB
+ bufferU[j++]=memCODE_W[i]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG2; //externally timed
+ bufferU[j++]=WAIT_T3; //Tprogram
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x17; //END_PROGX (10111)
+ bufferU[j++]=READ_DATA_PROG;
+ bufferU[j++]=INC_ADDR;
+ }
+ }
+ else{
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=4;
+ }
+ if(ICDenable){ //write a GOTO ICD routine (0x28xx)
+ bufferU[j++]=LOAD_DATA_PROG;
+ bufferU[j++]=ICDgoto>>8; //MSB
+ bufferU[j++]=ICDgoto&0xFF; //LSB
+ bufferU[j++]=BEGIN_PROG2; //externally timed
+ bufferU[j++]=WAIT_T3; //Tprogram
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x17; //END_PROGX (10111)
+ bufferU[j++]=READ_DATA_PROG;
+ }
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=3;
+ bufferU[j++]=LOAD_DATA_PROG; //Config word 0x2007
+ bufferU[j++]=memCODE_W[0x2007]>>8; //MSB
+ bufferU[j++]=memCODE_W[0x2007]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG2; //externally timed
+ bufferU[j++]=WAIT_T3; //Tprogram
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x17; //END_PROGX (10111)
+ bufferU[j++]=READ_DATA_PROG;
+ bufferU[j++]=INC_ADDR;
+ if(sizeW>0x2008&&memCODE_W[0x2008]!=0x3fff){
+ bufferU[j++]=LOAD_DATA_PROG; //Config word2 0x2008
+ bufferU[j++]=memCODE_W[0x2008]>>8; //MSB
+ bufferU[j++]=memCODE_W[0x2008]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG2; //externally timed
+ bufferU[j++]=WAIT_T3; //Tprogram
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x17; //END_PROGX (10111)
+ bufferU[j++]=READ_DATA_PROG;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(15);
+ for(i=0,z=0;programID&&i<4;i++){
+ for(;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if (memCODE_W[0x2000+i]!=(bufferI[z+1]<<8)+bufferI[z+2]){
+ PrintMessage3(strings[S_IDErr],i,memCODE_W[0x2000+i],(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing ID%d: written %04X, read %04X\r\n"
+ err_c++;
+ }
+ z+=7;
+ }
+ if(ICDenable){
+ for(;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if (ICDgoto!=(bufferI[z+1]<<8)+bufferI[z+2]){
+ PrintMessage4(strings[S_ICDErr],0x2004,i,ICDgoto,(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing ICD (0x%X): written %04X, read %04X\r\n"
+ err_c++;
+ }
+ z+=7;
+ }
+ for(;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if(~memCODE_W[0x2007]&((bufferI[z+1]<<8)+bufferI[z+2])){ //error if written 0 and read 1 (~W&R)
+ PrintMessage2(strings[S_ConfigWErr3],memCODE_W[0x2007],(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing config area: written %04X, read %04X\r\n"
+ err_c++;
+ }
+ if(sizeW>0x2008&&memCODE_W[0x2008]!=0x3fff){
+ for(z+=7;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if(~memCODE_W[0x2008]&((bufferI[z+1]<<8)+bufferI[z+2])){ //error if written 0 and read 1 (~W&R)
+ PrintMessage2(strings[S_ConfigWErr3],memCODE_W[0x2008],(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing config area: written %04X, read %04X\r\n"
+ err_c++;
+ }
+ }
+ err+=err_c;
+ PrintMessage1(strings[S_ComplErr],err_c); //"completed, %d errors\r\n"
+ if(saveLog){
+ fprintf(logfile,strings[S_Log9],err); //"Area config. errors=%d \n"
+ }
+//****************** exit ********************
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2000>>8;
+ bufferU[j++]=2000&0xff;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ unsigned int stop=GetTickCount();
+ sprintf(str,strings[S_EndErr],(stop-start)/1000.0,err,err!=1?strings[S_ErrPlur]:strings[S_ErrSing]); //"\r\nEnd (%.2f s) %d %s\r\n\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+ PrintStatusClear(); //clear status report
+}
+
+void Write12F61x(int dim, int d, int d2)
+// write 14 bit PIC
+// dim=program size
+// d not used
+// vpp before vdd
+// DevREV@0x2005
+// DevID@0x2006
+// Config@0x2007
+// Calib1@0x2008 (save)
+// Calib2@0x2009
+// erase: BULK_ERASE_PROG (1001) +10ms
+// write: LOAD_DATA_PROG (0010) + BEGIN_PROG2 (11000) + 4ms + END_PROG (1010)
+// verify during write
+{
+ int err=0;
+ WORD devID=0x3fff,devREV=0x3fff,calib1=0x3fff,calib2=0x3fff;
+ int k=0,z=0,i,j,w;
+ if(sizeW<0x2007){
+ PrintMessage(strings[S_NoConfigW3]); //"Can't find CONFIG (0x2007)\r\nEnd\r\n"
+ return;
+ }
+ if(load_calibword){
+ if(sizeW>0x2008) load_calibword=1;
+ else{
+ PrintMessage(strings[S_NoCalibW]); //"Can't find calibration data\r\n"
+ load_calibword=0;
+ }
+ }
+ if(saveLog){
+ OpenLogFile(); //"log.txt"
+ fprintf(logfile,"Write12F61x(%d)\n",dim);
+ }
+ for(i=0;i<0x2009&&i<sizeW;i++) memCODE_W[i]&=0x3FFF;
+ unsigned int start=GetTickCount();
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T1T2;
+ bufferU[j++]=1; //T1=1u
+ bufferU[j++]=100; //T2=100u
+ bufferU[j++]=EN_VPP_VCC; //enter program mode
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=EN_VPP_VCC; //VPP
+ bufferU[j++]=0x4;
+ bufferU[j++]=NOP;
+ bufferU[j++]=EN_VPP_VCC; //VDD+VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=NOP;
+ bufferU[j++]=LOAD_CONF; //counter at 0x2000
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=0x05;
+ bufferU[j++]=READ_DATA_PROG; //DevREV
+ bufferU[j++]=INC_ADDR;
+ bufferU[j++]=READ_DATA_PROG; //DevID
+ bufferU[j++]=INC_ADDR;
+ bufferU[j++]=INC_ADDR;
+ bufferU[j++]=READ_DATA_PROG; //Calib1
+ bufferU[j++]=INC_ADDR;
+ bufferU[j++]=READ_DATA_PROG; //Calib2
+ bufferU[j++]=NOP; //exit program mode
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=10000>>8;
+ bufferU[j++]=10000&0xff;
+ bufferU[j++]=WAIT_T3; //delay after exiting prog mode
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(15);
+ for(z=0;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ devREV=(bufferI[z+1]<<8)+bufferI[z+2];
+ for(z+=3;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ devID=(bufferI[z+1]<<8)+bufferI[z+2];
+ PrintMessage1(strings[S_DevID],devID); //"DevID: 0x%04X\r\n"
+ if(devREV<0x3FFF) PrintMessage1(strings[S_DevREV],devREV); //"DevREV: 0x%04X\r\n"
+ PIC16_ID(devID);
+ for(z+=3;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ calib1=(bufferI[z+1]<<8)+bufferI[z+2];
+ for(z+=3;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ calib2=(bufferI[z+1]<<8)+bufferI[z+2];
+ if(calib1<0x3fff) PrintMessage1(strings[S_CalibWord1],calib1); //"Calib1: 0x%04X\r\n"
+ if(calib2<0x3fff) PrintMessage1(strings[S_CalibWord2],calib2); //"Calib2: 0x%04X\r\n"
+//****************** erase memory ********************
+ PrintMessage(strings[S_StartErase]); //"Erase ... "
+ j=0;
+ bufferU[j++]=EN_VPP_VCC; //enter program mode
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=EN_VPP_VCC; //VPP
+ bufferU[j++]=0x4;
+ bufferU[j++]=NOP;
+ bufferU[j++]=EN_VPP_VCC; //VDD+VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=NOP;
+ if(programID||load_calibword){
+ bufferU[j++]=LOAD_CONF; //counter at 0x2000
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=0xFF; //fake config
+ if(load_calibword){
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=0x08;
+ }
+ }
+ bufferU[j++]=BULK_ERASE_PROG;
+ bufferU[j++]=WAIT_T3; // delay T3=10ms
+ bufferU[j++]=EN_VPP_VCC; //exit program mode
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=WAIT_T3; // delay T3=10ms after exiting program mode
+ bufferU[j++]=EN_VPP_VCC; //enter program mode
+ bufferU[j++]=0x4;
+ bufferU[j++]=NOP;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x5;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=4000>>8;
+ bufferU[j++]=4000&0xff;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(40);
+ PrintMessage(strings[S_Compl]); //"completed\r\n"
+//****************** write code ********************
+ PrintMessage(strings[S_StartCodeProg]); //"Write code ... "
+ PrintStatusSetup();
+ for(w=i=k=0,j=0;i<dim;i++){
+ if(memCODE_W[i]<0x3fff){
+ bufferU[j++]=LOAD_DATA_PROG;
+ bufferU[j++]=memCODE_W[i]>>8; //MSB
+ bufferU[j++]=memCODE_W[i]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG2; //externally timed, T=3ms min
+ bufferU[j++]=WAIT_T3; //Tprogram 4ms
+ bufferU[j++]=END_PROG;
+ bufferU[j++]=WAIT_T2; //Tdischarge 100us
+ bufferU[j++]=READ_DATA_PROG;
+ w++;
+ }
+ bufferU[j++]=INC_ADDR;
+ if(j>DIMBUF-12||i==dim-1){
+ PrintStatus(strings[S_CodeWriting],i*100/dim,i); //"Writing: %d%%, add. %03X"
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(w*5+2.5);
+ w=0;
+ for(z=0;z<DIMBUF-7;z++){
+ if(bufferI[z]==INC_ADDR&&memCODE_W[k]>=0x3fff) k++;
+ else if(bufferI[z]==LOAD_DATA_PROG&&bufferI[z+5]==READ_DATA_PROG){
+ if (memCODE_W[k]!=(bufferI[z+6]<<8)+bufferI[z+7]){
+ PrintMessage("\r\n");
+ PrintMessage3(strings[S_CodeWError2],k,memCODE_W[k],(bufferI[z+4]<<8)+bufferI[z+5]); //"Error writing address %3X: written %04X, read %04X\r\n"
+ err++;
+ if(max_err&&err>max_err){
+ PrintMessage1(strings[S_MaxErr],err); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ PrintMessage(strings[S_IntW]); //"Write interrupted"
+ i=dim;
+ z=DIMBUF;
+ }
+ }
+ k++;
+ z+=8;
+ }
+ }
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,err); //"i=%d, k=%d, errors=%d,\n"
+ }
+ }
+ }
+ err+=i-k;
+ PrintStatusEnd();
+ PrintMessage1(strings[S_ComplErr],err); //"completed, %d errors\r\n"
+//****************** write ID, CONFIG, CALIB ********************
+ PrintMessage(strings[S_ConfigAreaW]); //"Writing CONFIG area ... "
+ int err_c=0;
+ bufferU[j++]=LOAD_CONF; //counter at 0x2000
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=0xFF; //fake config
+ if(programID){
+ for(i=0x2000;i<0x2004;i++){
+ bufferU[j++]=LOAD_DATA_PROG;
+ bufferU[j++]=memCODE_W[i]>>8; //MSB
+ bufferU[j++]=memCODE_W[i]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG2; //externally timed, T=3ms min
+ bufferU[j++]=WAIT_T3; //Tprogram 4ms
+ bufferU[j++]=END_PROG;
+ bufferU[j++]=WAIT_T2; //Tdischarge 100us
+ bufferU[j++]=READ_DATA_PROG;
+ bufferU[j++]=INC_ADDR;
+ }
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=3;
+ }
+ else{
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=7;
+ }
+ bufferU[j++]=LOAD_DATA_PROG; //Config word 0x2007
+ bufferU[j++]=memCODE_W[0x2007]>>8; //MSB
+ bufferU[j++]=memCODE_W[0x2007]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG2; //externally timed, T=3ms min
+ bufferU[j++]=WAIT_T3; //Tprogram 4ms
+ bufferU[j++]=END_PROG;
+ bufferU[j++]=WAIT_T2; //Tdischarge 100us
+ bufferU[j++]=READ_DATA_PROG;
+ bufferU[j++]=INC_ADDR;
+ if(load_calibword){
+ bufferU[j++]=LOAD_DATA_PROG; //Calib word 1
+ bufferU[j++]=memCODE_W[0x2008]>>8; //MSB
+ bufferU[j++]=memCODE_W[0x2008]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG2; //externally timed, T=3ms min
+ bufferU[j++]=WAIT_T3; //Tprogram 4ms
+ bufferU[j++]=END_PROG;
+ bufferU[j++]=WAIT_T2; //Tdischarge 100us
+ bufferU[j++]=READ_DATA_PROG;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(35);
+ for(i=0,z=0;programID&&i<4;i++){
+ for(;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if (memCODE_W[0x2000+i]!=(bufferI[z+1]<<8)+bufferI[z+2]){
+ PrintMessage("\r\n");
+ PrintMessage3(strings[S_IDErr],i,memCODE_W[0x2000+i],(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing ID%d: written %04X, read %04X\r\n"
+ err_c++;
+ }
+ z+=8;
+ }
+ for(;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if(~memCODE_W[0x2007]&((bufferI[z+1]<<8)+bufferI[z+2])){ //error if written 0 and read 1 (~W&R)
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ConfigWErr3],memCODE_W[0x2007],(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing config area: written %04X, read %04X\r\n"
+ err_c++;
+ }
+ if(load_calibword){
+ for(z+=8;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if (memCODE_W[0x2008]!=(bufferI[z+1]<<8)+bufferI[z+2]){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_Calib1Err],memCODE_W[0x2008],(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing Calib1: written %04X, read %04X\r\n"
+ err_c++;
+ }
+ }
+ err+=err_c;
+ PrintMessage1(strings[S_ComplErr],err_c); //"completed, %d errors\r\n"
+ if(saveLog){
+ fprintf(logfile,strings[S_Log9],err); //"Area config. errors=%d \n"
+ }
+//****************** exit ********************
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2000>>8;
+ bufferU[j++]=2000&0xff;
+ bufferU[j++]=NOP; //exit program mode
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ unsigned int stop=GetTickCount();
+ sprintf(str,strings[S_EndErr],(stop-start)/1000.0,err,err!=1?strings[S_ErrPlur]:strings[S_ErrSing]); //"\r\nEnd (%.2f s) %d %s\r\n\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+ PrintStatusClear(); //clear status report
+}
+
+void Write16F88x(int dim,int dim2)
+// write 14 bit PIC
+// dim=program size dim2=eeprom size
+// vpp before vdd
+// DevID@0x2006
+// Config@0x2007
+// Config2@0x2008
+// Calib1@0x2009 (salva)
+// eeprom@0x2100
+// erase: BULK_ERASE_PROG (1001) +6ms
+// write:LOAD_DATA_PROG (0010) + BEGIN_PROG (1000) + 3ms
+// eeprom: BULK_ERASE_DATA (1011) + 6ms
+// LOAD_DATA_DATA (0011) + BEGIN_PROG (1000) + 6ms
+// verify during write
+{
+ int err=0;
+ WORD devID=0x3fff,calib1=0x3fff;
+ int k=0,z=0,i,j,w;
+ if(sizeW<0x2009){
+ PrintMessage(strings[S_NoConfigW4]); //"Can't find CONFIG (0x2008)\r\nEnd\r\n"
+ return;
+ }
+ if(load_calibword){
+ if(sizeW>0x200A) load_calibword=1;
+ else{
+ PrintMessage(strings[S_NoCalibW]); //"Can't find calibration data\r\n"
+ load_calibword=0;
+ }
+ }
+ if(dim2){
+ if(sizeW<0x2100){
+ dim2=0;
+ PrintMessage(strings[S_NoEEMem]); //"Can't find EEPROM data\r\n"
+ }
+ else if(dim2>sizeW-0x2100) dim2=sizeW-0x2100;
+ }
+ if(saveLog){
+ OpenLogFile(); //"log.txt"
+ fprintf(logfile,"Write16F88x(%d,%d)\n",dim,dim2);
+ }
+ for(i=0;i<0x200A&&i<sizeW;i++) memCODE_W[i]&=0x3FFF;
+ unsigned int start=GetTickCount();
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T1T2;
+ bufferU[j++]=1; //T1=1u
+ bufferU[j++]=100; //T2=100u
+ bufferU[j++]=EN_VPP_VCC; //enter program mode
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=EN_VPP_VCC; //VPP
+ bufferU[j++]=0x4;
+ bufferU[j++]=NOP;
+ bufferU[j++]=EN_VPP_VCC; //VDD+VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=NOP;
+ bufferU[j++]=LOAD_CONF; //counter at 0x2000
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=0x06;
+ bufferU[j++]=READ_DATA_PROG; //DevID
+ bufferU[j++]=INC_ADDR;
+ bufferU[j++]=INC_ADDR;
+ bufferU[j++]=INC_ADDR;
+ bufferU[j++]=READ_DATA_PROG; //Calib1
+ bufferU[j++]=NOP; //exit program mode
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=6000>>8;
+ bufferU[j++]=6000&0xff;
+ bufferU[j++]=WAIT_T3; //delay after exiting prog mode
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(15);
+ for(z=0;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ devID=(bufferI[z+1]<<8)+bufferI[z+2];
+ PrintMessage1(strings[S_DevID],devID); //"DevID: 0x%04X\r\n"
+ PIC16_ID(devID);
+ for(z+=3;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ calib1=(bufferI[z+1]<<8)+bufferI[z+2];
+ if(calib1<0x3fff){
+ PrintMessage1(strings[S_CalibWord1],calib1); //"Calib1: 0x%04X\r\n"
+ }
+//****************** erase memory ********************
+ PrintMessage(strings[S_StartErase]); //"Erase ... "
+ j=0;
+ bufferU[j++]=EN_VPP_VCC; //enter program mode
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=EN_VPP_VCC; //VPP
+ bufferU[j++]=0x4;
+ bufferU[j++]=NOP;
+ bufferU[j++]=EN_VPP_VCC; //VDD+VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=NOP;
+ if(programID||load_calibword||ICDenable){
+ bufferU[j++]=LOAD_CONF; //counter at 0x2000
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=0xFF; //fake config
+ if(load_calibword){
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=9;
+ }
+ }
+ bufferU[j++]=BULK_ERASE_PROG;
+ bufferU[j++]=WAIT_T3; // delay T3=6ms
+ bufferU[j++]=EN_VPP_VCC; //exit program mode
+ bufferU[j++]=0x0;
+ bufferU[j++]=WAIT_T3; // delay T3=6ms after exiting program mode
+ bufferU[j++]=EN_VPP_VCC; //enter program mode
+ bufferU[j++]=0x4;
+ bufferU[j++]=NOP;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x5;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=3000>>8;
+ bufferU[j++]=3000&0xff;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(40);
+ PrintMessage(strings[S_Compl]); //"completed\r\n"
+//****************** write code ********************
+ PrintMessage(strings[S_StartCodeProg]); //"Write code ... "
+ PrintStatusSetup();
+ for(w=i=k=0,j=0;i<dim;i++){
+ if(memCODE_W[i]<0x3fff){
+ bufferU[j++]=LOAD_DATA_PROG;
+ bufferU[j++]=memCODE_W[i]>>8; //MSB
+ bufferU[j++]=memCODE_W[i]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG; //internally timed, T=3ms min
+ bufferU[j++]=WAIT_T3; //Tprogram 3ms
+ bufferU[j++]=READ_DATA_PROG;
+ w++;
+ }
+ bufferU[j++]=INC_ADDR;
+ if(j>DIMBUF-12||i==dim-1){
+ PrintStatus(strings[S_CodeWriting],i*100/dim,i); //"Writing: %d%%, add. %03X"
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(w*3+2);
+ w=0;
+ for(z=0;z<DIMBUF-5;z++){
+ if(bufferI[z]==INC_ADDR&&memCODE_W[k]>=0x3fff) k++;
+ else if(bufferI[z]==LOAD_DATA_PROG&&bufferI[z+3]==READ_DATA_PROG){
+ if (memCODE_W[k]!=(bufferI[z+4]<<8)+bufferI[z+5]){
+ PrintMessage("\r\n");
+ PrintMessage3(strings[S_CodeWError2],k,memCODE_W[k],(bufferI[z+4]<<8)+bufferI[z+5]); //"Error writing address %3X: written %04X, read %04X\r\n"
+ err++;
+ if(max_err&&err>max_err){
+ PrintMessage1(strings[S_MaxErr],err); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ PrintMessage(strings[S_IntW]); //"Write interrupted"
+ i=dim;
+ z=DIMBUF;
+ }
+ }
+ k++;
+ z+=6;
+ }
+ }
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,err); //"i=%d, k=%d, errors=%d,\n"
+ }
+ }
+ }
+ err+=i-k;
+ PrintStatusEnd();
+ PrintMessage1(strings[S_ComplErr],err); //"completed, %d errors\r\n"
+//****************** write eeprom ********************
+ if(dim2){
+ PrintMessage(strings[S_EEAreaW]); //"Writing EEPROM ... "
+ PrintStatusSetup();
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=6000>>8;
+ bufferU[j++]=6000&0xff;
+ bufferU[j++]=LOAD_CONF; //counter at 0x2000
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=BULK_ERASE_DATA;
+ bufferU[j++]=WAIT_T3; // delay T3=6ms
+ bufferU[j++]=INC_ADDR_N; //use only INC_ADDR_N so verification does not look at it
+ bufferU[j++]=0xFF;
+ bufferU[j++]=INC_ADDR_N; //EEPROM: counter at 0x2100
+ bufferU[j++]=1;
+ for(w=2,i=k=0x2100;i<0x2100+dim2;i++){
+ if(memCODE_W[i]<0xff){
+ bufferU[j++]=LOAD_DATA_DATA;
+ bufferU[j++]=memCODE_W[i]&0xff;
+ bufferU[j++]=BEGIN_PROG; //internally timed, T=6ms min
+ bufferU[j++]=WAIT_T3; //Tprogram 6ms
+ bufferU[j++]=READ_DATA_DATA;
+ w++;
+ }
+ bufferU[j++]=INC_ADDR;
+ if(j>DIMBUF-12||i==0x2100+dim2-1){
+ PrintStatus(strings[S_CodeWriting],(i-0x2100+dim)*100/(dim+dim2),i); //"Writing: %d%%, add. %03X"
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(w*6.5+2);
+ w=0;
+ for(z=0;z<DIMBUF-4;z++){
+ if(bufferI[z]==INC_ADDR&&memCODE_W[k]>=0xff) k++;
+ else if(bufferI[z]==LOAD_DATA_DATA&&bufferI[z+3]==READ_DATA_DATA){
+ if (memCODE_W[k]!=bufferI[z+4]){
+ PrintMessage("\r\n");
+ PrintMessage3(strings[S_CodeWError3],k,memCODE_W[k],bufferI[z+4]); //"Error writing address %4X: written %02X, read %02X\r\n"
+ err++;
+ if(max_err&&err>max_err){
+ PrintMessage1(strings[S_MaxErr],err); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ PrintMessage(strings[S_IntW]); //"Write interrupted"
+ i=0x2200;
+ z=DIMBUF;
+ }
+ }
+ k++;
+ z+=5;
+ }
+ }
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,err); //"i=%d, k=%d, errors=%d \n"
+ }
+ }
+ }
+ err+=i-k;
+ PrintStatusEnd();
+ PrintMessage1(strings[S_ComplErr],i-k); //"completed, %d errors\r\n"
+ }
+//****************** write ID, CONFIG, CALIB ********************
+ PrintMessage(strings[S_ConfigAreaW]); //"Writing CONFIG area ... "
+ int err_c=0;
+ int ICDgoto=0x2800+(ICDaddr&0x7FF); //GOTO ICD routine (0x28xx)
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=3000>>8;
+ bufferU[j++]=3000&0xff;
+ bufferU[j++]=LOAD_CONF; //counter at 0x2000
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=0xFF; //fake config
+ if(programID){
+ for(i=0x2000;i<0x2004;i++){
+ bufferU[j++]=LOAD_DATA_PROG;
+ bufferU[j++]=memCODE_W[i]>>8; //MSB
+ bufferU[j++]=memCODE_W[i]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG; //internally timed, T=3ms min
+ bufferU[j++]=WAIT_T3; //Tprogram 3ms
+ bufferU[j++]=READ_DATA_PROG;
+ bufferU[j++]=INC_ADDR;
+ }
+ }
+ else{
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=4;
+ }
+ if(ICDenable){ //write a GOTO ICD routine (0x28xx)
+ bufferU[j++]=LOAD_DATA_PROG;
+ bufferU[j++]=ICDgoto>>8; //MSB
+ bufferU[j++]=ICDgoto&0xFF; //LSB
+ bufferU[j++]=BEGIN_PROG; //internally timed, T=3ms min
+ bufferU[j++]=WAIT_T3; //Tprogram 3ms
+ bufferU[j++]=READ_DATA_PROG;
+ }
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=3;
+ bufferU[j++]=LOAD_DATA_PROG; //Config word 0x2007
+ bufferU[j++]=memCODE_W[0x2007]>>8; //MSB
+ bufferU[j++]=memCODE_W[0x2007]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG; //internally timed, T=3ms min
+ bufferU[j++]=WAIT_T3; //Tprogram 3ms
+ bufferU[j++]=READ_DATA_PROG;
+ bufferU[j++]=INC_ADDR;
+ bufferU[j++]=LOAD_DATA_PROG; //Config word2 0x2008
+ bufferU[j++]=memCODE_W[0x2008]>>8; //MSB
+ bufferU[j++]=memCODE_W[0x2008]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG; //internally timed, T=3ms min
+ bufferU[j++]=WAIT_T3; //Tprogram 3ms
+ bufferU[j++]=READ_DATA_PROG;
+ bufferU[j++]=INC_ADDR;
+ if(load_calibword){
+ bufferU[j++]=LOAD_DATA_PROG; //Calib word 1
+ bufferU[j++]=memCODE_W[0x2009]>>8; //MSB
+ bufferU[j++]=memCODE_W[0x2009]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG; //internally timed, T=3ms min
+ bufferU[j++]=WAIT_T3; //Tprogram 3ms
+ bufferU[j++]=READ_DATA_PROG;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(35);
+ for(i=0,z=0;programID&&i<4;i++){
+ for(;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if (memCODE_W[0x2000+i]!=(bufferI[z+1]<<8)+bufferI[z+2]){
+ PrintMessage("\r\n");
+ PrintMessage3(strings[S_IDErr],i,memCODE_W[0x2000+i],(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing ID%d: written %04X, read %04X\r\n"
+ err_c++;
+ }
+ z+=6;
+ }
+ if(ICDenable){
+ for(;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if (ICDgoto!=(bufferI[z+1]<<8)+bufferI[z+2]){
+ PrintMessage4(strings[S_ICDErr],0x2004,i,ICDgoto,(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing ICD (0x%X): written %04X, read %04X\r\n"
+ err_c++;
+ }
+ z+=6;
+ }
+ for(;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if(~memCODE_W[0x2007]&((bufferI[z+1]<<8)+bufferI[z+2])){ //error if written 0 and read 1 (~W&R)
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ConfigWErr3],memCODE_W[0x2007],(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing config area: written %04X, read %04X\r\n"
+ err_c++;
+ }
+ for(z+=6;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if(~memCODE_W[0x2008]&((bufferI[z+1]<<8)+bufferI[z+2])){ //error if written 0 and read 1 (~W&R)
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ConfigWErr3],memCODE_W[0x2008],(bufferI[z+1]<<8)+bufferI[z+2]); //"\r\n"
+ err_c++;
+ }
+ if(load_calibword){
+ for(z+=6;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if (memCODE_W[0x2009]!=(bufferI[z+1]<<8)+bufferI[z+2]){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_Calib1Err],memCODE_W[0x2009],(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing Calib1: written %04X, read %04X\r\n"
+ err_c++;
+ }
+ }
+ err+=err_c;
+ PrintMessage1(strings[S_ComplErr],err_c); //"completed, %d errors\r\n"
+ if(saveLog){
+ fprintf(logfile,strings[S_Log9],err); //"Area config. errors=%d \n"
+ }
+//****************** exit ********************
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2000>>8;
+ bufferU[j++]=2000&0xff;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ unsigned int stop=GetTickCount();
+ sprintf(str,strings[S_EndErr],(stop-start)/1000.0,err,err!=1?strings[S_ErrPlur]:strings[S_ErrSing]); //"\r\nEnd (%.2f s) %d %s\r\n\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+ PrintStatusClear(); //clear status report
+}
+
+void Write16F7x(int dim,int vdd)
+// dim=program size
+// write 14 bit PIC
+// vdd=0 vdd +50ms before vpp
+// vdd=1 vdd before vpp
+// DevID@0x2006
+// Config@0x2007
+// Config2@0x2008
+// erase: BULK_ERASE_PROG (1001) +30ms
+// write:LOAD_DATA_PROG (0010) + BEGIN_PROG (1000) + 1ms + END_PROG2(1110)
+// verify during write
+{
+ int err=0;
+ WORD devID=0x3fff;
+ int k=0,z=0,i,j,w;
+ if(sizeW<0x2007){
+ PrintMessage(strings[S_NoConfigW3]); //"Can't find CONFIG (0x2007)\r\nEnd\r\n"
+ return;
+ }
+ if(saveLog){
+ OpenLogFile(); //"log.txt"
+ fprintf(logfile,"Write16F7x(%d,%d)\n",dim,vdd);
+ }
+ for(i=0;i<0x2009&&i<sizeW;i++) memCODE_W[i]&=0x3FFF;
+ unsigned int start=GetTickCount();
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T1T2;
+ bufferU[j++]=1; //T1=1u
+ bufferU[j++]=100; //T2=100u
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=10000>>8;
+ bufferU[j++]=10000&0xff;
+ bufferU[j++]=EN_VPP_VCC; //enter program mode
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ if(vdd==0){
+ bufferU[j++]=WAIT_T3; //delay between vdd and vpp
+ bufferU[j++]=WAIT_T3; //delay between vdd and vpp
+ bufferU[j++]=WAIT_T3; //delay between vdd and vpp
+ bufferU[j++]=WAIT_T3; //delay between vdd and vpp
+ bufferU[j++]=WAIT_T3; //delay between vdd and vpp
+ }
+ bufferU[j++]=EN_VPP_VCC; //VDD+VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=NOP;
+ bufferU[j++]=LOAD_CONF; //counter at 0x2000
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=0x06;
+ bufferU[j++]=READ_DATA_PROG; //DevID
+ bufferU[j++]=NOP; //exit program mode
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=WAIT_T3; //delay after exiting prog mode
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(vdd?20:70);
+ for(z=0;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ devID=(bufferI[z+1]<<8)+bufferI[z+2];
+ PrintMessage1(strings[S_DevID],devID); //"DevID: 0x%04X\r\n"
+ PIC16_ID(devID);
+//****************** erase memory ********************
+ PrintMessage(strings[S_StartErase]); //"Erase ... "
+ j=0;
+ //enter program mode
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ if(vdd==0){
+ bufferU[j++]=WAIT_T3; //delay between vdd and vpp
+ bufferU[j++]=WAIT_T3; //delay between vdd and vpp
+ bufferU[j++]=WAIT_T3; //delay between vdd and vpp
+ bufferU[j++]=WAIT_T3; //delay between vdd and vpp
+ bufferU[j++]=WAIT_T3; //delay between vdd and vpp
+ }
+ bufferU[j++]=EN_VPP_VCC; //VDD+VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=NOP;
+ bufferU[j++]=BULK_ERASE_PROG;
+ bufferU[j++]=WAIT_T3; // delay T3=10ms
+ bufferU[j++]=WAIT_T3; // delay T3=10ms
+ bufferU[j++]=WAIT_T3; // delay T3=10ms
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(vdd?50:100);
+ PrintMessage(strings[S_Compl]); //"completed\r\n"
+ j=0;
+ //enter program mode
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ if(vdd==0){
+ bufferU[j++]=WAIT_T3; //delay between vdd and vpp
+ bufferU[j++]=WAIT_T3; //delay between vdd and vpp
+ bufferU[j++]=WAIT_T3; //delay between vdd and vpp
+ bufferU[j++]=WAIT_T3; //delay between vdd and vpp
+ bufferU[j++]=WAIT_T3; //delay between vdd and vpp
+ }
+ bufferU[j++]=EN_VPP_VCC; //VDD+VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=1000>>8;
+ bufferU[j++]=1000&0xff;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(vdd?2:52);
+//****************** write code ********************
+ PrintMessage(strings[S_StartCodeProg]); //"Write code ... "
+ PrintStatusSetup();
+ for(w=i=k=0,j=0;i<dim;i++){
+ if(memCODE_W[i]<0x3fff){
+ bufferU[j++]=LOAD_DATA_PROG;
+ bufferU[j++]=memCODE_W[i]>>8; //MSB
+ bufferU[j++]=memCODE_W[i]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG; //externally timed, T=1ms min
+ bufferU[j++]=WAIT_T3; //Tprogram 1ms min
+ bufferU[j++]=END_PROG2;
+ bufferU[j++]=READ_DATA_PROG;
+ w++;
+ }
+ bufferU[j++]=INC_ADDR;
+ if(j>DIMBUF-10||i==dim-1){
+ PrintStatus(strings[S_CodeWriting],i*100/dim,i); //"Writing: %d%%, add. %03X"
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(w*1.5+2);
+ w=0;
+ for(z=0;z<DIMBUF-6;z++){
+ if(bufferI[z]==INC_ADDR&&memCODE_W[k]>=0x3fff) k++;
+ else if(bufferI[z]==LOAD_DATA_PROG&&bufferI[z+4]==READ_DATA_PROG){
+ if (memCODE_W[k]!=(bufferI[z+5]<<8)+bufferI[z+6]){
+ PrintMessage("\r\n");
+ PrintMessage3(strings[S_CodeWError2],k,memCODE_W[k],(bufferI[z+5]<<8)+bufferI[z+6]); //"Error writing address %3X: written %04X, read %04X\r\n"
+ err++;
+ if(max_err&&err>max_err){
+ PrintMessage1(strings[S_MaxErr],err); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ PrintMessage(strings[S_IntW]); //"Write interrupted"
+ i=dim;
+ z=DIMBUF;
+ }
+ }
+ k++;
+ z+=7;
+ }
+ }
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,err); //"i=%d, k=%d, errors=%d,\n"
+ }
+ }
+ }
+ err+=i-k;
+ PrintStatusEnd();
+ PrintMessage1(strings[S_ComplErr],err); //"completed, %d errors\r\n"
+//****************** write ID, CONFIG, CALIB ********************
+ PrintMessage(strings[S_ConfigAreaW]); //"Writing CONFIG area ... "
+ int err_c=0;
+ bufferU[j++]=LOAD_CONF; //counter at 0x2000
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=0xFF; //fake config
+ if(programID){
+ for(i=0x2000;i<0x2004;i++){
+ bufferU[j++]=LOAD_DATA_PROG;
+ bufferU[j++]=memCODE_W[i]>>8; //MSB
+ bufferU[j++]=memCODE_W[i]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG; //externally timed, T=1ms min
+ bufferU[j++]=WAIT_T3; //Tprogram 1ms
+ bufferU[j++]=END_PROG2;
+ bufferU[j++]=READ_DATA_PROG;
+ bufferU[j++]=INC_ADDR;
+ }
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=3;
+ }
+ else{
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=7;
+ }
+ bufferU[j++]=LOAD_DATA_PROG; //Config word 0x2007
+ bufferU[j++]=memCODE_W[0x2007]>>8; //MSB
+ bufferU[j++]=memCODE_W[0x2007]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG; //externally timed, T=1ms min
+ bufferU[j++]=WAIT_T3; //Tprogram 1ms
+ bufferU[j++]=END_PROG2;
+ bufferU[j++]=WAIT_T3; //Tprogram 1ms
+ bufferU[j++]=READ_DATA_PROG;
+ bufferU[j++]=INC_ADDR;
+ if(sizeW>0x2008&&memCODE_W[0x2008]<0x3fff){
+ bufferU[j++]=LOAD_DATA_PROG; //Config word 2 0x2008
+ bufferU[j++]=memCODE_W[0x2008]>>8; //MSB
+ bufferU[j++]=memCODE_W[0x2008]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG; //externally timed, T=1ms min
+ bufferU[j++]=WAIT_T3; //Tprogram 1ms
+ bufferU[j++]=END_PROG2;
+ bufferU[j++]=WAIT_T3; //Tprogram 1ms
+ bufferU[j++]=READ_DATA_PROG;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(15);
+ for(i=0,z=0;programID&&i<4;i++){
+ for(;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if (memCODE_W[0x2000+i]!=(bufferI[z+1]<<8)+bufferI[z+2]){
+ PrintMessage("\r\n");
+ PrintMessage3(strings[S_IDErr],i,memCODE_W[0x2000+i],(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing ID%d: written %04X, read %04X\r\n"
+ err_c++;
+ }
+ z+=6;
+ }
+ for(;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if(~memCODE_W[0x2007]&((bufferI[z+1]<<8)+bufferI[z+2])){ //error if written 0 and read 1 (~W&R)
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ConfigWErr3],memCODE_W[0x2007],(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing config area: written %04X, read %04X\r\n"
+ err_c++;
+ }
+ if(sizeW>0x2008&&memCODE_W[0x2008]<0x3fff){
+ for(z+=6;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if(~memCODE_W[0x2008]&((bufferI[z+1]<<8)+bufferI[z+2])){ //error if written 0 and read 1 (~W&R)
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ConfigWErr3],memCODE_W[0x2008],(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing config area: written %04X, read %04X\r\n"
+ err_c++;
+ }
+ }
+ err+=err_c;
+ PrintMessage1(strings[S_ComplErr],err_c); //"completed, %d errors\r\n"
+ if(saveLog){
+ fprintf(logfile,strings[S_Log9],err); //"Area config. errors=%d \n"
+ }
+//****************** exit ********************
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2000>>8;
+ bufferU[j++]=2000&0xff;
+ bufferU[j++]=NOP; //exit program mode
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ unsigned int stop=GetTickCount();
+ sprintf(str,strings[S_EndErr],(stop-start)/1000.0,err,err!=1?strings[S_ErrPlur]:strings[S_ErrSing]); //"\r\nEnd (%.2f s) %d %s\r\n\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+ PrintStatusClear(); //clear status report
+}
+
+void Write16F71x(int dim,int vdd)
+// write 14 bit PIC
+// dim=program size
+// vdd=0 vdd +50ms before vpp
+// vdd=1 vdd before vpp
+// DevID@0x2006
+// Config@0x2007
+// erase: BULK_ERASE_PROG (1001) +6ms
+// write:LOAD_DATA_PROG (0010) + BEGIN_PROG2 (11000) + 2ms + END_PROG2(1110)
+// verify during write
+{
+ int err=0;
+ WORD devID=0x3fff;
+ int k=0,z=0,i,j,w;
+ if(sizeW<0x2007){
+ PrintMessage(strings[S_NoConfigW3]); //"Can't find CONFIG (0x2007)\r\nEnd\r\n"
+ return;
+ }
+ if(saveLog){
+ OpenLogFile(); //"log.txt"
+ fprintf(logfile,"Write16F71x(%d,%d)\n",dim,vdd);
+ }
+ for(i=0;i<0x2009&&i<sizeW;i++) memCODE_W[i]&=0x3FFF;
+ unsigned int start=GetTickCount();
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T1T2;
+ bufferU[j++]=1; //T1=1u
+ bufferU[j++]=100; //T2=100u
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=10000>>8;
+ bufferU[j++]=10000&0xff;
+ bufferU[j++]=EN_VPP_VCC; //enter program mode
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ if(vdd==0){
+ bufferU[j++]=WAIT_T3; //delay between vdd and vpp
+ bufferU[j++]=WAIT_T3; //delay between vdd and vpp
+ bufferU[j++]=WAIT_T3; //delay between vdd and vpp
+ bufferU[j++]=WAIT_T3; //delay between vdd and vpp
+ bufferU[j++]=WAIT_T3; //delay between vdd and vpp
+ }
+ bufferU[j++]=EN_VPP_VCC; //VDD+VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=NOP;
+ bufferU[j++]=LOAD_CONF; //counter at 0x2000
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=0x06;
+ bufferU[j++]=READ_DATA_PROG; //DevID
+ bufferU[j++]=NOP; //exit program mode
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=WAIT_T3; //delay after exiting prog mode
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(vdd?20:70);
+ for(z=0;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ devID=(bufferI[z+1]<<8)+bufferI[z+2];
+ PrintMessage1(strings[S_DevID],devID); //"DevID: 0x%04X\r\n"
+ PIC16_ID(devID);
+//****************** erase memory ********************
+ PrintMessage(strings[S_StartErase]); //"Erase ... "
+ j=0;
+ //enter program mode
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ if(vdd==0){
+ bufferU[j++]=WAIT_T3; //delay between vdd and vpp
+ bufferU[j++]=WAIT_T3; //delay between vdd and vpp
+ bufferU[j++]=WAIT_T3; //delay between vdd and vpp
+ bufferU[j++]=WAIT_T3; //delay between vdd and vpp
+ bufferU[j++]=WAIT_T3; //delay between vdd and vpp
+ }
+ bufferU[j++]=EN_VPP_VCC; //VDD+VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=NOP;
+ if(programID){
+ bufferU[j++]=LOAD_CONF; //counter at 0x2000
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=0xFF; //fake config
+ }
+ bufferU[j++]=BULK_ERASE_PROG;
+ bufferU[j++]=WAIT_T3; // delay T3=10ms
+ bufferU[j++]=NOP; //exit program mode
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=WAIT_T3; //delay after exiting prog mode
+ //enter program mode
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ if(vdd==0){
+ bufferU[j++]=WAIT_T3; //delay between vdd and vpp
+ bufferU[j++]=WAIT_T3; //delay between vdd and vpp
+ bufferU[j++]=WAIT_T3; //delay between vdd and vpp
+ bufferU[j++]=WAIT_T3; //delay between vdd and vpp
+ bufferU[j++]=WAIT_T3; //delay between vdd and vpp
+ }
+ bufferU[j++]=EN_VPP_VCC; //VDD+VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2000>>8;
+ bufferU[j++]=2000&0xff;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(vdd?30:130);
+ PrintMessage(strings[S_Compl]); //"completed\r\n"
+//****************** write code ********************
+ PrintMessage(strings[S_StartCodeProg]); //"Write code ... "
+ PrintStatusSetup();
+ for(w=i=k=0,j=0;i<dim;i++){
+ if(memCODE_W[i]<0x3fff){
+ bufferU[j++]=LOAD_DATA_PROG;
+ bufferU[j++]=memCODE_W[i]>>8; //MSB
+ bufferU[j++]=memCODE_W[i]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG2; //externally timed, T=1ms min
+ bufferU[j++]=WAIT_T3; //Tprogram 1ms min
+ bufferU[j++]=END_PROG2;
+ bufferU[j++]=WAIT_T2; //Tdischarge 100us
+ bufferU[j++]=READ_DATA_PROG;
+ w++;
+ }
+ bufferU[j++]=INC_ADDR;
+ if(j>DIMBUF-11||i==dim-1){
+ PrintStatus(strings[S_CodeWriting],i*100/dim,i); //"Writing: %d%%, add. %03X"
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(w*2.5+2);
+ w=0;
+ for(z=0;z<DIMBUF-7;z++){
+ if(bufferI[z]==INC_ADDR&&memCODE_W[k]>=0x3fff) k++;
+ else if(bufferI[z]==LOAD_DATA_PROG&&bufferI[z+5]==READ_DATA_PROG){
+ if (memCODE_W[k]!=(bufferI[z+6]<<8)+bufferI[z+7]){
+ PrintMessage("\r\n");
+ PrintMessage3(strings[S_CodeWError2],k,memCODE_W[k],(bufferI[z+6]<<8)+bufferI[z+7]); //"Error writing address %3X: written %04X, read %04X\r\n"
+ err++;
+ if(max_err&&err>max_err){
+ PrintMessage1(strings[S_MaxErr],err); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ PrintMessage(strings[S_IntW]); //"Write interrupted"
+ i=dim;
+ z=DIMBUF;
+ }
+ }
+ k++;
+ z+=8;
+ }
+ }
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,err); //"i=%d, k=%d, errors=%d,\n"
+ }
+ }
+ }
+ err+=i-k;
+ PrintStatusEnd();
+ PrintMessage1(strings[S_ComplErr],err); //"completed, %d errors\r\n"
+//****************** write ID, CONFIG, CALIB ********************
+ PrintMessage(strings[S_ConfigAreaW]); //"Writing CONFIG area ... "
+ int err_c=0;
+ bufferU[j++]=LOAD_CONF; //counter at 0x2000
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=0xFF; //fake config
+ if(programID){
+ for(i=0x2000;i<0x2004;i++){
+ bufferU[j++]=LOAD_DATA_PROG;
+ bufferU[j++]=memCODE_W[i]>>8; //MSB
+ bufferU[j++]=memCODE_W[i]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG2; //externally timed, T=1ms min
+ bufferU[j++]=WAIT_T3; //Tprogram 1ms
+ bufferU[j++]=END_PROG2;
+ bufferU[j++]=WAIT_T2; //Tdischarge 100us
+ bufferU[j++]=READ_DATA_PROG;
+ bufferU[j++]=INC_ADDR;
+ }
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=3;
+ }
+ else{
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=7;
+ }
+ bufferU[j++]=LOAD_DATA_PROG; //Config word 0x2007
+ bufferU[j++]=memCODE_W[0x2007]>>8; //MSB
+ bufferU[j++]=memCODE_W[0x2007]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG2; //externally timed, T=1ms min
+ bufferU[j++]=WAIT_T3; //Tprogram 1ms
+ bufferU[j++]=END_PROG2;
+ bufferU[j++]=WAIT_T2; //Tdischarge 100us
+ bufferU[j++]=READ_DATA_PROG;
+ bufferU[j++]=INC_ADDR;
+ if(sizeW>0x2008&&memCODE_W[0x2008]<0x3fff){
+ bufferU[j++]=LOAD_DATA_PROG; //Config word 2 0x2008
+ bufferU[j++]=memCODE_W[0x2008]>>8; //MSB
+ bufferU[j++]=memCODE_W[0x2008]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG2; //externally timed, T=1ms min
+ bufferU[j++]=WAIT_T3; //Tprogram 1ms
+ bufferU[j++]=END_PROG2;
+ bufferU[j++]=WAIT_T2; //Tdischarge 100us
+ bufferU[j++]=READ_DATA_PROG;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(15);
+ for(i=0,z=0;programID&&i<4;i++){
+ for(;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if (memCODE_W[0x2000+i]!=(bufferI[z+1]<<8)+bufferI[z+2]){
+ PrintMessage("\r\n");
+ PrintMessage3(strings[S_IDErr],i,memCODE_W[0x2000+i],(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing ID%d: written %04X, read %04X\r\n"
+ err_c++;
+ }
+ z+=6;
+ }
+ for(;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if(~memCODE_W[0x2007]&((bufferI[z+1]<<8)+bufferI[z+2])){ //error if written 0 and read 1 (~W&R)
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ConfigWErr3],memCODE_W[0x2007],(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing config area: written %04X, read %04X\r\n"
+ err_c++;
+ }
+ if(sizeW>0x2008&&memCODE_W[0x2008]<0x3fff){
+ for(z+=6;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if(~memCODE_W[0x2008]&((bufferI[z+1]<<8)+bufferI[z+2])){ //error if written 0 and read 1 (~W&R)
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ConfigWErr3],memCODE_W[0x2008],(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing config area: written %04X, read %04X\r\n"
+ err_c++;
+ }
+ }
+ err+=err_c;
+ PrintMessage1(strings[S_ComplErr],err_c); //"completed, %d errors\r\n"
+ if(saveLog){
+ fprintf(logfile,strings[S_Log9],err); //"Area config. errors=%d \n"
+ }
+//****************** exit ********************
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2000>>8;
+ bufferU[j++]=2000&0xff;
+ bufferU[j++]=NOP; //exit program mode
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ unsigned int stop=GetTickCount();
+ sprintf(str,strings[S_EndErr],(stop-start)/1000.0,err,err!=1?strings[S_ErrPlur]:strings[S_ErrSing]); //"\r\nEnd (%.2f s) %d %s\r\n\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+ PrintStatusClear(); //clear status report
+}
+
+void Write16F72x(int dim, int d, int d2)
+// write 14 bit PIC
+// dim=program size
+// d not used
+// vpp before vdd
+// DevID@0x2006
+// Config@0x2007
+// Config2@0x2008 (not used on LF devices)
+// erase: BULK_ERASE_PROG (1001) +6ms
+// write:LOAD_DATA_PROG (0010) + BEGIN_PROG (1000) + 2.5ms
+// verify during write
+{
+ int err=0;
+ WORD devID=0x3fff;
+ int k=0,z=0,i,j,w;
+ if(!CheckV33Regulator()){
+ PrintMessage(strings[S_noV33reg]); //Can't find 3.3V expansion board
+ return;
+ }
+ if(!StartHVReg(8.5)){
+ PrintMessage(strings[S_HVregErr]); //"HV regulator error\r\n"
+ return;
+ }
+ if(sizeW<0x2008){
+ PrintMessage(strings[S_NoConfigW3]); //"Can't find CONFIG (0x2007)\r\nEnd\r\n"
+ return;
+ }
+ if(saveLog){
+ OpenLogFile(); //"log.txt"
+ fprintf(logfile,"Write16F72x(%d)\n",dim);
+ }
+ for(i=0;i<0x2009&&i<sizeW;i++) memCODE_W[i]&=0x3FFF;
+ unsigned int start=GetTickCount();
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T1T2;
+ bufferU[j++]=1; //T1=1u
+ bufferU[j++]=100; //T2=100u
+ bufferU[j++]=EN_VPP_VCC; //enter program mode
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=EN_VPP_VCC; //VPP
+ bufferU[j++]=0x4;
+ bufferU[j++]=EN_VPP_VCC; //VDD+VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=WAIT_T2;
+ bufferU[j++]=WAIT_T2;
+ bufferU[j++]=WAIT_T2;
+ bufferU[j++]=LOAD_CONF; //counter at 0x2000
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=0x06;
+ bufferU[j++]=READ_DATA_PROG; //DevID
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x16; //Reset address
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=6000>>8;
+ bufferU[j++]=6000&0xff;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(3);
+ for(z=0;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ devID=(bufferI[z+1]<<8)+bufferI[z+2];
+ PrintMessage1(strings[S_DevID],devID); //"DevID: 0x%04X\r\n"
+ PIC16_ID(devID);
+//****************** erase memory ********************
+ PrintMessage(strings[S_StartErase]); //"Erase ... "
+ j=0;
+ if(programID||ICDenable){
+ bufferU[j++]=LOAD_CONF; //counter at 0x2000
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=0xFF; //fake config
+ }
+ bufferU[j++]=READ_DATA_PROG; //DevID
+ bufferU[j++]=BULK_ERASE_PROG;
+ bufferU[j++]=WAIT_T3; // delay T3=6ms
+ bufferU[j++]=READ_DATA_PROG; //DevID
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x16; //Reset address
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2500>>8;
+ bufferU[j++]=2500&0xff;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(18);
+ PrintMessage(strings[S_Compl]); //"completed\r\n"
+//****************** write code ********************
+ PrintMessage(strings[S_StartCodeProg]); //"Write code ... "
+ PrintStatusSetup();
+ for(w=i=k=0,j=0;i<dim;i++){
+ if(memCODE_W[i]<0x3fff){
+ bufferU[j++]=LOAD_DATA_PROG;
+ bufferU[j++]=memCODE_W[i]>>8; //MSB
+ bufferU[j++]=memCODE_W[i]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG; //internally timed, T=3ms min
+ bufferU[j++]=WAIT_T3; //Tprogram 3ms
+ bufferU[j++]=READ_DATA_PROG;
+ w++;
+ }
+ bufferU[j++]=INC_ADDR;
+ if(j>DIMBUF-12||i==dim-1){
+ PrintStatus(strings[S_CodeWriting],i*100/dim,i); //"Writing: %d%%, add. %03X"
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(w*2.5+2);
+ w=0;
+ for(z=0;z<DIMBUF-5;z++){
+ if(bufferI[z]==INC_ADDR&&memCODE_W[k]>=0x3fff) k++;
+ else if(bufferI[z]==LOAD_DATA_PROG&&bufferI[z+3]==READ_DATA_PROG){
+ if (memCODE_W[k]!=(bufferI[z+4]<<8)+bufferI[z+5]){
+ PrintMessage("\r\n");
+ PrintMessage3(strings[S_CodeWError2],k,memCODE_W[k],(bufferI[z+4]<<8)+bufferI[z+5]); //"Error writing address %3X: written %04X, read %04X\r\n"
+ err++;
+ if(max_err&&err>max_err){
+ PrintMessage1(strings[S_MaxErr],err); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ PrintMessage(strings[S_IntW]); //"Write interrupted"
+ i=dim;
+ z=DIMBUF;
+ }
+ }
+ k++;
+ z+=6;
+ }
+ }
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,err); //"i=%d, k=%d, errors=%d,\n"
+ }
+ }
+ }
+ err+=i-k;
+ PrintStatusEnd();
+ PrintMessage1(strings[S_ComplErr],err); //"completed, %d errors\r\n"
+//****************** write ID, CONFIG, CALIB ********************
+ PrintMessage(strings[S_ConfigAreaW]); //"Writing CONFIG area ... "
+ int err_c=0;
+ int ICDgoto=0x2800+(ICDaddr&0x7FF); //GOTO ICD routine (0x28xx)
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=6000>>8;
+ bufferU[j++]=6000&0xff;
+ bufferU[j++]=LOAD_CONF; //counter at 0x2000
+ bufferU[j++]=0xFF; //fake config
+ bufferU[j++]=0xFF; //fake config
+ if(programID){
+ for(i=0x2000;i<0x2004;i++){
+ bufferU[j++]=LOAD_DATA_PROG;
+ bufferU[j++]=memCODE_W[i]>>8; //MSB
+ bufferU[j++]=memCODE_W[i]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG; //internally timed, T=3ms min
+ bufferU[j++]=WAIT_T3; //Tprogram 3ms
+ bufferU[j++]=READ_DATA_PROG;
+ bufferU[j++]=INC_ADDR;
+ }
+ }
+ else{
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=4;
+ }
+ if(ICDenable){ //write a GOTO ICD routine (0x28xx)
+ bufferU[j++]=LOAD_DATA_PROG;
+ bufferU[j++]=ICDgoto>>8; //MSB
+ bufferU[j++]=ICDgoto&0xFF; //LSB
+ bufferU[j++]=BEGIN_PROG; //internally timed, T=3ms min
+ bufferU[j++]=WAIT_T3; //Tprogram 3ms
+ bufferU[j++]=READ_DATA_PROG;
+ }
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=3;
+ bufferU[j++]=LOAD_DATA_PROG; //Config word 0x2007
+ bufferU[j++]=memCODE_W[0x2007]>>8; //MSB
+ bufferU[j++]=memCODE_W[0x2007]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG; //internally timed, T=5ms min
+ bufferU[j++]=WAIT_T3; //Tprogram 3ms
+ bufferU[j++]=READ_DATA_PROG;
+ bufferU[j++]=INC_ADDR;
+ if(sizeW>0x2008){ //only if Config2 is present
+ bufferU[j++]=LOAD_DATA_PROG; //Config word 2 0x2008
+ bufferU[j++]=memCODE_W[0x2008]>>8; //MSB
+ bufferU[j++]=memCODE_W[0x2008]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG; //internally timed, T=5ms min
+ bufferU[j++]=WAIT_T3; //Tprogram 3ms
+ bufferU[j++]=READ_DATA_PROG;
+ bufferU[j++]=FLUSH;
+ }
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(45);
+ for(i=0,z=0;programID&&i<4;i++){
+ for(;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if (memCODE_W[0x2000+i]!=(bufferI[z+1]<<8)+bufferI[z+2]){
+ PrintMessage("\r\n");
+ PrintMessage3(strings[S_IDErr],i,memCODE_W[0x2000+i],(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing ID%d: written %04X, read %04X\r\n"
+ err_c++;
+ }
+ z+=6;
+ }
+ if(ICDenable){
+ for(;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if (ICDgoto!=(bufferI[z+1]<<8)+bufferI[z+2]){
+ PrintMessage4(strings[S_ICDErr],0x2004,i,ICDgoto,(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing ICD (0x%X): written %04X, read %04X\r\n"
+ err_c++;
+ }
+ z+=6;
+ }
+ for(;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if(~memCODE_W[0x2007]&((bufferI[z+1]<<8)+bufferI[z+2])){ //error if written 0 and read 1 (~W&R)
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ConfigWErr3],memCODE_W[0x2007],(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing config area: written %04X, read %04X\r\n"
+ err_c++;
+ }
+ if(sizeW>0x2008){ //only if Config2 is present
+ for(z+=6;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if(~memCODE_W[0x2008]&((bufferI[z+1]<<8)+bufferI[z+2])){ //error if written 0 and read 1 (~W&R)
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ConfigWErr3],memCODE_W[0x2008],(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing config area: written %04X, read %04X\r\n"
+ err_c++;
+ }
+ }
+ err+=err_c;
+ PrintMessage1(strings[S_ComplErr],err_c); //"completed, %d errors\r\n"
+ if(saveLog){
+ fprintf(logfile,strings[S_Log9],err); //"Area config. errors=%d \n"
+ }
+//****************** exit ********************
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2000>>8;
+ bufferU[j++]=2000&0xff;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ unsigned int stop=GetTickCount();
+ sprintf(str,strings[S_EndErr],(stop-start)/1000.0,err,err!=1?strings[S_ErrPlur]:strings[S_ErrSing]); //"\r\nEnd (%.2f s) %d %s\r\n\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+ PrintStatusClear(); //clear status report
+}
+
+void Write16F1xxx(int dim,int dim2,int options)
+// write 14 bit enhanced PIC
+// dim=program size
+// dim2=eeprom size
+// options:
+// bit0=0 -> vpp before vdd
+// bit0=1 -> vdd before vpp
+// bit1=1 -> LVP programming
+// bit2=1 -> Config3@0x8009
+// bit3=1 -> Config4@0x800A
+// bit4=1 -> PIC16F18xxx (calib words @0xE000 + new commands)
+// DevREV@0x8005 DevID@0x8006
+// Config1@0x8007 Config2@0x8008
+// Config3@0x8009 Config4@0x800A
+// Calib1@0x8009/A Calib2@0x800A/B Calib3@0x800B/C
+// eeprom@0x0 or 0xF000
+// erase: BULK_ERASE_PROG (1001) +5ms
+// write:LOAD_DATA_PROG (0010) + BEGIN_PROG (1000) + 2.5ms (8 word algorithm)
+// config write time 5ms
+// eeprom: BULK_ERASE_DATA (1011) + 5ms
+// LOAD_DATA_DATA (0011) + BEGIN_PROG (1000) + 2.5ms
+// verify after write
+// write (16F18xxx): LOAD_DATA_INC (100010) + BEGIN_PROG (1000) + 2.5ms (32 word algorithm)
+{
+ int err=0;
+ WORD devID=0x3fff,devREV=0x3fff,calib1=0x3fff,calib2=0x3fff,calib3=0x3fff;
+ int k=0,k2=0,z=0,i,j,w;
+ int F18x=options&16;
+ if(F18x&&FWVersion<0xA00){ //only for 16F18xxx
+ PrintMessage1(strings[S_FWver2old],"0.10.0"); //"This firmware is too old. Version %s is required\r\n"
+ return;
+ }
+ if(!CheckV33Regulator()){
+ PrintMessage(strings[S_noV33reg]); //Can't find 3.3V expansion board
+ return;
+ }
+ if(sizeW<0x8009){
+ PrintMessage(strings[S_NoConfigW5]); //"Can't find CONFIG (0x8007-0x8008)\r\n"
+ PrintMessage(strings[S_End]);
+ return;
+ }
+ if((options&4)&&sizeW<0x800A){ //Config3 defaults to 0x3FFF
+ sizeW=0x800A;
+ memCODE_W=(WORD*)realloc(memCODE_W,sizeof(WORD)*sizeW);
+ memCODE_W[0x8009]=0x3FFF;
+ }
+ if((options&8)&&sizeW<0x800B){ //Config4 defaults to 0x3FFF
+ sizeW=0x800B;
+ memCODE_W=(WORD*)realloc(memCODE_W,sizeof(WORD)*sizeW);
+ memCODE_W[0x800A]=0x3FFF;
+ }
+ if(saveLog){
+ OpenLogFile(); //"Log.txt"
+ fprintf(logfile,"Write16F1xxx(%d,%d,%d)\n",dim,dim2,options);
+ }
+ if(dim2>sizeEE) dim2=sizeEE;
+ if((options&2)==0){ //HV entry
+ if(!StartHVReg(8.5)){
+ PrintMessage(strings[S_HVregErr]); //"HV regulator error\r\n"
+ return;
+ }
+ }
+ else StartHVReg(-1); //LVP mode, turn off HV
+ for(i=0;i<0x800C&&i<sizeW;i++) memCODE_W[i]&=0x3FFF;
+ unsigned int start=GetTickCount();
+// bufferU[0]=0;
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T1T2;
+ bufferU[j++]=1; //T1=1u
+ bufferU[j++]=100; //T2=100u
+ bufferU[j++]=EN_VPP_VCC; //enter program mode
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ if((options&2)==0){ //HV entry
+ if((options&1)==0){ //VPP before VDD
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=4; //VPP
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x5; //VDD+VPP
+ }
+ else{ //VDD before VPP without delay
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=1; //VDD
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x5; //VDD+VPP
+ }
+ }
+ else{ //Low voltage programming
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=4; //VPP
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=TX16; //0000 1010 0001 0010 1100 0010 1011 0010 = 0A12C2B2
+ bufferU[j++]=2;
+ bufferU[j++]=0x0A;
+ bufferU[j++]=0x12;
+ bufferU[j++]=0xC2;
+ bufferU[j++]=0xB2;
+ bufferU[j++]=SET_CK_D; //Clock pulse
+ bufferU[j++]=0x4;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ }
+ bufferU[j++]=WAIT_T2;
+ bufferU[j++]=WAIT_T2;
+ bufferU[j++]=WAIT_T2;
+ bufferU[j++]=LOAD_CONF; //counter at 0x8000
+ bufferU[j++]=0xFF;
+ bufferU[j++]=0xFF;
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=0x05;
+ bufferU[j++]=READ_DATA_PROG; //DevREV
+ bufferU[j++]=INC_ADDR;
+ bufferU[j++]=READ_DATA_PROG; //DevID
+ bufferU[j++]=INC_ADDR;
+ bufferU[j++]=INC_ADDR;
+ bufferU[j++]=INC_ADDR;
+ if(options&4) bufferU[j++]=INC_ADDR;
+ bufferU[j++]=READ_DATA_PROG; //Calib1
+ bufferU[j++]=INC_ADDR;
+ bufferU[j++]=READ_DATA_PROG; //Calib2
+ bufferU[j++]=INC_ADDR;
+ bufferU[j++]=READ_DATA_PROG; //Calib3
+// bufferU[j++]=CUST_CMD;
+// bufferU[j++]=0x16; //Reset address
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2500>>8;
+ bufferU[j++]=2500&0xff;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ j=0;
+ for(z=0;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ devREV=(bufferI[z+1]<<8)+bufferI[z+2];
+ for(z+=3;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ devID=(bufferI[z+1]<<8)+bufferI[z+2];
+ PrintMessage1(strings[S_DevID],devID); //"DevID: 0x%04X\r\n"
+ if(devREV<0x3FFF) PrintMessage1(strings[S_DevREV],devREV); //"DevREV: 0x%04X\r\n"
+ PIC16_ID(devID);
+ if(memCODE_W[0x8006]<0x3FFF&&devID!=memCODE_W[0x8006]) PrintMessage(strings[S_DevMismatch]); //"Warning: the device is different from what specified in source data"
+ if(!F18x){ //16F1xxx
+ for(z+=3;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ calib1=(bufferI[z+1]<<8)+bufferI[z+2];
+ if(calib1<0x3fff) PrintMessage2(strings[S_CalibWordX],1,calib1); //"Calibration word %d: 0x%04X\r\n"
+ for(z+=3;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ calib2=(bufferI[z+1]<<8)+bufferI[z+2];
+ if(calib2<0x3fff) PrintMessage2(strings[S_CalibWordX],2,calib2); //"Calibration word %d: 0x%04X\r\n"
+ for(z+=3;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ calib3=(bufferI[z+1]<<8)+bufferI[z+2];
+ if(calib3<0x3fff) PrintMessage2(strings[S_CalibWordX],3,calib3); //"Calibration word %d: 0x%04X\r\n"
+ }
+ else{ //16F18xxx
+ WORD calib[4]={0x3FFF,0x3FFF,0x3FFF,0x3FFF};
+ bufferU[j++]=LOAD_PC; //counter at 0xE000
+ bufferU[j++]=0xE0;
+ bufferU[j++]=0x00;
+ for(i=0;i<4;i++) bufferU[j++]=READ_DATA_INC;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ j=0;
+ if(saveLog){
+ fprintf(logfile,"Calibration area @0xE000\n");
+ }
+ for(z=0,i=0;z<DIMBUF-2&&i<4;z++){
+ if(bufferI[z]==READ_DATA_INC){
+ calib[i++]=(bufferI[z+1]<<8)+bufferI[z+2];
+ z+=2;
+ }
+ }
+ if(i!=4){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ConfigErr],4,i); //"Error reading config area, requested %d words, read %d\r\n"
+ }
+ else{
+ for(i=0;i<4;i++) PrintMessage2(strings[S_CalibWordX],i+1,calib[i]); //"Calibration word %d: 0x%04X\r\n"
+ }
+ }
+//****************** erase memory ********************
+ PrintMessage(strings[S_StartErase]); //"Erasing ... "
+ if(saveLog) fprintf(logfile,"%s\n",strings[S_StartErase]);
+ int dly=8;
+ j=0;
+ if(programID){
+ bufferU[j++]=LOAD_CONF; //PC @ 0x8000
+ bufferU[j++]=0xFF;
+ bufferU[j++]=0xFF;
+ }
+ else if(!F18x){
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x16; //Reset address
+ }
+ else{ //18F18xxx
+ bufferU[j++]=LOAD_PC; //counter at 0
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ }
+ bufferU[j++]=BULK_ERASE_PROG;
+ bufferU[j++]=WAIT_T3; // wait 5ms
+ bufferU[j++]=WAIT_T3;
+ if(F18x){ //18F18xxx: EEPROM@0xF000
+ bufferU[j++]=LOAD_PC; //counter at 0xF000
+ bufferU[j++]=0xF0;
+ bufferU[j++]=0x00;
+ bufferU[j++]=BULK_ERASE_PROG;
+ bufferU[j++]=WAIT_T3; // wait 5ms
+ bufferU[j++]=WAIT_T3;
+ dly+=6;
+ }
+ if(!F18x){
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x16; //Reset address
+ }
+ else{ //18F18xxx
+ bufferU[j++]=LOAD_PC; //counter at 0
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(dly);
+ PrintMessage(strings[S_Compl]); //"completed\r\n"
+//****************** write code ********************
+ PrintMessage(strings[S_StartCodeProg]); //"Write code ... "
+ PrintStatusSetup();
+ if(saveLog) fprintf(logfile,"%s\n",strings[S_StartCodeProg]);
+ fflush(logfile);
+ int valid,inc;
+ for(;dim>0&&memCODE_W[dim]>=0x3fff;dim--); //skip empty space at end
+ if(!F18x){ //16F1xxx
+ if(dim%8) dim+=8-dim%8; //grow to 8 word multiple
+ for(i=k=0,j=0;i<dim;i+=8){
+ valid=inc=0;
+ for(;i<dim&&!valid;){ //skip empty locations (8 words)
+ valid=0;
+ for(k=0;k<8;k++) if(memCODE_W[i+k]<0x3fff) valid=1;
+ if(!valid){
+ inc+=8;
+ i+=8;
+ }
+ if(inc&&(valid||inc==248)){ //increase address to skip empty words
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=k=inc;
+ inc=0;
+ }
+ if(j>DIMBUF-4||(valid&&j>1)){
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(3+k/2);
+ j=0;
+ }
+ }
+ if(valid){
+ k=0;
+ bufferU[j++]=LOAD_DATA_PROG;
+ bufferU[j++]=memCODE_W[i+k]>>8; //MSB
+ bufferU[j++]=memCODE_W[i+k]&0xff; //LSB
+ for(k=1;k<8;k++){
+ bufferU[j++]=INC_ADDR;
+ bufferU[j++]=LOAD_DATA_PROG;
+ bufferU[j++]=memCODE_W[i+k]>>8; //MSB
+ bufferU[j++]=memCODE_W[i+k]&0xff; //LSB
+ }
+ bufferU[j++]=BEGIN_PROG; //internally timed, T=2.5ms
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=INC_ADDR;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(3);
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,0,0); //"i=%d, k=%d 0=%d\n"
+ }
+ PrintStatus(strings[S_CodeWriting],i*100/dim,i); //"Writing: %d%%, addr. %03X"
+ }
+ }
+ }
+ else{ //16F18xxx 32 word algorithm
+ if(dim%32) dim+=32-dim%32; //grow to 32 word multiple
+ for(i=k=0,j=0;i<dim;i+=32){
+ for(valid=0;i<dim&&!valid;i+=valid?0:32){ //skip empty locations (32 words)
+ valid=0;
+ for(k=0;k<32;k++) if(memCODE_W[i+k]<0x3fff) valid=1;
+ }
+ bufferU[j++]=LOAD_PC; //update counter
+ bufferU[j++]=i>>8;
+ bufferU[j++]=i&0xFF;
+ for(k=0;k<32&&i<dim;k++){
+ bufferU[j++]=k<31?LOAD_DATA_INC:LOAD_DATA_PROG;
+ bufferU[j++]=memCODE_W[i+k]>>8; //MSB
+ bufferU[j++]=memCODE_W[i+k]&0xff; //LSB
+ if(j>DIMBUF-4){
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(3);
+ j=0;
+ }
+ }
+ if(i<dim){
+ bufferU[j++]=BEGIN_PROG; //internally timed, T=2.5ms
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(3);
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,0,0); //"i=%d, k=%d 0=%d\n"
+ }
+ PrintStatus(strings[S_CodeWriting],i*100/dim,i); //"Writing: %d%%, addr. %03X"
+ }
+ }
+ }
+ PrintStatusEnd();
+ PrintMessage(strings[S_Compl]); //"completed\r\n"
+//****************** verify code ********************
+ PrintMessage(strings[S_CodeV]); //"Verifying code ... "
+ PrintStatusSetup();
+ if(saveLog) fprintf(logfile,"%s\n",strings[S_CodeV]);
+ j=0;
+ if(!F18x){
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x16; //Reset address
+ }
+ else{ //18F18xxx
+ bufferU[j++]=LOAD_PC; //counter at 0
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ for(i=k=0;i<dim;i++){
+ if(j==0){ //skip empty locations (only after a write)
+ for(valid=0;i<dim&&!valid;){
+ for(k2=0;k2<255&&!valid;k2++) if(memCODE_W[i+k2]<0x3fff) valid=1;
+ if(k2>16){ //increase address to skip empty words, if enough are found
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=k2;
+ i+=k2;
+ k+=k2;
+ }
+ if(j>DIMBUF-4||(valid&&j>1)){ //if buffer is full or last skip
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(3+j/2*0.1);
+ j=0;
+ }
+ }
+ }
+ if(memCODE_W[i]<0x3FFF) bufferU[j++]=READ_DATA_PROG;
+ bufferU[j++]=INC_ADDR;
+ if(j>DIMBUF*2/4-3||i==dim-1){ //2B cmd -> 4B data
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ for(z=0;z<DIMBUF-2;z++){
+ if(bufferI[z]==INC_ADDR) k++;
+ else if(bufferI[z]==READ_DATA_PROG){
+ if(memCODE_W[k]<0x3FFF&&(memCODE_W[k]!=(bufferI[z+1]<<8)+bufferI[z+2])){
+ PrintMessage3(strings[S_CodeWError2],k,memCODE_W[k],(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing address %3X: written %04X, read %04X\r\n"
+ err++;
+ }
+ z+=2;
+ }
+ }
+ PrintStatus(strings[S_CodeV2],i*100/(dim+dim2),i); //"Verify: %d%%, addr. %04X"
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,err); //"i=%d, k=%d, errors=%d\n"
+ }
+ if(err>=max_err) i=dim;
+ }
+ }
+ PrintStatusEnd();
+ if(k<dim){
+ PrintMessage2(strings[S_CodeVError3],dim,k); //"Error verifying code area, requested %d words, read %d\r\n"
+ }
+ PrintMessage1(strings[S_ComplErr],err); //"completed, %d errors\r\n"
+ if(err>=max_err){
+ PrintMessage1(strings[S_MaxErr],err); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ }
+//****************** write eeprom ********************
+ if(dim2&&err<max_err&&!F18x){
+ int errEE=0;
+ PrintMessage(strings[S_EEAreaW]); //"Writing EEPROM ... "
+ PrintStatusSetup();
+ if(saveLog) fprintf(logfile,"%s\n",strings[S_EEAreaW]);
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=5000>>8;
+ bufferU[j++]=5000&0xff;
+ bufferU[j++]=BULK_ERASE_DATA;
+ bufferU[j++]=WAIT_T3; // wait 5ms
+ bufferU[j++]=CUST_CMD;
+ bufferU[j++]=0x16; //Reset address
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(7);
+ j=0;
+ for(w=i=k=0;i<dim2;i++){
+ if(memEE[i]<0xff){
+ bufferU[j++]=LOAD_DATA_DATA;
+ bufferU[j++]=memEE[i];
+ bufferU[j++]=BEGIN_PROG; //internally timed, T=5ms max
+ bufferU[j++]=WAIT_T3; //Tprogram
+ bufferU[j++]=READ_DATA_DATA;
+ w++;
+ }
+ bufferU[j++]=INC_ADDR;
+ if(j>DIMBUF-12||i==dim2-1){
+ PrintStatus(strings[S_CodeWriting],(i+dim)*100/(dim+dim2),i); //"Writing: %d%%, add. %03X"
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(w*5+2);
+ w=0;
+ for(z=0;z<DIMBUF-4;z++){
+ if(bufferI[z]==INC_ADDR&&memEE[k]>=0xff) k++;
+ else if(bufferI[z]==LOAD_DATA_DATA&&bufferI[z+3]==READ_DATA_DATA){
+ if (memEE[k]!=bufferI[z+4]){
+ PrintMessage("\r\n");
+ PrintMessage3(strings[S_CodeWError3],k,memEE[k],bufferI[z+4]); //"Error writing address %4X: written %02X, read %02X\r\n"
+ errEE++;
+ if(max_err&&err+errEE>max_err){
+ PrintMessage1(strings[S_MaxErr],err+errEE); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ PrintMessage(strings[S_IntW]); //"write interrupted"
+ i=dim2;
+ z=DIMBUF;
+ }
+ }
+ k++;
+ z+=5;
+ }
+ }
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,errEE); //"i=%d, k=%d, errors=%d\n"
+ }
+ }
+ }
+ errEE+=i-k;
+ PrintStatusEnd();
+ PrintMessage1(strings[S_ComplErr],errEE); //"completed, %d errors\r\n"
+ err+=errEE;
+ }
+ else if(dim2&&err<max_err&&F18x){ //16F18xxx
+ int errEE=0;
+ PrintMessage(strings[S_EEAreaW]); //"Writing EEPROM ... "
+ PrintStatusSetup();
+ if(saveLog) fprintf(logfile,"%s\n",strings[S_EEAreaW]);
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=5000>>8;
+ bufferU[j++]=5000&0xff;
+ bufferU[j++]=LOAD_PC; //update counter
+ bufferU[j++]=0xF0;
+ bufferU[j++]=0x00;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(7);
+ j=0;
+ for(w=i=k=0;i<dim2;i++){
+ if(memEE[i]<0xff){
+ bufferU[j++]=LOAD_DATA_PROG;
+ bufferU[j++]=0;
+ bufferU[j++]=memEE[i];
+ bufferU[j++]=BEGIN_PROG; //internally timed, T=2.5ms max
+ bufferU[j++]=WAIT_T3; //Tprogram
+ bufferU[j++]=READ_DATA_PROG;
+ w++;
+ }
+ bufferU[j++]=INC_ADDR;
+ if(j>DIMBUF-12||i==dim2-1){
+ PrintStatus(strings[S_CodeWriting],(i+dim)*100/(dim+dim2),i); //"Writing: %d%%, add. %03X"
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(w*5+2);
+ w=0;
+ for(z=0;z<DIMBUF-4;z++){
+ if(bufferI[z]==INC_ADDR&&memEE[k]>=0xff) k++;
+ else if(bufferI[z]==LOAD_DATA_PROG&&bufferI[z+3]==READ_DATA_PROG){
+ if (memEE[k]!=bufferI[z+5]){
+ PrintMessage("\r\n");
+ PrintMessage3(strings[S_CodeWError3],k,memEE[k],bufferI[z+5]); //"Error writing address %4X: written %02X, read %02X\r\n"
+ errEE++;
+ if(max_err&&err+errEE>max_err){
+ PrintMessage1(strings[S_MaxErr],err+errEE); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ PrintMessage(strings[S_IntW]); //"write interrupted"
+ i=dim2;
+ z=DIMBUF;
+ }
+ }
+ k++;
+ z+=6;
+ }
+ }
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,errEE); //"i=%d, k=%d, errors=%d\n"
+ }
+ }
+ }
+ errEE+=i-k;
+ PrintStatusEnd();
+ PrintMessage1(strings[S_ComplErr],errEE); //"completed, %d errors\r\n"
+ err+=errEE;
+
+ }
+ if(err>=max_err){
+ PrintMessage1(strings[S_MaxErr],err); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ }
+//****************** write ID, CONFIG, CALIB ********************
+ if(max_err&&err<max_err){
+ PrintMessage(strings[S_ConfigAreaW]); //"Writing CONFIG area ... "
+ if(saveLog) fprintf(logfile,"%s\n",strings[S_ConfigAreaW]);
+ int err_c=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=5000>>8;
+ bufferU[j++]=5000&0xff;
+ bufferU[j++]=LOAD_CONF; //PC @ 0x8000
+ bufferU[j++]=0xFF;
+ bufferU[j++]=0xFF;
+ if(programID){
+ for(i=0x8000;i<0x8004;i++){
+ bufferU[j++]=LOAD_DATA_PROG;
+ bufferU[j++]=memCODE_W[i]>>8; //MSB
+ bufferU[j++]=memCODE_W[i]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG; //internally timed
+ bufferU[j++]=WAIT_T3; //Tprogram 5ms
+ bufferU[j++]=READ_DATA_PROG;
+ bufferU[j++]=INC_ADDR;
+ }
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=3;
+ }
+ else{
+ bufferU[j++]=INC_ADDR_N;
+ bufferU[j++]=7;
+ }
+ bufferU[j++]=LOAD_DATA_PROG; //Config word 0x8007
+ bufferU[j++]=memCODE_W[0x8007]>>8; //MSB
+ bufferU[j++]=memCODE_W[0x8007]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG; //internally timed
+ bufferU[j++]=WAIT_T3; //Tprogram 5ms
+ bufferU[j++]=READ_DATA_PROG;
+ bufferU[j++]=INC_ADDR;
+ bufferU[j++]=LOAD_DATA_PROG; //Config word 2
+ bufferU[j++]=memCODE_W[0x8008]>>8; //MSB
+ bufferU[j++]=memCODE_W[0x8008]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG; //internally timed
+ bufferU[j++]=WAIT_T3; //Tprogram 5ms
+ bufferU[j++]=READ_DATA_PROG;
+ bufferU[j++]=INC_ADDR;
+ if(options&0xC){
+ bufferU[j++]=LOAD_DATA_PROG; //Config word 3
+ bufferU[j++]=memCODE_W[0x8009]>>8; //MSB
+ bufferU[j++]=memCODE_W[0x8009]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG; //internally timed
+ bufferU[j++]=WAIT_T3; //Tprogram 5ms
+ bufferU[j++]=READ_DATA_PROG;
+ bufferU[j++]=INC_ADDR;
+ }
+ if(options&8){
+ bufferU[j++]=LOAD_DATA_PROG; //Config word 4
+ bufferU[j++]=memCODE_W[0x800A]>>8; //MSB
+ bufferU[j++]=memCODE_W[0x800A]&0xff; //LSB
+ bufferU[j++]=BEGIN_PROG; //internally timed
+ bufferU[j++]=WAIT_T3; //Tprogram 5ms
+ bufferU[j++]=READ_DATA_PROG;
+ bufferU[j++]=INC_ADDR;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ j=(programID?22:0)+(options&0xC?10:0);
+ PacketIO(18+j);
+ for(i=0,z=0;programID&&i<4;i++){
+ for(;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if (memCODE_W[0x8000+i]!=(bufferI[z+1]<<8)+bufferI[z+2]){
+ PrintMessage("\r\n");
+ PrintMessage3(strings[S_IDErr],i,memCODE_W[0x8000+i],(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing ID%d: written %04X, read %04X\r\n"
+ err_c++;
+ }
+ z+=6;
+ }
+ for(;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if(~memCODE_W[0x8007]&((bufferI[z+1]<<8)+bufferI[z+2])){ //error if written 0 and read 1 (~W&R)
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ConfigWErr3],memCODE_W[0x8007],(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing config area: written %04X, read %04X\r\n"
+ err_c++;
+ }
+ for(z+=6;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if(~memCODE_W[0x8008]&((bufferI[z+1]<<8)+bufferI[z+2])){ //error if written 0 and read 1 (~W&R)
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ConfigWErr3],memCODE_W[0x8008],(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing config area: written %04X, read %04X\r\n"
+ err_c++;
+ }
+ if(options&0xC){
+ for(z+=6;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if(~memCODE_W[0x8009]&((bufferI[z+1]<<8)+bufferI[z+2])){ //error if written 0 and read 1 (~W&R)
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ConfigWErr3],memCODE_W[0x8009],(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing config area: written %04X, read %04X\r\n"
+ err_c++;
+ }
+ }
+ if(options&8){
+ for(z+=6;z<DIMBUF-2&&bufferI[z]!=READ_DATA_PROG;z++);
+ if(~memCODE_W[0x800A]&((bufferI[z+1]<<8)+bufferI[z+2])){ //error if written 0 and read 1 (~W&R)
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ConfigWErr3],memCODE_W[0x800A],(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing config area: written %04X, read %04X\r\n"
+ err_c++;
+ }
+ }
+ err+=err_c;
+ PrintMessage1(strings[S_ComplErr],err_c); //"completed, %d errors\r\n"
+ if(saveLog){
+ fprintf(logfile,strings[S_Log9],err); //"Config area errors=%d \n"
+ }
+ }
+//****************** exit ********************
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2000>>8;
+ bufferU[j++]=2000&0xff;
+ bufferU[j++]=NOP; //exit program mode
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ unsigned int stop=GetTickCount();
+ sprintf(str,strings[S_EndErr],(stop-start)/1000.0,err,err!=1?strings[S_ErrPlur]:strings[S_ErrSing]); //"\r\nEnd (%.2f s) %d %s\r\n\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+ PrintStatusClear(); //clear status report
+}
+
+
+
+void Write16F18xxx(int dim,int dim2,int options)
+// write 14 bit enhanced PIC
+// dim=program size (words)
+// dim2=eeprom size (bytes)
+// options:
+// bit0=0 -> vpp before vdd
+// bit0=1 -> vdd before vpp
+// bit1=1 -> LVP programming
+// bit4=1 -> do not use DIA&DCI
+// DevREV@0x8005 DevID@0x8006
+// Config@0x8007-800B
+// Device info area @0x8100
+// Device configuration info area @0x8200
+// erase: BULK_ERASE_PROGRAM_MEM (0x18) +14ms
+// EEPROM erase: idem
+// write flash: LOAD_NVM (0x0/2) + BEGIN_INT_PROG (0xE0) + 2.8ms (32 word algorithm)
+// EEPROM write: one word, 6ms
+// config write: one word, 10ms
+// verify after write
+{
+ int err=0;
+ WORD devID=0x3fff,devREV=0x3fff;
+ int k=0,k2=0,z=0,i,j,w;
+ int useDCI=(options&0x10)==0?1:0;
+ int rowN=32; //32 word algorithm
+ if(FWVersion<0xB00){
+ PrintMessage1(strings[S_FWver2old],"0.11.0"); //"This firmware is too old. Version %s is required\r\n"
+ return;
+ }
+ if(!CheckV33Regulator()){
+ PrintMessage(strings[S_noV33reg]); //Can't find 3.3V expansion board
+ return;
+ }
+ if(sizeW<0x800C){
+ PrintMessage(strings[S_NoConfigW6]); //"Can't find CONFIG (0x8007-0x800B)\r\n"
+ PrintMessage1(strings[S_End],0);
+ return;
+ }
+ if(saveLog){
+ OpenLogFile(); //"Log.txt"
+ fprintf(logfile,"Write16F18xxx(%d,%d,%d)\n",dim,dim2,options);
+ }
+ if(dim2>0) dim2=sizeEE;
+ if(dim2>0x1000) dim2=0x100;
+ if((options&2)==0){ //HV entry
+ if(!StartHVReg(8.5)){
+ PrintMessage(strings[S_HVregErr]); //"HV regulator error\r\n"
+ return;
+ }
+ }
+ else StartHVReg(-1); //LVP mode, turn off HV
+ for(i=0;i<0x800C&&i<sizeW;i++) memCODE_W[i]&=0x3FFF;
+ unsigned int start=GetTickCount();
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T1T2;
+ bufferU[j++]=1; //T1=1u
+ bufferU[j++]=100; //T2=100u
+ bufferU[j++]=EN_VPP_VCC; //enter program mode
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ if((options&2)==0){ //HV entry
+ if((options&1)==0){ //VPP before VDD
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=4; //VPP
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x5; //VDD+VPP
+ }
+ else{ //VDD before VPP without delay
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=1; //VDD
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x5; //VDD+VPP
+ }
+ }
+ else{ //Low voltage programming
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=4; //VPP
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=TX16; //0000 1010 0001 0010 1100 0010 1011 0010 = 0A12C2B2
+ bufferU[j++]=2;
+ bufferU[j++]=0x0A;
+ bufferU[j++]=0x12;
+ bufferU[j++]=0xC2;
+ bufferU[j++]=0xB2;
+ bufferU[j++]=SET_CK_D; //Clock pulse
+ bufferU[j++]=0x4;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ }
+ bufferU[j++]=WAIT_T2;
+ bufferU[j++]=WAIT_T2;
+ bufferU[j++]=WAIT_T2;
+ bufferU[j++]=ICSP8_LOAD;
+ bufferU[j++]=LOAD_PC_ADDR;
+ bufferU[j++]=0x80;
+ bufferU[j++]=0x05;
+ bufferU[j++]=ICSP8_READ;
+ bufferU[j++]=READ_NVM_INC; //DevREV
+ bufferU[j++]=ICSP8_READ;
+ bufferU[j++]=READ_NVM_INC; //DevID
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2800>>8;
+ bufferU[j++]=2800&0xff;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ j=0;
+ for(z=0;z<DIMBUF-2&&bufferI[z]!=ICSP8_READ;z++);
+ devREV=(bufferI[z+1]<<8)+bufferI[z+2];
+ for(z+=3;z<DIMBUF-2&&bufferI[z]!=ICSP8_READ;z++);
+ devID=(bufferI[z+1]<<8)+bufferI[z+2];
+ PrintMessage1(strings[S_DevID],devID); //"DevID: 0x%04X\r\n"
+ if(devREV<0x3FFF) PrintMessage1(strings[S_DevREV],devREV); //"DevREV: 0x%04X\r\n"
+ PIC16_ID(devID);
+ if(memCODE_W[0x8006]<0x3FFF&&devID!=memCODE_W[0x8006]) PrintMessage(strings[S_DevMismatch]); //"Warning: the device is different from what specified in source data"
+//****************** DIA-DCI ********************
+ if(useDCI){ //if not disabled
+ if(saveLog) fprintf(logfile,"Device Information Area @0x8100\n");
+ WORD DIA[0x20];
+ bufferU[j++]=ICSP8_LOAD; //counter at 0x8100
+ bufferU[j++]=LOAD_PC_ADDR;
+ bufferU[j++]=0x81;
+ bufferU[j++]=0x00;
+ k=0;
+ for(i=0;i<0x20;i++){ //DIA
+ bufferU[j++]=ICSP8_READ;
+ bufferU[j++]=READ_NVM_INC;
+ if((j+1)/2*3+3>DIMBUF||i==0x1F){ //2B cmd -> 3B data
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ for(z=0;z<DIMBUF-2;z++){
+ if(bufferI[z]==ICSP8_READ){
+ DIA[k++]=(bufferI[z+1]<<8)+bufferI[z+2];
+ z+=2;
+ }
+ }
+ j=0;
+ }
+ }
+ PrintMessage("Device Information Area @0x8100\r\n");
+ char s[256],t[256];
+ s[0]=0;
+ for(i=0;i<0x20;i+=COL){
+ sprintf(t,"%04X: ",0x8100+i);
+ strcat(s,t);
+ for(j=i;j<i+COL&&j<0x20;j++){
+ sprintf(t,"%04X ",DIA[j]);
+ strcat(s,t);
+ }
+ strcat(s,"\r\n");
+ }
+ PrintMessage(s);
+ if(saveLog) fprintf(logfile,"Device Configuration Information @0x8200\n");
+ WORD DCI[0x20];
+ j=0;
+ k=0;
+ bufferU[j++]=ICSP8_LOAD;
+ bufferU[j++]=LOAD_PC_ADDR;
+ bufferU[j++]=0x82;
+ bufferU[j++]=0x00;
+ for(i=0;i<0x20;i++){ //DCI
+ bufferU[j++]=ICSP8_READ;
+ bufferU[j++]=READ_NVM_INC;
+ if((j+1)/2*3+3>DIMBUF||i==0x1F){ //2B cmd -> 3B data
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ for(z=0;z<DIMBUF-2;z++){
+ if(bufferI[z]==ICSP8_READ){
+ DCI[k++]=(bufferI[z+1]<<8)+bufferI[z+2];
+ z+=2;
+ }
+ }
+ j=0;
+ }
+ }
+ PrintMessage("Device Configuration Information @0x8200\r\n");
+ s[0]=0;
+ for(i=0;i<0x20;i+=COL){
+ sprintf(t,"%04X: ",0x8200+i);
+ strcat(s,t);
+ for(j=i;j<i+COL&&j<0x20;j++){
+ sprintf(t,"%04X ",DCI[j]);
+ strcat(s,t);
+ }
+ strcat(s,"\r\n");
+ }
+ PrintMessage(s);
+ PrintMessage1("Erase row size: %d words\r\n",DCI[0]);
+ PrintMessage1("Write latches: %d\r\n",DCI[1]);
+ PrintMessage1("User rows: %d\r\n",DCI[2]);
+ PrintMessage1("->%d Flash words\r\n",DCI[0]*DCI[2]);
+ PrintMessage1("EE data memory size: %d\r\n",DCI[3]);
+ PrintMessage1("Pin count: %d\r\n",DCI[4]);
+ if(DCI[0]*DCI[2]!=dim) PrintMessage(strings[S_WarnFlashSize]); //"Warning, flash size is different from the expected value"
+ if(dim2>DCI[3]) dim2=DCI[3]; //limit EE to the real one
+ }
+//****************** erase memory ********************
+ PrintMessage(strings[S_StartErase]); //"Erasing ... "
+ if(saveLog) fprintf(logfile,"%s\n",strings[S_StartErase]);
+ j=0;
+ bufferU[j++]=ICSP8_LOAD;
+ bufferU[j++]=LOAD_PC_ADDR;
+ if(programID){ //0x8000 to erase UserID
+ bufferU[j++]=0x80;
+ bufferU[j++]=0x00;
+ }
+ else{
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ }
+ bufferU[j++]=ICSP8_SHORT;
+ bufferU[j++]=BULK_ERASE_PROGRAM_MEM;
+ bufferU[j++]=WAIT_T3; // wait ~14ms
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=WAIT_T3;
+ //separate EEPROM erase (undocumented on 16F184xx devices)
+ bufferU[j++]=ICSP8_LOAD;
+ bufferU[j++]=LOAD_PC_ADDR;
+ bufferU[j++]=0xF0;
+ bufferU[j++]=0x00;
+ bufferU[j++]=ICSP8_SHORT;
+ bufferU[j++]=BULK_ERASE_PROGRAM_MEM;
+ bufferU[j++]=WAIT_T3; // wait ~14ms
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(30);
+ PrintMessage(strings[S_Compl]); //"completed\r\n"
+//****************** write code ********************
+ PrintMessage(strings[S_StartCodeProg]); //"Write code ... "
+ PrintStatusSetup();
+ if(saveLog) fprintf(logfile,"%s\n",strings[S_StartCodeProg]);
+ fflush(logfile);
+ int valid,inc;
+ for(;dim>0&&memCODE_W[dim-1]>=0x3fff;dim--); //skip empty space at end
+ if(dim%rowN) dim+=rowN-dim%rowN; //grow to 32 word multiple
+ for(i=k=0,j=0;i<dim;i+=rowN){
+ for(valid=0;i<dim&&!valid;i+=valid?0:rowN){ //skip empty locations (32 words)
+ valid=0;
+ for(k=0;k<rowN;k++) if(memCODE_W[i+k]<0x3fff) valid=1;
+ }
+ bufferU[j++]=ICSP8_LOAD;
+ bufferU[j++]=LOAD_PC_ADDR; //update counter
+ bufferU[j++]=i>>8;
+ bufferU[j++]=i&0xFF;
+ for(k=0;k<rowN&&i<dim;k++){ //load all latches
+ bufferU[j++]=ICSP8_LOAD;
+ bufferU[j++]=k<(rowN-1)?LOAD_NVM_INC:LOAD_NVM;
+ bufferU[j++]=memCODE_W[i+k]>>8; //MSB
+ bufferU[j++]=memCODE_W[i+k]&0xff; //LSB
+ if(j>DIMBUF-5){
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(3);
+ j=0;
+ }
+ }
+ if(i<dim){
+ bufferU[j++]=ICSP8_SHORT;
+ bufferU[j++]=BEGIN_INT_PROG; //internally timed, T=2.8ms
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(3);
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,0,0); //"i=%d, k=%d 0=%d\n"
+ }
+ PrintStatus(strings[S_CodeWriting],i*100/dim,i); //"Writing: %d%%, addr. %03X"
+ }
+ }
+ PrintStatusEnd();
+ PrintMessage(strings[S_Compl]); //"completed\r\n"
+//****************** verify code ********************
+ PrintMessage(strings[S_CodeV]); //"Verifying code ... "
+ PrintStatusSetup();
+ if(saveLog) fprintf(logfile,"%s\n",strings[S_CodeV]);
+ j=0;
+ bufferU[j++]=ICSP8_LOAD;
+ bufferU[j++]=LOAD_PC_ADDR; //update counter
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ for(i=k=0;i<dim;i++){
+ if(j==0){ //skip empty locations (only at the beginning of a packet)
+ for(k2=i;k2<dim&&memCODE_W[k2]>=0x3fff;k2++);
+ if(k2>i+10){ //at least 10 skipped
+ i=k2;
+ k=i;
+ bufferU[j++]=ICSP8_LOAD;
+ bufferU[j++]=LOAD_PC_ADDR; //update counter
+ bufferU[j++]=(i>>8)&0xFF;
+ bufferU[j++]=i&0xFF;
+ }
+ }
+ bufferU[j++]=ICSP8_READ;
+ bufferU[j++]=READ_NVM_INC;
+ if((j+1)/2*3+3>DIMBUF||i==dim-1){ //2B cmd -> 3B data
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ for(z=0;z<DIMBUF-2;z++){
+ if(bufferI[z]==ICSP8_READ){
+ if(memCODE_W[k]!=(bufferI[z+1]<<8)+bufferI[z+2]){
+ PrintMessage3(strings[S_CodeWError2],k,memCODE_W[k],(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing address %3X: written %04X, read %04X\r\n"
+ err++;
+ }
+ z+=2;
+ k++;
+ }
+ }
+ PrintStatus(strings[S_CodeV2],i*100/(dim+dim2),i); //"Verify: %d%%, addr. %04X"
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,err); //"i=%d, k=%d, errors=%d\n"
+ }
+ if(err>=max_err) i=dim;
+ }
+ }
+ PrintStatusEnd();
+ PrintMessage1(strings[S_ComplErr],err); //"completed, %d errors\r\n"
+ if(err>=max_err){
+ PrintMessage1(strings[S_MaxErr],err); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ }
+//****************** write eeprom ********************
+ else if(dim2&&err<max_err){
+ int errEE=0;
+ PrintMessage(strings[S_EEAreaW]); //"Writing EEPROM ... "
+ PrintStatusSetup();
+ if(saveLog) fprintf(logfile,"%s\n",strings[S_EEAreaW]);
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=5600>>8; //5.6ms in datasheet?
+ bufferU[j++]=5600&0xff;
+ bufferU[j++]=ICSP8_LOAD;
+ bufferU[j++]=LOAD_PC_ADDR; //load address
+ bufferU[j++]=0xF0;
+ bufferU[j++]=0x00;
+ for(w=i=k=0;i<dim2;i++){
+ if(memEE[i]<0xff){
+ bufferU[j++]=ICSP8_LOAD;
+ bufferU[j++]=LOAD_NVM;
+ bufferU[j++]=0; //MSB
+ bufferU[j++]=memEE[i]&0xff; //LSB
+ bufferU[j++]=ICSP8_SHORT;
+ bufferU[j++]=BEGIN_INT_PROG; //internally timed
+ bufferU[j++]=WAIT_T3; //Tprogram XXms
+ bufferU[j++]=ICSP8_READ;
+ bufferU[j++]=READ_NVM_INC;
+ w++;
+ }
+ else{
+ bufferU[j++]=ICSP8_SHORT;
+ bufferU[j++]=INC_ADDR8;
+ }
+ if(j>DIMBUF-10||i==dim2-1){
+ PrintStatus(strings[S_CodeWriting],(i+dim)*100/(dim+dim2),i); //"Writing: %d%%, add. %03X"
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(w*6+2);
+ j=0;
+ w=0;
+ for(z=0;z<DIMBUF-5;z++){
+ if(bufferI[z]==ICSP8_SHORT&&memEE[k]>=0xff) k++;
+ else if(bufferI[z]==ICSP8_LOAD&&bufferI[z+3]==ICSP8_READ){
+ if(memEE[k]!=bufferI[z+5]){
+ PrintMessage("\r\n");
+ PrintMessage3(strings[S_CodeWError3],k,memEE[k],bufferI[z+5]); //"Error writing address %4X: written %02X, read %02X\r\n"
+ errEE++;
+ if(max_err&&err+errEE>max_err){
+ PrintMessage1(strings[S_MaxErr],err+errEE); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ PrintMessage(strings[S_IntW]); //"write interrupted"
+ i=dim2;
+ z=DIMBUF;
+ }
+ }
+ k++;
+ z+=5;
+ }
+ }
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,errEE); //"i=%d, k=%d, errors=%d\n"
+ }
+ }
+ }
+ errEE+=i-k;
+ PrintStatusEnd();
+ PrintMessage1(strings[S_ComplErr],errEE); //"completed, %d errors\r\n"
+ if(max_err&&err+errEE>max_err){
+ PrintMessage1(strings[S_MaxErr],err+errEE); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ }
+ err+=errEE;
+ }
+//****************** write ID, CONFIG, CALIB ********************
+ if(max_err&&err<max_err){
+ char t[256];
+ PrintMessage(strings[S_ConfigAreaW]); //"Writing CONFIG area ... "
+ PrintMessage("\r\n");
+ if(saveLog) fprintf(logfile,"%s\n",strings[S_ConfigAreaW]);
+ int err_c=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=10000>>8; //5.6ms in datasheet, but requires more in practice
+ bufferU[j++]=10000&0xff;
+ if(programID){
+ bufferU[j++]=ICSP8_LOAD;
+ bufferU[j++]=LOAD_PC_ADDR; //load address
+ bufferU[j++]=0x80;
+ bufferU[j++]=0x00;
+ for(i=0x8000;i<0x8004;i++){
+ bufferU[j++]=ICSP8_LOAD;
+ bufferU[j++]=LOAD_NVM;
+ bufferU[j++]=memCODE_W[i]>>8; //MSB
+ bufferU[j++]=memCODE_W[i]&0xff; //LSB
+ bufferU[j++]=ICSP8_SHORT;
+ bufferU[j++]=BEGIN_INT_PROG; //internally timed
+ bufferU[j++]=WAIT_T3; //Tprogram 10ms
+ bufferU[j++]=ICSP8_READ;
+ bufferU[j++]=READ_NVM_INC;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(45);
+ for(i=0,z=0;i<4;i++){
+ for(;z<DIMBUF-2&&bufferI[z]!=ICSP8_READ;z++);
+ if (memCODE_W[0x8000+i]!=(bufferI[z+1]<<8)+bufferI[z+2]){
+ PrintMessage3(strings[S_IDErr],i,memCODE_W[0x8000+i],(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing ID%d: written %04X, read %04X\r\n"
+ err_c++;
+ }
+ z+=6;
+ }
+ j=0;
+ }
+ bufferU[j++]=ICSP8_LOAD;
+ bufferU[j++]=LOAD_PC_ADDR; //load address
+ bufferU[j++]=0x80;
+ bufferU[j++]=0x07;
+ for(i=0x8007;i<0x800C;i++){ //5 config words
+ bufferU[j++]=ICSP8_LOAD;
+ bufferU[j++]=LOAD_NVM;
+ bufferU[j++]=memCODE_W[i]>>8; //MSB
+ bufferU[j++]=memCODE_W[i]&0xff; //LSB
+ bufferU[j++]=ICSP8_SHORT;
+ bufferU[j++]=BEGIN_INT_PROG; //internally timed
+ bufferU[j++]=WAIT_T3; //Tprogram 10ms
+ bufferU[j++]=ICSP8_READ;
+ bufferU[j++]=READ_NVM_INC;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(55);
+ for(i=0,z=0;i<5;i++){
+ for(;z<DIMBUF-2&&bufferI[z]!=ICSP8_READ;z++);
+ if (~memCODE_W[0x8007+i]&((bufferI[z+1]<<8)+bufferI[z+2])){ //error if written 0 and read 1 (~W&R)
+
+ sprintf(t,"config%d",i+1);
+ PrintMessage3(strings[S_WErr2],t,memCODE_W[0x8007+i],(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing %s: written %04X, read %04X"
+ err_c++;
+ }
+ z+=6;
+ }
+ err+=err_c;
+ PrintMessage1(strings[S_ComplErr],err_c); //"completed, %d errors\r\n"
+ if(saveLog){
+ fprintf(logfile,strings[S_Log9],err_c); //"Config area errors=%d \n"
+ }
+ }
+//****************** exit ********************
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2000>>8;
+ bufferU[j++]=2000&0xff;
+ bufferU[j++]=NOP; //exit program mode
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC;
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ unsigned int stop=GetTickCount();
+ sprintf(str,strings[S_EndErr],(stop-start)/1000.0,err,err!=1?strings[S_ErrPlur]:strings[S_ErrSing]); //"\r\nEnd (%.2f s) %d %s\r\n\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+ PrintStatusClear(); //clear status report
+}
+
diff --git a/progP16.h b/progP16.h
new file mode 100644
index 0000000..53a4b49
--- /dev/null
+++ b/progP16.h
@@ -0,0 +1,20 @@
+void Read16Fxxx(int dim,int dim2,int dim3,int vdd);
+void Write12F6xx(int dim,int dim2);
+void Write12F61x(int dim,int d,int d2);
+void Write12F62x(int dim,int dim2);
+void Write16F7x(int dim,int vdd);
+void Write16F71x(int dim,int vdd);
+void Write16F72x(int dim,int d,int d2);
+void Write16F62x (int dim,int dim2);
+void Write16F8x(int dim,int dim2);
+void Write16F81x(int dim,int dim2);
+void Write16F87x(int dim,int dim2);
+void Write16F87xA(int dim,int dim2,int seq);
+void Write16F88x(int dim,int dim2);
+void Read16F1xxx(int dim,int dim2,int dim3,int options);
+void Write16F1xxx(int dim,int dim2,int options);
+void Read16F18xxx(int dim,int dim2,int dim3,int options);
+void Write16F18xxx(int dim,int dim2,int options);
+void DisplayCODE16F(int size);
+void DisplayEE16F(int size);
+
diff --git a/progP18.c b/progP18.c
new file mode 100644
index 0000000..922e8bf
--- /dev/null
+++ b/progP18.c
@@ -0,0 +1,2662 @@
+/**
+ * \file progP18F.c - algorithms to program the PIC18 family of microcontrollers
+ * Copyright (C) 2009-2022 Alberto Maccioni
+ *
+ * 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/>
+ */
+
+//This cannot be executed conditionally on MSVC
+//#include "stdafx.h"
+
+#include "common.h"
+
+struct ID18{
+ int id;
+ char *device;
+ int revmask;
+} PIC18LIST[]={
+ {0x0400,"18F252/2539 rev%d\r\n",0x1F},
+ {0x0420,"18F452/4539 rev%d\r\n",0x1F},
+ {0x0480,"18F242/2439 rev%d\r\n",0x1F},
+ {0x04A0,"18F442/4439 rev%d\r\n",0x1F},
+ {0x0500,"18F2320 rev%d\r\n",0x1F},
+ {0x0520,"18F4320 rev%d\r\n",0x1F},
+ {0x0580,"18F2220 rev%d\r\n",0x1F},
+ {0x05A0,"18F4220 rev%d\r\n",0x1F},
+ {0x0600,"18F8720 rev%d\r\n",0x1F},
+ {0x0620,"18F6720 rev%d\r\n",0x1F},
+ {0x0640,"18F8620 rev%d\r\n",0x1F},
+ {0x0660,"18F6620 rev%d\r\n",0x1F},
+ {0x07C0,"18F1320 rev%d\r\n",0x1F},
+ {0x07E0,"18F1220 rev%d\r\n",0x1F},
+ {0x0800,"18F248 rev%d\r\n",0x1F},
+ {0x0820,"18F448 rev%d\r\n",0x1F},
+ {0x0840,"18F258 rev%d\r\n",0x1F},
+ {0x0860,"18F458 rev%d\r\n",0x1F},
+ {0x0880,"18F4431 rev%d\r\n",0x1F},
+ {0x08A0,"18F4331 rev%d\r\n",0x1F},
+ {0x08C0,"18F2431 rev%d\r\n",0x1F},
+ {0x08E0,"18F2331 rev%d\r\n",0x1F},
+ {0x0B20,"18F6520 rev%d\r\n",0x1F},
+ {0x0B00,"18F8520 rev%d\r\n",0x1F},
+ {0x0C00,"18F4620 rev%d\r\n",0x1F},
+ {0x0C20,"18F4610 rev%d\r\n",0x1F},
+ {0x0C40,"18F4525 rev%d\r\n",0x1F},
+ {0x0C60,"18F4515 rev%d\r\n",0x1F},
+ {0x0C80,"18F2620 rev%d\r\n",0x1F},
+ {0x0CA0,"18F2610 rev%d\r\n",0x1F},
+ {0x0CC0,"18F2525 rev%d\r\n",0x1F},
+ {0x0CE0,"18F2515 rev%d\r\n",0x1F},
+ {0x0E80,"18F4680 rev%d\r\n",0x1F},
+ {0x0EA0,"18F4585 rev%d\r\n",0x1F},
+ {0x0EC0,"18F2680 rev%d\r\n",0x1F},
+ {0x0EE0,"18F2585 rev%d\r\n",0x1F},
+ {0x1081,"18F4523 rev%d\r\n",0x0F},
+ {0x1080,"18F4520 rev%d\r\n",0x0F},
+ {0x10A0,"18F4510 rev%d\r\n",0x1F},
+ {0x10C1,"18F4423 rev%d\r\n",0x0F},
+ {0x10C0,"18F4420 rev%d\r\n",0x0F},
+ {0x10E0,"18F4410 rev%d\r\n",0x1F},
+ {0x1100,"18F2523 rev%d\r\n",0x0F},
+ {0x1100,"18F2520 rev%d\r\n",0x0F},
+ {0x1120,"18F2510 rev%d\r\n",0x1F},
+ {0x1140,"18F2423 rev%d\r\n",0x0F},
+ {0x1140,"18F2420 rev%d\r\n",0x0F},
+ {0x1160,"18F2410 rev%d\r\n",0x1F},
+ {0x1200,"18F4550 rev%d\r\n",0x1F},
+ {0x1220,"18F4455 rev%d\r\n",0x1F},
+ {0x1240,"18F2550 rev%d\r\n",0x1F},
+ {0x1260,"18F2455 rev%d\r\n",0x1F},
+ {0x1340,"18F6527 rev%d\r\n",0x1F},
+ {0x1360,"18F8527 rev%d\r\n",0x1F},
+ {0x1380,"18F6622 rev%d\r\n",0x1F},
+ {0x13A0,"18F8622 rev%d\r\n",0x1F},
+ {0x13C0,"18F6627 rev%d\r\n",0x1F},
+ {0x13E0,"18F8627 rev%d\r\n",0x1F},
+ {0x1400,"18F6722 rev%d\r\n",0x1F},
+ {0x1420,"18F8722 rev%d\r\n",0x1F},
+ {0x1520,"18F65J10 rev%d\r\n",0x1F},
+ {0x1540,"18F65J15 rev%d\r\n",0x1F},
+ {0x1560,"18F66J10 rev%d\r\n",0x1F},
+ {0x1580,"18F66J15 rev%d\r\n",0x1F},
+ {0x15A0,"18F67J10 rev%d\r\n",0x1F},
+ {0x15E0,"18F85J10 rev%d\r\n",0x1F},
+ {0x1700,"18F85J15 rev%d\r\n",0x1F},
+ {0x1720,"18F86J10 rev%d\r\n",0x1F},
+ {0x1740,"18F86J15 rev%d\r\n",0x1F},
+ {0x1760,"18F87J10 rev%d\r\n",0x1F},
+ {0x1800,"18F66J60 rev%d\r\n",0x1F},
+ {0x1820,"18F86J60 rev%d\r\n",0x1F},
+ {0x1840,"18F96J60 rev%d\r\n",0x1F},
+ {0x1A80,"18F4580 rev%d\r\n",0x1F},
+ {0x1AA0,"18F4480 rev%d\r\n",0x1F},
+ {0x1AC0,"18F2580 rev%d\r\n",0x1F},
+ {0x1AE0,"18F2480 rev%d\r\n",0x1F},
+ {0x1C00,"18F25J10 rev%d\r\n",0x1F},
+ {0x1C20,"18F45J10 rev%d\r\n",0x1F},
+ {0x1C40,"18LF25J10 rev%d\r\n",0x1F},
+ {0x1C60,"18LF45J10 rev%d\r\n",0x1F},
+ {0x1D00,"18F24J10 rev%d\r\n",0x1F},
+ {0x1D20,"18F44J10 rev%d\r\n",0x1F},
+ {0x1D40,"18LF24J10 rev%d\r\n",0x1F},
+ {0x1D60,"18LF44J10 rev%d\r\n",0x1F},
+ {0x1E00,"18F1230 rev%d\r\n",0x1F},
+ {0x1E20,"18F1330 rev%d\r\n",0x1F},
+ {0x1F00,"18F66J65 rev%d\r\n",0x1F},
+ {0x1F20,"18F67J60 rev%d\r\n",0x1F},
+ {0x1F40,"18F86J65 rev%d\r\n",0x1F},
+ {0x1F60,"18F87J60 rev%d\r\n",0x1F},
+ {0x1F80,"18F96J65 rev%d\r\n",0x1F},
+ {0x1FA0,"18F97J60 rev%d\r\n",0x1F},
+ {0x1FE0,"18F1330-ICD rev%d\r\n",0x1F},
+ {0x2000,"18F46K20 rev%d\r\n",0x1F},
+ {0x2020,"18F26K20 rev%d\r\n",0x1F},
+ {0x2040,"18F45K20 rev%d\r\n",0x1F},
+ {0x2060,"18F25K20 rev%d\r\n",0x1F},
+ {0x2080,"18F44K20 rev%d\r\n",0x1F},
+ {0x20A0,"18F24K20 rev%d\r\n",0x1F},
+ {0x20C0,"18F43K20 rev%d\r\n",0x1F},
+ {0x20E0,"18F23K20 rev%d\r\n",0x1F},
+ {0x2100,"18F4321 rev%d\r\n",0x1F},
+ {0x2120,"18F2321 rev%d\r\n",0x1F},
+ {0x2140,"18F4221 rev%d\r\n",0x1F},
+ {0x2160,"18F2221 rev%d\r\n",0x1F},
+ {0x2400,"18F4450 rev%d\r\n",0x1F},
+ {0x2420,"18F2450 rev%d\r\n",0x1F},
+ {0x2700,"18F2682 rev%d\r\n",0x1F},
+ {0x2720,"18F2685 rev%d\r\n",0x1F},
+ {0x2740,"18F4682 rev%d\r\n",0x1F},
+ {0x2760,"18F4685 rev%d\r\n",0x1F},
+ {0x2A00,"18F4553 rev%d\r\n",0x1F},
+ {0x2A20,"18F4458 rev%d\r\n",0x1F},
+ {0x2A40,"18F2553 rev%d\r\n",0x1F},
+ {0x2A60,"18F2458 rev%d\r\n",0x1F},
+ {0x3800,"18F63J90 rev%d\r\n",0x1F},
+ {0x3820,"18F64J90 rev%d\r\n",0x1F},
+ {0x3860,"18F65J90 rev%d\r\n",0x1F},
+ {0x3880,"18F83J90 rev%d\r\n",0x1F},
+ {0x38A0,"18F84J90 rev%d\r\n",0x1F},
+ {0x38E0,"18F85J90 rev%d\r\n",0x1F},
+ {0x3900,"18F63J11 rev%d\r\n",0x1F},
+ {0x3920,"18F64J11 rev%d\r\n",0x1F},
+ {0x3960,"18F65J11 rev%d\r\n",0x1F},
+ {0x3980,"18F83J11 rev%d\r\n",0x1F},
+ {0x39A0,"18F84J11 rev%d\r\n",0x1F},
+ {0x39E0,"18F85J11 rev%d\r\n",0x1F},
+ {0x4100,"18F65J50 rev%d\r\n",0x1F},
+ {0x4140,"18F66J50 rev%d\r\n",0x1F},
+ {0x4160,"18F66J55 rev%d\r\n",0x1F},
+ {0x4180,"18F67J50 rev%d\r\n",0x1F},
+ {0x41A0,"18F85J50 rev%d\r\n",0x1F},
+ {0x41E0,"18F86J50 rev%d\r\n",0x1F},
+ {0x4200,"18F86J55 rev%d\r\n",0x1F},
+ {0x4220,"18F87J50 rev%d\r\n",0x1F},
+ {0x4440,"18F66J11 rev%d\r\n",0x1F},
+ {0x4460,"18F66J16 rev%d\r\n",0x1F},
+ {0x4480,"18F67J11 rev%d\r\n",0x1F},
+ {0x44E0,"18F86J11 rev%d\r\n",0x1F},
+ {0x4500,"18F86J16 rev%d\r\n",0x1F},
+ {0x4520,"18F87J11 rev%d\r\n",0x1F},
+ {0x4700,"18LF13K50 rev%d\r\n",0x1F},
+ {0x4720,"18LF14K50 rev%d\r\n",0x1F},
+ {0x4740,"18F13K50 rev%d\r\n",0x1F},
+ {0x4760,"18F14K50 rev%d\r\n",0x1F},
+ {0x49C0,"18F6628 rev%d\r\n",0x1F},
+ {0x49E0,"18F8628 rev%d\r\n",0x1F},
+ {0x4A00,"18F6723 rev%d\r\n",0x1F},
+ {0x4A20,"18F8723 rev%d\r\n",0x1F},
+ {0x4C00,"18F24J50 rev%d\r\n",0x1F},
+ {0x4C20,"18F25J50 rev%d\r\n",0x1F},
+ {0x4C40,"18F26J50 rev%d\r\n",0x1F},
+ {0x4C60,"18F44J50 rev%d\r\n",0x1F},
+ {0x4C80,"18F45J50 rev%d\r\n",0x1F},
+ {0x4D80,"18F24J11 rev%d\r\n",0x1F},
+ {0x4DA0,"18F25J11 rev%d\r\n",0x1F},
+ {0x4DC0,"18F26J11 rev%d\r\n",0x1F},
+ {0x4DE0,"18F44J11 rev%d\r\n",0x1F},
+ {0x4E00,"18F45J11 rev%d\r\n",0x1F},
+ {0x4E20,"18F46J11 rev%d\r\n",0x1F},
+ {0x4E60,"18LF25J11 rev%d\r\n",0x1F},
+ {0x4E80,"18LF26J11 rev%d\r\n",0x1F},
+ {0x4EA0,"18LF44J11 rev%d\r\n",0x1F},
+ {0x4EC0,"18LF45J11 rev%d\r\n",0x1F},
+ {0x4EE0,"18LF46J11 rev%d\r\n",0x1F},
+ {0x4F20,"18F14K22 rev%d\r\n",0x1F},
+ {0x4F40,"18F13K22 rev%d\r\n",0x1F},
+ {0x4F60,"18LF14K22 rev%d\r\n",0x1F},
+ {0x4F80,"18LF13K22 rev%d\r\n",0x1F},
+ {0x5000,"18F66J90 rev%d\r\n",0x1F},
+ {0x5020,"18F67J90 rev%d\r\n",0x1F},
+ {0x5040,"18F66J93/86J72 rev%d\r\n",0x1F},
+ {0x5060,"18F67J93/87J72 rev%d\r\n",0x1F},
+ {0x5080,"18F86J90 rev%d\r\n",0x1F},
+ {0x50A0,"18F87J90 rev%d\r\n",0x1F},
+ {0x50C0,"18F86J93 rev%d\r\n",0x1F},
+ {0x50E0,"18F87J93 rev%d\r\n",0x1F},
+ {0x5400,"18F46K22 rev%d\r\n",0x1F},
+ {0x5420,"18LF46K22 rev%d\r\n",0x1F},
+ {0x5440,"18F26K22 rev%d\r\n",0x1F},
+ {0x5460,"18LF26K22 rev%d\r\n",0x1F},
+ {0x5500,"18F45K22 rev%d\r\n",0x1F},
+ {0x5520,"18LF45K22 rev%d\r\n",0x1F},
+ {0x5540,"18F25K22 rev%d\r\n",0x1F},
+ {0x5560,"18LF25K22 rev%d\r\n",0x1F},
+ {0x5600,"18F44K22 rev%d\r\n",0x1F},
+ {0x5620,"18LF44K22 rev%d\r\n",0x1F},
+ {0x5640,"18F24K22 rev%d\r\n",0x1F},
+ {0x5660,"18LF24K22 rev%d\r\n",0x1F},
+ {0x5700,"18F43K22 rev%d\r\n",0x1F},
+ {0x5720,"18LF43K22 rev%d\r\n",0x1F},
+ {0x5740,"18F23K22 rev%d\r\n",0x1F},
+ {0x5760,"18LF23K22 rev%d\r\n",0x1F},
+ {0x5820,"18F26J53 rev%d\r\n",0x1F},
+ {0x5860,"18F27J53 rev%d\r\n",0x1F},
+ {0x58A0,"18F46J53 rev%d\r\n",0x1F},
+ {0x58E0,"18F47J53 rev%d\r\n",0x1F},
+ {0x5920,"18F26J13 rev%d\r\n",0x1F},
+ {0x5960,"18F27J13 rev%d\r\n",0x1F},
+ {0x59A0,"18F46J13 rev%d\r\n",0x1F},
+ {0x59E0,"18F47J13 rev%d\r\n",0x1F},
+ {0x5A20,"18LF26J53 rev%d\r\n",0x1F},
+ {0x5A60,"18LF27J53 rev%d\r\n",0x1F},
+ {0x5AA0,"18LF46J53 rev%d\r\n",0x1F},
+ {0x5AE0,"18LF47J53 rev%d\r\n",0x1F},
+ {0x5B20,"18LF26J13 rev%d\r\n",0x1F},
+ {0x5B60,"18LF27J13 rev%d\r\n",0x1F},
+ {0x5BA0,"18LF46J13 rev%d\r\n",0x1F},
+ {0x5BE0,"18LF47J13 rev%d\r\n",0x1F},
+ {0x5C00,"18F45K50 rev%d\r\n",0x1F},
+ {0x5C20,"18F25K50 rev%d\r\n",0x1F},
+ {0x5C60,"18F24K50 rev%d\r\n",0x1F},
+ {0x5C80,"18LF45K50 rev%d\r\n",0x1F},
+ {0x5CA0,"18LF25K50 rev%d\r\n",0x1F},
+ {0x5CE0,"18LF24K50 rev%d\r\n",0x1F},
+ {0x5D00,"18F46K50 rev%d\r\n",0x1F},
+ {0x5D20,"18F26K50 rev%d\r\n",0x1F},
+ {0x5D40,"18LF46K50 rev%d\r\n",0x1F},
+ {0x5D60,"18LF26K50 rev%d\r\n",0x1F},
+ {0x60E0,"18F66K80 rev%d\r\n",0x1F},
+ {0x6100,"18F46K80 rev%d\r\n",0x1F},
+ {0x6120,"18F26K80 rev%d\r\n",0x1F},
+ {0x6140,"18F65K80 rev%d\r\n",0x1F},
+ {0x6160,"18F45K80 rev%d\r\n",0x1F},
+ {0x6180,"18F25K80 rev%d\r\n",0x1F},
+ {0x61C0,"18LF66K80 rev%d\r\n",0x1F},
+ {0x61E0,"18LF46K80 rev%d\r\n",0x1F},
+ {0x6200,"18LF26K80 rev%d\r\n",0x1F},
+ {0x6220,"18LF65K80 rev%d\r\n",0x1F},
+ {0x6240,"18LF45K80 rev%d\r\n",0x1F},
+ {0x6260,"18LF25K80 rev%d\r\n",0x1F},
+ {0x6B80,"18F57K42 rev%c%d\r\n",0xFFFF},
+ {0x6BA0,"18F56K42 rev%c%d\r\n",0xFFFF},
+ {0x6BC0,"18F55K42 rev%c%d\r\n",0xFFFF},
+ {0x6BE0,"18F47K42 rev%c%d\r\n",0xFFFF},
+ {0x6C00,"18F46K42 rev%c%d\r\n",0xFFFF},
+ {0x6C20,"18F45K42 rev%c%d\r\n",0xFFFF},
+ {0x6C40,"18F27K42 rev%c%d\r\n",0xFFFF},
+ {0x6C60,"18F26K42 rev%c%d\r\n",0xFFFF},
+ {0x6CC0,"18LF57K42 rev%c%d\r\n",0xFFFF},
+ {0x6CE0,"18LF56K42 rev%c%d\r\n",0xFFFF},
+ {0x6D00,"18LF55K42 rev%c%d\r\n",0xFFFF},
+ {0x6D20,"18LF47K42 rev%c%d\r\n",0xFFFF},
+ {0x6D40,"18LF46K42 rev%c%d\r\n",0xFFFF},
+ {0x6D60,"18LF45K42 rev%c%d\r\n",0xFFFF},
+ {0x6D80,"18LF27K42 rev%c%d\r\n",0xFFFF},
+ {0x6DA0,"18LF26K42 rev%c%d\r\n",0xFFFF},
+ {0x6EC0,"18F26K83 rev%c%d\r\n",0xFFFF},
+ {0x6EE0,"18F25K83 rev%c%d\r\n",0xFFFF},
+ {0x6F00,"18LF26K83 rev%c%d\r\n",0xFFFF},
+ {0x6F20,"18LF25K83 rev%c%d\r\n",0xFFFF},
+ {0x73C0,"18F25Q43 rev%c%d\r\n",0xFFFF},
+ {0x73E0,"18F45Q43 rev%c%d\r\n",0xFFFF},
+ {0x7400,"18F55Q43 rev%c%d\r\n",0xFFFF},
+ {0x7420,"18F26Q43 rev%c%d\r\n",0xFFFF},
+ {0x7440,"18F46Q43 rev%c%d\r\n",0xFFFF},
+ {0x7460,"18F56Q43 rev%c%d\r\n",0xFFFF},
+ {0x7480,"18F27Q43 rev%c%d\r\n",0xFFFF},
+ {0x74A0,"18F47Q43 rev%c%d\r\n",0xFFFF},
+ {0x74C0,"18F57Q43 rev%c%d\r\n",0xFFFF},
+ {0x74E0,"18F15Q41 rev%c%d\r\n",0xFFFF},
+ {0x7500,"18F05Q41 rev%c%d\r\n",0xFFFF},
+ {0x7520,"18F14Q41 rev%c%d\r\n",0xFFFF},
+ {0x7540,"18F04Q41 rev%c%d\r\n",0xFFFF},
+ {0x7560,"18F16Q41 rev%c%d\r\n",0xFFFF},
+ {0x7580,"18F06Q41 rev%c%d\r\n",0xFFFF},
+ {0x75A0,"18F16Q40 rev%c%d\r\n",0xFFFF},
+ {0x75C0,"18F06Q40 rev%c%d\r\n",0xFFFF},
+ {0x75E0,"18F15Q40 rev%c%d\r\n",0xFFFF},
+ {0x7600,"18F05Q40 rev%c%d\r\n",0xFFFF},
+ {0x7620,"18F14Q40 rev%c%d\r\n",0xFFFF},
+ {0x7640,"18F04Q40 rev%c%d\r\n",0xFFFF},
+ {0x7660,"18F24Q71 rev%c%d\r\n",0xFFFF},
+ {0x76A0,"18F25Q71 rev%c%d\r\n",0xFFFF},
+ {0x76E0,"18F26Q71 rev%c%d\r\n",0xFFFF},
+ {0x7720,"18F46Q71 rev%c%d\r\n",0xFFFF},
+ {0x7760,"18F56Q71 rev%c%d\r\n",0xFFFF},
+ {0x77A0,"18F44Q71 rev%c%d\r\n",0xFFFF},
+ {0x77E0,"18F45Q71 rev%c%d\r\n",0xFFFF},
+ {0x7820,"18F54Q71 rev%c%d\r\n",0xFFFF},
+ {0x7860,"18F55Q71 rev%c%d\r\n",0xFFFF},
+ {0x9900,"18F26Q84 rev%c%d\r\n",0xFFFF},
+ {0x9901,"18F46Q84 rev%c%d\r\n",0xFFFF},
+ {0x9902,"18F56Q84 rev%c%d\r\n",0xFFFF},
+ {0x9903,"18F27Q84 rev%c%d\r\n",0xFFFF},
+ {0x9904,"18F47Q84 rev%c%d\r\n",0xFFFF},
+ {0x9905,"18F57Q84 rev%c%d\r\n",0xFFFF},
+ {0x9906,"18F26Q83 rev%c%d\r\n",0xFFFF},
+ {0x9907,"18F46Q83 rev%c%d\r\n",0xFFFF},
+ {0x9908,"18F56Q83 rev%c%d\r\n",0xFFFF},
+ {0x9909,"18F27Q83 rev%c%d\r\n",0xFFFF},
+ {0x990A,"18F47Q83 rev%c%d\r\n",0xFFFF},
+ {0x990B,"18F57Q83 rev%c%d\r\n",0xFFFF},
+};
+
+void PIC18_ID(int id)
+{
+ char s[128];
+ int i;
+ for(i=0;i<sizeof(PIC18LIST)/sizeof(PIC18LIST[0]);i++){
+ if(PIC18LIST[i].revmask!=0xFFFF&&PIC18LIST[i].id==(id&~PIC18LIST[i].revmask)){
+ sprintf(s,PIC18LIST[i].device,id&PIC18LIST[i].revmask);
+ PrintMessage(s);
+ return;
+ }
+ else if(PIC18LIST[i].revmask==0xFFFF&&PIC18LIST[i].id==(id&0xFFFF)){
+ int MJrev=(id>>22)&0x3F;
+ int MNrev=(id>>16)&0x3F;
+ sprintf(s,PIC18LIST[i].device,MJrev+'A',MNrev);
+ PrintMessage(s);
+ return;
+ }
+ }
+ sprintf(s,"%s",strings[S_nodev]); //"Unknown device\r\n");
+ PrintMessage(s);
+}
+
+void DisplayCODE18F(int dim){
+// display PIC18F CODE memory
+ char s[256]="",t[256]="";
+ char* aux=(char*)malloc((dim/COL+1)*(16+COL*6));
+ aux[0]=0;
+ int valid=0,empty=1,i,j,lines=0;
+ for(i=0;i<dim&&i<size;i+=COL*2){
+ valid=0;
+ for(j=i;j<i+COL*2&&j<dim;j++){
+ sprintf(t,"%02X ",memCODE[j]);
+ strcat(s,t);
+ if(memCODE[j]<0xff) valid=1;
+ }
+ if(valid){
+ sprintf(t,"%04X: %s\r\n",i,s);
+ strcat(aux,t);
+ empty=0;
+ lines++;
+ if(lines>500){ //limit number of lines printed
+ strcat(aux,"(...)\r\n");
+ i=(dim<size?dim:size)-COL*4;
+ lines=490;
+ }
+ }
+ s[0]=0;
+ }
+ if(empty) PrintMessage(strings[S_Empty]); //empty
+ else PrintMessage(aux);
+ free(aux);
+}
+
+void Read18Fx(int dim,int dim2,int options)
+// read 16 bit PIC 18Fxxxx
+// dim=program size (bytes) dim2=eeprom size (bytes)
+// options:
+// bit [3:0]
+// 0 = vdd before vpp (12V)
+// 1 = vdd before vpp (9V)
+// 2 = low voltage entry with 32 bit key
+// 3 = vdd before vpp (9V) with 32 bit key
+// bit [7:4]
+// 0 = normal control registers address
+// 1 = new control registers address (18FxxK80)
+{
+ int k=0,k2=0,z=0,i,j;
+ int entry=options&0xF;
+ int newAddr=(options>>4)&0xF;
+ if(dim>0x1FFFFF||dim<0){
+ PrintMessage(strings[S_CodeLim]); //"Code size out of limits\r\n"
+ return;
+ }
+ if(dim2>0x800||dim2<0){
+ PrintMessage(strings[S_EELim]); //"EEPROM size out of limits\r\n"
+ return;
+ }
+ if(entry>0&&!CheckV33Regulator()){
+ PrintMessage(strings[S_noV33reg]); //Can't find 3.3V expansion board
+ return;
+ }
+ double vpp=-1;
+ if(entry==0) vpp=12;
+ else if(entry==1||entry==3) vpp=8.5;
+ if(!StartHVReg(vpp)){
+ PrintMessage(strings[S_HVregErr]); //"HV regulator error\r\n"
+ return;
+ }
+ if(saveLog){
+ OpenLogFile(); //"log.txt"
+ fprintf(logfile,"Read18F(%d,%d,%d) (0x%X,0x%X,0x%X)\n",dim,dim2,options,dim,dim2,options);
+ }
+ size=dim;
+ sizeEE=dim2;
+ if(memCODE) free(memCODE);
+ memCODE=(unsigned char*)malloc(size); //CODE
+ if(memEE) free(memEE);
+ memEE=(unsigned char*)malloc(sizeEE); //EEPROM
+ for(j=0;j<8;j++) memID[j]=0xFF;
+ for(j=0;j<14;j++) memCONFIG[j]=0xFF;
+ unsigned int start=GetTickCount();
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T1T2;
+ bufferU[j++]=1; //T1=1u
+ bufferU[j++]=100; //T2=100u
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2000>>8;
+ bufferU[j++]=2000&0xff;
+ bufferU[j++]=EN_VPP_VCC; //enter program mode
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=NOP;
+ bufferU[j++]=EN_VPP_VCC; //VDD+VPP
+ bufferU[j++]=0x5;
+ if(entry==2){ //LV entry with key
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ }
+ if(entry==2||entry==3){ //entry with key
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=TX16;
+ bufferU[j++]=2;
+ bufferU[j++]=0x4D;
+ bufferU[j++]=0x43;
+ bufferU[j++]=0x48;
+ bufferU[j++]=0x50;
+ bufferU[j++]=EN_VPP_VCC; //VDD+VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=WAIT_T3;
+ }
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E; //3F
+ bufferU[j++]=0x3F;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //-> TBLPTRU
+ bufferU[j++]=0xF8;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E; //FF
+ bufferU[j++]=0xFF;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //-> TBLPTRH
+ bufferU[j++]=0xF7;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E; //FE
+ bufferU[j++]=0xFE;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //-> TBLPTRL
+ bufferU[j++]=0xF6;
+ bufferU[j++]=TBLR_INC_N; //DevID1-2 0x3FFFFE-F
+ bufferU[j++]=2;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6A; //CLRF TBLPTRU
+ bufferU[j++]=0xF8;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6A; //CLRF TBLPTRH
+ bufferU[j++]=0xF7;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6A; //CLRF TBLPTRL
+ bufferU[j++]=0xF6;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(entry==2?11:4);
+ for(z=0;bufferI[z]!=TBLR_INC_N&&z<DIMBUF;z++);
+ if(z<DIMBUF-3){
+ PrintMessage2(strings[S_DevID2],bufferI[z+3],bufferI[z+2]); //"DevID: 0x%02X%02X\r\n"
+ PIC18_ID(bufferI[z+2]+(bufferI[z+3]<<8));
+ }
+//****************** read code ********************
+ PrintMessage(strings[S_CodeReading1]); //code read ...
+ PrintStatusSetup();
+ if(saveLog) fprintf(logfile,"Read code\n");
+ for(i=0,j=0;i<dim;i+=DIMBUF-4){
+ bufferU[j++]=TBLR_INC_N;
+ bufferU[j++]=i<dim-(DIMBUF-4)?DIMBUF-4:dim-i;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ for(z=0;bufferI[z]!=TBLR_INC_N&&z<DIMBUF;z++);
+ for(j=z+2;(j<z+2+bufferI[z+1])&&j<DIMBUF;j++) memCODE[k++]=bufferI[j];
+ PrintStatus(strings[S_CodeReading2],i*100/(dim+dim2),i); //"Read: %d%%, addr. %05X"
+ if(RWstop) i=dim;
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k,k); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ }
+ PrintStatusEnd();
+ if(k!=dim){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ReadCodeErr2],dim,k); //"Error reading code area, requested %d bytes, read %d\r\n"
+ }
+ else PrintMessage(strings[S_Compl]);
+//****************** read config area ********************
+ if(saveLog) fprintf(logfile,"Read config\n");
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E; //TBLPTRU ID 0x200000
+ bufferU[j++]=0x20; //TBLPTRU ID 0x200000
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //TBLPTRU
+ bufferU[j++]=0xF8; //TBLPTRU
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6A; //TBLPTRH
+ bufferU[j++]=0xF7; //TBLPTRH
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6A; //TBLPTRL
+ bufferU[j++]=0xF6; //TBLPTRL
+ bufferU[j++]=TBLR_INC_N;
+ bufferU[j++]=8;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E; //TBLPTRU CONFIG 0x300000
+ bufferU[j++]=0x30; //TBLPTRU CONFIG 0x300000
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //TBLPTRU
+ bufferU[j++]=0xF8; //TBLPTRU
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6A; //TBLPTRH
+ bufferU[j++]=0xF7; //TBLPTRH
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6A; //TBLPTRL
+ bufferU[j++]=0xF6; //TBLPTRL
+ bufferU[j++]=TBLR_INC_N;
+ bufferU[j++]=14;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(8);
+ for(z=0;bufferI[z]!=TBLR_INC_N&&z<DIMBUF-28;z++);
+ if(z<DIMBUF-28){
+ for(i=0;i<8;i++) memID[k2++]=bufferI[z+i+2];
+ for(;i<14+8;i++) memCONFIG[-8+k2++]=bufferI[z+i+8];
+ }
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k2,k2); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ if(k2!=22){
+ PrintMessage2(strings[S_ReadConfigErr],22,k2); //"Error reading config area, requested %d bytes, read %d\r\n"
+ }
+//****************** read eeprom ********************
+ if(dim2){
+ PrintMessage(strings[S_ReadEE]); //read eeprom ...
+ PrintStatusSetup();
+ if(saveLog) fprintf(logfile,"Read EEPROM\n");
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x9E; //EEPGD=0
+ bufferU[j++]=newAddr==0?0xA6:0x7F;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x9C; //CFGS=0
+ bufferU[j++]=newAddr==0?0xA6:0x7F;
+ for(k2=0,i=0;i<dim2;i++){
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E; //MOVLW
+ bufferU[j++]=i&0xFF;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //MOVWF
+ bufferU[j++]=newAddr==0?0xA9:0x74; //ADDR
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E; //MOVLW
+ bufferU[j++]=(i>>8)&0xFF;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //MOVWF
+ bufferU[j++]=newAddr==0?0xAA:0x75; //ADDRH
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x80; //RD=1
+ bufferU[j++]=newAddr==0?0xA6:0x7F;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x50; //MOVF EEDATA,w
+ bufferU[j++]=newAddr==0?0xA8:0x73;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //MOVWF TABLAT
+ bufferU[j++]=0xF5;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x00; //NOP
+ bufferU[j++]=0x00;
+ bufferU[j++]=SHIFT_TABLAT;
+ if(j>DIMBUF-26||i==dim2-1){
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(10);
+ for(z=0;z<DIMBUF-1;z++){
+ if(bufferI[z]==SHIFT_TABLAT){
+ memEE[k2++]=bufferI[z+1];
+ z+=8;
+ }
+ }
+ PrintStatus(strings[S_CodeReading],(i+dim)*100/(dim+dim2),i); //"Read: %d%%, addr. %03X"
+ if(RWstop) i=dim2;
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k2,k2); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ }
+ }
+ PrintStatusEnd();
+ if(k2!=dim2){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ReadEEErr],dim2,k2); //"Error reading EEPROM area, requested %d bytes, read %d\r\n"
+ }
+ else PrintMessage(strings[S_Compl]);
+ }
+ PrintMessage("\r\n");
+//****************** exit ********************
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=1;
+ bufferU[j++]=EN_VPP_VCC; //0
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(1);
+ unsigned int stop=GetTickCount();
+ PrintStatusClear();
+//****************** visualize ********************
+ for(i=0;i<8;i+=2){
+ PrintMessage4(strings[S_ChipID2],i,memID[i],i+1,memID[i+1]); //"ID%d: 0x%02X ID%d: 0x%02X\r\n"
+ }
+ 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"
+ }
+ PrintMessage(strings[S_CodeMem]); //"\r\nCode memory:\r\n"
+ DisplayCODE18F(dim);
+ if(dim2){
+ DisplayEE(); //visualize
+ }
+ sprintf(str,strings[S_End],(stop-start)/1000.0); //"\r\nEnd (%.2f s)\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+}
+
+void Write18Fx(int dim,int dim2,int wbuf,int eraseW1,int eraseW2,int options)
+// write 16 bit PIC 18Fxxxx
+// dim=program size (bytes) dim2=eeprom size (bytes) wbuf=write buffer size {<=64}
+// eraseW1=erase word @3C0005 (not used if >= 0x10000)
+// eraseW2=erase word @3C0004 (not used if >= 0x10000)
+// options:
+// bit [3:0]
+// 0 = vdd before vpp (12V)
+// 1 = vdd before vpp (9V)
+// 2 = low voltage entry with 32 bit key
+// 3 = vdd before vpp (9V) with 32 bit key
+// bit [7:4]
+// 0 = normal eeprom write algoritm
+// 1 = with unlock sequence 55 AA
+// bit [11:8]
+// 0 = 15ms erase delay, 1ms code write time, 5ms EE write, 5ms config write
+// 1 = 550ms erase delay, 1.2ms code write time, no config or EEPROM
+// 2 = 550ms erase delay, 3.4ms code write time, no config or EEPROM
+// 3 = separate block erase with 5ms delay, 1ms code write, 5ms EE write, 5ms config write
+// + new control registers address (18FxxK80)
+{
+ int k=0,k2,z=0,i,j;
+ int err=0;
+ int EEalgo=(options>>4)&0xF,entry=options&0xF,optWrite=(options>>8)&0xF;
+ if(dim>0x1FFFFF||dim<0){
+ PrintMessage(strings[S_CodeLim]); //"Code size out of limits\r\n"
+ return;
+ }
+ if(dim2>0x800||dim2<0){
+ PrintMessage(strings[S_EELim]); //"EEPROM size out of limits\r\n"
+ return;
+ }
+ if(wbuf>64){
+ PrintMessage(strings[S_WbufLim]); //"Write buffer size out of limits\r\n"
+ return;
+ }
+ if(entry>0&&!CheckV33Regulator()){
+ PrintMessage(strings[S_noV33reg]); //Can't find 3.3V expansion board
+ return;
+ }
+ double vpp=-1;
+ if(entry==0) vpp=12;
+ else if(entry==1||entry==3) vpp=8.5;
+ if(!StartHVReg(vpp)){
+ PrintMessage(strings[S_HVregErr]); //"HV regulator error\r\n"
+ return;
+ }
+ if(saveLog){
+ OpenLogFile(); //"log.txt"
+ fprintf(logfile,"Write18F(%d,%d,%d,%d) (0x%X,0x%X,0x%X,0x%X)\n",dim,dim2,wbuf,options,dim,dim2,wbuf,options);
+ }
+ if(dim>size) dim=size;
+ if(dim%wbuf){ //grow to an integer number of rows
+ dim+=wbuf-dim%wbuf;
+ j=size;
+ if(j<dim){
+ size=dim;
+ memCODE=(unsigned char*)realloc(memCODE,size);
+ for(;j<dim;j++) memCODE[j]=0xFF;
+ }
+ }
+ if(dim2>sizeEE) dim2=sizeEE;
+ if(dim<1){
+ PrintMessage(strings[S_NoCode]); //"Empty data area\r\n"
+ return;
+ }
+ unsigned int start=GetTickCount();
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T1T2;
+ bufferU[j++]=1; //T1=1u
+ bufferU[j++]=100; //T2=100u
+ bufferU[j++]=EN_VPP_VCC; //enter program mode
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC; //VDD+VPP
+ bufferU[j++]=0x5;
+ if(entry==2){ //LV entry with key
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ }
+ if(entry==2||entry==3){ //entry with key
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=TX16;
+ bufferU[j++]=2;
+ bufferU[j++]=0x4D;
+ bufferU[j++]=0x43;
+ bufferU[j++]=0x48;
+ bufferU[j++]=0x50;
+ bufferU[j++]=EN_VPP_VCC; //VDD+VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=WAIT_T3;
+ }
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E; //3F
+ bufferU[j++]=0x3F;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //-> TBLPTRU
+ bufferU[j++]=0xF8;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E; //FF
+ bufferU[j++]=0xFF;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //-> TBLPTRH
+ bufferU[j++]=0xF7;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E; //FE
+ bufferU[j++]=0xFE;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //-> TBLPTRL
+ bufferU[j++]=0xF6;
+ bufferU[j++]=TBLR_INC_N; //DevID1-2 0x3FFFFE-F
+ bufferU[j++]=2;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=5100>>8;
+ bufferU[j++]=5100&0xff;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(entry==2?10:3);
+ for(z=0;bufferI[z]!=TBLR_INC_N&&z<DIMBUF;z++);
+ if(z<DIMBUF-3){
+ PrintMessage2(strings[S_DevID2],bufferI[z+3],bufferI[z+2]); //"DevID: 0x%02X%02X\r\n"
+ PIC18_ID(bufferI[z+2]+(bufferI[z+3]<<8));
+ }
+ j=0;
+//****************** erase memory ********************
+ PrintMessage(strings[S_StartErase]); //"Erase ... "
+ if(optWrite!=3){ //chip erase
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E; //3C
+ bufferU[j++]=0x3C;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //-> TBLPTRU
+ bufferU[j++]=0xF8;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6A; //TBLPTRH=0
+ bufferU[j++]=0xF7;
+ if(eraseW1<0x10000){
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E; //05
+ bufferU[j++]=0x05;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //-> TBLPTRL
+ bufferU[j++]=0xF6;
+ bufferU[j++]=TABLE_WRITE; // eraseW1@3C0005
+ bufferU[j++]=(eraseW1>>8)&0xFF; //0x3F;
+ bufferU[j++]=eraseW1&0xFF; //0x3F;
+ }
+ if(eraseW2<0x10000){
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E; //04
+ bufferU[j++]=0x04;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //-> TBLPTRL
+ bufferU[j++]=0xF6;
+ bufferU[j++]=TABLE_WRITE; // eraseW2@3C0004
+ bufferU[j++]=(eraseW2>>8)&0xFF; //0x8F;
+ bufferU[j++]=eraseW2&0xFF; //0x8F;
+ }
+ bufferU[j++]=CORE_INS; //NOP
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=CORE_INS; //NOP
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(16);
+ if(optWrite!=0) msDelay(550);//bulk erase delay
+ j=0;
+ }
+ else{ //separate block erase
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E; //MOVLW 3C
+ bufferU[j++]=0x3C;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //MOVWF TBLPTRU
+ bufferU[j++]=0xF8;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6A; //CLRF TBLPTRH
+ bufferU[j++]=0xF7;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E; //MOVLW 4
+ bufferU[j++]=0x04;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //MOVWF TBLPTRL
+ bufferU[j++]=0xF6;
+ bufferU[j++]=TABLE_WRITE; //0x04 @ 0x3C0004
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x04;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E; //MOVLW 5
+ bufferU[j++]=0x05;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //MOVWF TBLPTRL
+ bufferU[j++]=0xF6;
+ bufferU[j++]=TABLE_WRITE; //0x01 @ 0x3C0005
+ bufferU[j++]=0x01;
+ bufferU[j++]=0x01;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E; //MOVLW 6
+ bufferU[j++]=0x06;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //MOVWF TBLPTRL
+ bufferU[j++]=0xF6;
+ bufferU[j++]=TABLE_WRITE; //0x80 @ 0x3C0006
+ bufferU[j++]=0x80;
+ bufferU[j++]=0x80;
+ bufferU[j++]=CORE_INS; //NOP
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=CORE_INS; //NOP
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(7); //block erase delay
+ j=0;
+ if(saveLog){
+ fprintf(logfile,"ERASE BLOCK0\n");
+ }
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E; //MOVLW 4
+ bufferU[j++]=0x04;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //MOVWF TBLPTRL
+ bufferU[j++]=0xF6;
+ bufferU[j++]=TABLE_WRITE; //0x04 @ 0x3C0004
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x04;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E; //MOVLW 5
+ bufferU[j++]=0x05;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //MOVWF TBLPTRL
+ bufferU[j++]=0xF6;
+ bufferU[j++]=TABLE_WRITE; //0x02 @ 0x3C0005
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x02;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E; //MOVLW 6
+ bufferU[j++]=0x06;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //MOVWF TBLPTRL
+ bufferU[j++]=0xF6;
+ bufferU[j++]=TABLE_WRITE; //0x80 @ 0x3C0006
+ bufferU[j++]=0x80;
+ bufferU[j++]=0x80;
+ bufferU[j++]=CORE_INS; //NOP
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=CORE_INS; //NOP
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(7); //block erase delay
+ j=0;
+ if(saveLog){
+ fprintf(logfile,"ERASE BLOCK1\n");
+ }
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E; //MOVLW 4
+ bufferU[j++]=0x04;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //MOVWF TBLPTRL
+ bufferU[j++]=0xF6;
+ bufferU[j++]=TABLE_WRITE; //0x04 @ 0x3C0004
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x04;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E; //MOVLW 5
+ bufferU[j++]=0x05;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //MOVWF TBLPTRL
+ bufferU[j++]=0xF6;
+ bufferU[j++]=TABLE_WRITE; //0x04 @ 0x3C0005
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x04;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E; //MOVLW 6
+ bufferU[j++]=0x06;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //MOVWF TBLPTRL
+ bufferU[j++]=0xF6;
+ bufferU[j++]=TABLE_WRITE; //0x80 @ 0x3C0006
+ bufferU[j++]=0x80;
+ bufferU[j++]=0x80;
+ bufferU[j++]=CORE_INS; //NOP
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=CORE_INS; //NOP
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(7); //block erase delay
+ j=0;
+ if(saveLog){
+ fprintf(logfile,"ERASE BLOCK2\n");
+ }
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E; //MOVLW 4
+ bufferU[j++]=0x04;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //MOVWF TBLPTRL
+ bufferU[j++]=0xF6;
+ bufferU[j++]=TABLE_WRITE; //0x04 @ 0x3C0004
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x04;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E; //MOVLW 5
+ bufferU[j++]=0x05;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //MOVWF TBLPTRL
+ bufferU[j++]=0xF6;
+ bufferU[j++]=TABLE_WRITE; //0x08 @ 0x3C0005
+ bufferU[j++]=0x08;
+ bufferU[j++]=0x08;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E; //MOVLW 6
+ bufferU[j++]=0x06;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //MOVWF TBLPTRL
+ bufferU[j++]=0xF6;
+ bufferU[j++]=TABLE_WRITE; //0x80 @ 0x3C0006
+ bufferU[j++]=0x80;
+ bufferU[j++]=0x80;
+ bufferU[j++]=CORE_INS; //NOP
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=CORE_INS; //NOP
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(7); //block erase delay
+ j=0;
+ if(saveLog){
+ fprintf(logfile,"ERASE BLOCK3\n");
+ }
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E; //MOVLW 4
+ bufferU[j++]=0x04;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //MOVWF TBLPTRL
+ bufferU[j++]=0xF6;
+ bufferU[j++]=TABLE_WRITE; //0x05 @ 0x3C0004
+ bufferU[j++]=0x05;
+ bufferU[j++]=0x05;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E; //MOVLW 5
+ bufferU[j++]=0x05;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //MOVWF TBLPTRL
+ bufferU[j++]=0xF6;
+ bufferU[j++]=TABLE_WRITE; //0x00 @ 0x3C0005
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E; //MOVLW 6
+ bufferU[j++]=0x06;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //MOVWF TBLPTRL
+ bufferU[j++]=0xF6;
+ bufferU[j++]=TABLE_WRITE; //0x80 @ 0x3C0006
+ bufferU[j++]=0x80;
+ bufferU[j++]=0x80;
+ bufferU[j++]=CORE_INS; //NOP
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=CORE_INS; //NOP
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(7); //block erase delay
+ j=0;
+ if(saveLog){
+ fprintf(logfile,"ERASE BOOT BLOCK\n");
+ }
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E; //MOVLW 4
+ bufferU[j++]=0x04;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //MOVWF TBLPTRL
+ bufferU[j++]=0xF6;
+ bufferU[j++]=TABLE_WRITE; //0x02 @ 0x3C0004
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x02;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E; //MOVLW 5
+ bufferU[j++]=0x05;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //MOVWF TBLPTRL
+ bufferU[j++]=0xF6;
+ bufferU[j++]=TABLE_WRITE; //0x00 @ 0x3C0005
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E; //MOVLW 6
+ bufferU[j++]=0x06;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //MOVWF TBLPTRL
+ bufferU[j++]=0xF6;
+ bufferU[j++]=TABLE_WRITE; //0x80 @ 0x3C0006
+ bufferU[j++]=0x80;
+ bufferU[j++]=0x80;
+ bufferU[j++]=CORE_INS; //NOP
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=CORE_INS; //NOP
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(7); //block erase delay
+ j=0;
+ if(saveLog){
+ fprintf(logfile,"ERASE CONFIG\n");
+ }
+ if(programID){
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x8E; //EEPGD=1
+ bufferU[j++]=0x7F;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x9C; //CFGS=0
+ bufferU[j++]=0x7F;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x84; //WREN=1
+ bufferU[j++]=0x7F;
+ bufferU[j++]=CORE_INS; //ID 0x200000
+ bufferU[j++]=0x0E; //MOVLW
+ bufferU[j++]=0x20; //
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //MOVWF TBLPTRU
+ bufferU[j++]=0xF8; //
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6A; //CLRF TBLPTRH
+ bufferU[j++]=0xF7; //CLRF TBLPTRH
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6A; //CLRF TBLPTRL
+ bufferU[j++]=0xF6; //CLRF TBLPTRL
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x88; //FREE=1
+ bufferU[j++]=0x7F;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x82; //WR=1
+ bufferU[j++]=0x7F;
+ bufferU[j++]=CORE_INS; //NOP
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(7); //row erase delay
+ j=0;
+ if(saveLog){
+ fprintf(logfile,"ERASE ID\n");
+ }
+ }
+ }
+ PrintMessage(strings[S_Compl]); //"completed\r\n"
+//****************** prepare write ********************
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x8E; //EEPGD=1
+ bufferU[j++]=optWrite!=3?0xA6:0x7F;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x9C; //CFCGS=0
+ bufferU[j++]=optWrite!=3?0xA6:0x7F;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x84; //WREN=1
+ bufferU[j++]=optWrite!=3?0xA6:0x7F;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6A; //TBLPTRU
+ bufferU[j++]=0xF8; //TBLPTRU
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6A; //TBLPTRH
+ bufferU[j++]=0xF7; //TBLPTRH
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6A; //TBLPTRL
+ bufferU[j++]=0xF6; //TBLPTRL
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(1);
+ j=0;
+//****************** write code ********************
+ PrintMessage(strings[S_StartCodeProg]); //"code write ... "
+ PrintStatusSetup();
+ int ww;
+ double wdly=1.0;
+ if(optWrite==1) wdly=1.2;
+ if(optWrite==2) wdly=3.4;
+ if(saveLog){
+ fprintf(logfile,"WRITE CODE\ndim=%d(0x%X)\n",dim,dim); //
+ }
+ int valid,i0;
+ j=0;
+ for(i=k=0;i<dim;){ //write xx instruction words
+ if(k==0){ //skip row if empty
+ i0=i;
+ for(valid=0;!valid&&i<dim;i+=valid?0:wbuf){
+ for(k2=0;k2<wbuf&&!valid;k2++) if(memCODE[i+k2]<0xFF) valid=1;
+ }
+ if(i>=dim) break;
+ if(i>i0){ //some rows were skipped; update current address
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E;
+ bufferU[j++]=(i>>16)&0xFF;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //MOVWF TBLPTRU
+ bufferU[j++]=0xF8;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E;
+ bufferU[j++]=(i>>8)&0xFF;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //MOVWF TBLPTRH
+ bufferU[j++]=0xF7;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E;
+ bufferU[j++]=i&0xFF;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //MOVWF TBLPTRL
+ bufferU[j++]=0xF6;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ }
+ }
+ if(DIMBUF-4-j<wbuf-2-k) ww=(DIMBUF-4-j)/2; //split data for a total of wbuf-2
+ else ww=(wbuf-2-k)/2;
+ bufferU[j++]=TBLW_INC_N;
+ bufferU[j++]=ww;
+ for(z=0;z<ww;z++){
+ bufferU[j++]=memCODE[i+1];
+ bufferU[j++]=memCODE[i];
+ i+=2;
+ }
+ k+=ww*2;
+ if(k==wbuf-2){ //Write row
+ if(j>DIMBUF-8){
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(3);
+ j=0;
+ }
+ bufferU[j++]=TBLW_PROG_INC;
+ bufferU[j++]=memCODE[i+1];
+ bufferU[j++]=memCODE[i];
+ if(optWrite==1){ //1.2ms
+ bufferU[j++]=1200>>8;
+ bufferU[j++]=1200&0xFF;
+ }
+ else if(optWrite==2){ //3.4ms
+ bufferU[j++]=3400>>8;
+ bufferU[j++]=3400&0xFF;
+ }
+ else{ //1ms
+ bufferU[j++]=1000>>8;
+ bufferU[j++]=1000&0xFF;
+ }
+ i+=2;
+ k=0;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(k==0?wdly:2);
+ j=0;
+ PrintStatus(strings[S_CodeWriting2],i*100/(dim+dim2),i/2); //"Write: %d%%,addr. %04X"
+ if(RWstop) i=dim;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k,k); //"i=%d, k=%d 0=%d\n"
+ }
+ }
+ PrintStatusEnd();
+ PrintMessage(strings[S_Compl]); //"completed\r\n"
+//****************** write ID ********************
+ if(programID&&(optWrite==0||optWrite==3)){
+ PrintMessage(strings[S_IDW]); //"Write ID ... "
+ if(saveLog) fprintf(logfile,"Write ID\n");
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x8E; //EEPGD=1
+ bufferU[j++]=optWrite!=3?0xA6:0x7F;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x9C; //CFCGS=0
+ bufferU[j++]=optWrite!=3?0xA6:0x7F;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E; //TBLPTRU ID 0x200000
+ bufferU[j++]=0x20; //TBLPTRU ID 0x200000
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //TBLPTRU
+ bufferU[j++]=0xF8; //TBLPTRU
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6A; //CLRF TBLPTRH
+ bufferU[j++]=0xF7; //CLRF TBLPTRH
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6A; //CLRF TBLPTRL
+ bufferU[j++]=0xF6; //CLRF TBLPTRL
+ bufferU[j++]=TBLW_INC_N;
+ bufferU[j++]=3;
+ for(i=0;i<3;i++){
+ bufferU[j++]=memID[i*2+1];
+ bufferU[j++]=memID[i*2];
+ }
+ bufferU[j++]=TBLW_PROG;
+ bufferU[j++]=memID[i*2+1];
+ bufferU[j++]=memID[i*2];
+ bufferU[j++]=1000>>8; //only one write so no need to specify different delay
+ bufferU[j++]=1000&0xFF;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,0,0); //"i=%d, k=%d 0=%d\n"
+ }
+ PrintMessage(strings[S_Compl]); //"completed\r\n"
+ }
+//****************** write and verify EEPROM ********************
+ if(dim2&&(optWrite==0||optWrite==3)){
+ PrintMessage(strings[S_EEAreaW]); //"Write EEPROM ... "
+ PrintStatusSetup();
+ if(saveLog) fprintf(logfile,"Write EEPROM\n");
+ int errEE=0;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x9E; //EEPGD=0
+ bufferU[j++]=optWrite!=3?0xA6:0x7F;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x9C; //CFGS=0
+ bufferU[j++]=optWrite!=3?0xA6:0x7F;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x84; //WREN=1
+ bufferU[j++]=optWrite!=3?0xA6:0x7F;
+ for(i=0;i<dim2&&err<=max_err;i++){
+ if(memEE[i]!=0xFF){
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E; //MOVLW
+ bufferU[j++]=i&0xFF;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //MOVWF
+ bufferU[j++]=optWrite!=3?0xA9:0x74; //ADDR
+ if(EEalgo==0){
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E; //MOVLW
+ bufferU[j++]=(i>>8)&0xFF;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //MOVWF
+ bufferU[j++]=optWrite!=3?0xAA:0x75; //ADDRH
+ }
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E; //MOVLW
+ bufferU[j++]=memEE[i];
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //MOVWF
+ bufferU[j++]=optWrite!=3?0xA8:0x73; //EEDATA
+ if(EEalgo==1){ //memory unlock
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E; //MOVLW
+ bufferU[j++]=0x55;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //MOVWF
+ bufferU[j++]=0xA7; //EECON2
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E; //MOVLW
+ bufferU[j++]=0xAA;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //MOVWF
+ bufferU[j++]=0xA7; //EECON2
+ }
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x82;
+ bufferU[j++]=optWrite!=3?0xA6:0x7F; //WR=1
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00; //NOP
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00; //NOP
+ bufferU[j++]=WAIT_T3; //write delay
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x80; //RD=1
+ bufferU[j++]=optWrite!=3?0xA6:0x7F;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x50; //MOVF EEDATA,w
+ bufferU[j++]=optWrite!=3?0xA8:0x73;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //MOVWF TABLAT
+ bufferU[j++]=0xF5;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x00; //NOP
+ bufferU[j++]=0x00;
+ bufferU[j++]=SHIFT_TABLAT;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(8);
+ PrintStatus(strings[S_CodeWriting],(i+dim)*100/(dim+dim2),i); //"Writing: %d%%, addr. %03X"
+ if(RWstop) i=dim2;
+ j=0;
+ for(z=DIMBUF-1;z&&!(bufferI[z]==SHIFT_TABLAT&&bufferI[z-1]==CORE_INS);z--);
+ if(z&&memEE[i]!=bufferI[z+1]) errEE++;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,errEE); //"i=%d, k=%d, errors=%d\n"
+ }
+ }
+ }
+ PrintStatusEnd();
+ PrintMessage1(strings[S_ComplErr],errEE); //"completed: %d errors \r\n"
+ err+=errEE;
+ }
+//****************** verify code ********************
+ PrintMessage(strings[S_CodeV]); //"Verify code ... "
+ PrintStatusSetup();
+ if(saveLog)fprintf(logfile,"VERIFY CODE\n");
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x8E; //EEPGD=1
+ bufferU[j++]=optWrite!=3?0xA6:0x7F;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x9C; //CFCGS=0
+ bufferU[j++]=optWrite!=3?0xA6:0x7F;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6A; //CLRF TBLPTRU
+ bufferU[j++]=0xF8; //CLRF TBLPTRU
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6A; //CLRF TBLPTRH
+ bufferU[j++]=0xF7; //CLRF TBLPTRH
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6A; //CLRF TBLPTRL
+ bufferU[j++]=0xF6; //CLRF TBLPTRL
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ if(saveLog){
+ fprintf(logfile,"\n\n");
+ }
+ for(i=0,j=0,k=0;i<dim;i+=DIMBUF-4){
+ i0=i;
+ for(valid=0;!valid&&i<dim;i+=valid?0:DIMBUF-4){ //skip verification if 0xFF
+ for(k2=0;k2<DIMBUF-4&&!valid&&i+k2<dim;k2++) if(memCODE[i+k2]<0xFF) valid=1;
+ }
+ if(i>=dim) break;
+ if(i>i0){ //some data was skipped; update current address
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E;
+ bufferU[j++]=(i>>16)&0xFF;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //MOVWF TBLPTRU
+ bufferU[j++]=0xF8;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E;
+ bufferU[j++]=(i>>8)&0xFF;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //MOVWF TBLPTRH
+ bufferU[j++]=0xF7;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E;
+ bufferU[j++]=i&0xFF;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //MOVWF TBLPTRL
+ bufferU[j++]=0xF6;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ }
+ bufferU[j++]=TBLR_INC_N;
+ bufferU[j++]=i<dim-(DIMBUF-4)?DIMBUF-4:dim-i;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ if(bufferI[1]==TBLR_INC_N){
+ for(z=0;z<bufferI[2]&&z<DIMBUF;z++){
+ if(memCODE[i+z]!=bufferI[z+3]){
+ PrintMessage4(strings[S_CodeVError],i+z,i+z,memCODE[i+z],bufferI[z+3]); //"Error writing address %4X: written %02X, read %02X\r\n"
+ err++;
+ }
+ //k++;
+ }
+ }
+ PrintStatus(strings[S_CodeV2],i*100/(dim+dim2),i); //"Verifica: %d%%, ind. %04X"
+ if(RWstop) i=dim;
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,err); //"i=%d, k=%d, errors=%d\n"
+ }
+ if(err>=max_err) break;
+ }
+ PrintStatusEnd();
+ if(i<dim){
+ PrintMessage2(strings[S_CodeVError2],dim,i); //"Error verifying code area, requested %d bytes, read %d\r\n"
+ }
+ PrintMessage1(strings[S_ComplErr],err); //"completed: %d errors\r\n"
+ if(err>=max_err){
+ PrintMessage1(strings[S_MaxErr],err); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ }
+//****************** verify ID ********************
+ if(programID&&err<max_err&&optWrite==0){
+ PrintMessage(strings[S_IDV]); //"Verify ID ... "
+ int errID=0;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E; //TBLPTRU ID 0x200000
+ bufferU[j++]=0x20; //TBLPTRU ID 0x200000
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //TBLPTRU
+ bufferU[j++]=0xF8; //TBLPTRU
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6A; //CLRF TBLPTRH
+ bufferU[j++]=0xF7; //CLRF TBLPTRH
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6A; //CLRF TBLPTRL
+ bufferU[j++]=0xF6; //CLRF TBLPTRL
+ bufferU[j++]=TBLR_INC_N;
+ bufferU[j++]=8;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ for(z=0;bufferI[z]!=TBLR_INC_N&&z<DIMBUF;z++);
+ for(i=0;i<8;i++) if(memID[i]!=0xFF&&memID[i]!=bufferI[z+i+2]) errID++;
+ PrintMessage1(strings[S_ComplErr],errID); //"completed: %d errors\r\n"
+ err+=errID;
+ if(err>=max_err){
+ PrintMessage1(strings[S_MaxErr],err); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ }
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,0,0,err); //"i=%d, k=%d, errors=%d\n"
+ }
+ }
+//****************** write CONFIG ********************
+ if(err<max_err&&(optWrite==0||optWrite==3)){
+ PrintMessage(strings[S_ConfigW]); //"Write CONFIG ..."
+ if(saveLog) fprintf(logfile,"Write CONFIG\n");
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x8E; //EEPGD=1
+ bufferU[j++]=optWrite!=3?0xA6:0x7F;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x8C; //CFCGS=1
+ bufferU[j++]=optWrite!=3?0xA6:0x7F;
+ bufferU[j++]=CORE_INS; //CONFIG 0x300000
+ bufferU[j++]=0x0E; //MOVLW
+ bufferU[j++]=0x30;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //MOVWF TBLPTRU
+ bufferU[j++]=0xF8; //MOVWF TBLPTRU
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6A; //CLRF TBLPTRH
+ bufferU[j++]=0xF7; //CLRF TBLPTRH
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6A; //CLRF TBLPTRL
+ bufferU[j++]=0xF6; //CLRF TBLPTRL
+ for(i=0;i<14;i++){
+ if(memCONFIG[i]<0xFF){
+ bufferU[j++]=TBLW_PROG;
+ bufferU[j++]=0;
+ bufferU[j++]=memCONFIG[i];
+ bufferU[j++]=5000>>8;
+ bufferU[j++]=5000&0xFF;
+ }
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x2A; //INCF
+ bufferU[j++]=0xF6; //TBLPTRL
+ i++;
+ if(memCONFIG[i]<0xFF){
+ bufferU[j++]=TBLW_PROG;
+ bufferU[j++]=memCONFIG[i];
+ bufferU[j++]=0;
+ bufferU[j++]=5000>>8;
+ bufferU[j++]=5000&0xFF;
+ }
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x2A; //INCF
+ bufferU[j++]=0xF6; //TBLPTRL
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(12);
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,0,0); //"i=%d, k=%d\n"
+ }
+ }
+ PrintMessage(strings[S_Compl]); //"completed\r\n"
+//****************** verify CONFIG ********************
+ PrintMessage(strings[S_ConfigV]); //"Verify CONFIG ... "
+ int errC=0;
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x0E; //TBLPTRU CONFIG 0x300000
+ bufferU[j++]=0x30; //
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6E; //MOVWF TBLPTRU
+ bufferU[j++]=0xF8; //MOVWF TBLPTRU
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6A; //CLRF TBLPTRH
+ bufferU[j++]=0xF7; //CLRF TBLPTRH
+ bufferU[j++]=CORE_INS;
+ bufferU[j++]=0x6A; //CLRF TBLPTRL
+ bufferU[j++]=0xF6; //CLRF TBLPTRL
+ bufferU[j++]=TBLR_INC_N;
+ bufferU[j++]=14;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ for(z=0;bufferI[z]!=TBLR_INC_N&&z<DIMBUF-16;z++);
+ if(z<DIMBUF-16){
+ for(i=0;i<14;i++) if(~memCONFIG[i]&bufferI[z+i+2]) errC++; //error if written 0 and read 1 (~W&R)
+ }
+ PrintMessage1(strings[S_ComplErr],errC); //"completed: %d errors\r\n"
+ err+=errC;
+ if(err>=max_err){
+ PrintMessage1(strings[S_MaxErr],err); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ }
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,0,0,err); //"i=%d, k=%d, errors=%d\n"
+ }
+ }
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2000>>8;
+ bufferU[j++]=2000&0xff;
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=1;
+ bufferU[j++]=EN_VPP_VCC; //0
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(1);
+ unsigned int stop=GetTickCount();
+ sprintf(str,strings[S_EndErr],(stop-start)/1000.0,err,err!=1?strings[S_ErrPlur]:strings[S_ErrSing]); //"\r\nEnd (%.2f s) %d %s\r\n\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+ PrintStatusClear(); //clear status report
+}
+
+#define LOAD_PC_ADDR 0x80
+#define BULK_ERASE 0x18
+#define ROW_ERASE_PROGRAM_MEM 0xF0
+#define LOAD_NVM 0x00
+#define LOAD_NVM_INC 0x02
+#define READ_NVM 0xFC
+#define READ_NVM_INC 0xFE
+#define INC_ADDR8 0xF8
+#define BEGIN_INT_PROG 0xE0
+#define BEGIN_EXT_PROG 0xC0
+#define PROGRAM_DATA 0xC0
+#define PROGRAM_DATA_INC 0xE0
+#define END_EXT_PROG 0x82
+
+void Read18FKx(int dim,int dim2,int options)
+// read 16 bit PIC 18FxxKx3 with new 8b commands
+// dim=program size (bytes)
+// dim2=if>0 use eeprom, size is automatic when reading DCI
+// options:
+// bit [3:0]
+// 0 = vpp before vdd (8.5V)
+// bit [7:4] memory layout
+// code config EE DCI DIA model
+// 0 5 0x310000 0x3FFF00 0x3F0000 K42 K83
+// 1 10 0x380000 0x3C0000 0x2C0000 Q40-43
+// 2 35 0x380000 0x3C0000 0x2C0000 Q83-84
+{
+ int k=0,k2=0,z=0,i,j;
+ int devID=0,devREV=0;
+ int MemAddr;
+ int EEaddr=0,DCIaddr=0,DIAaddr=0,DIAlen=0,UIDlen=0,CONFIGlen=0;
+ int type=(options>>4)&0xF;
+ if(type==0){ //K42 K83
+ EEaddr=0x310000;
+ DCIaddr=0x3FFF00;
+ DIAaddr=0x3F0000;
+ DIAlen=0x40;
+ UIDlen=0x10;
+ CONFIGlen=5;
+ }
+ else if(type==1){ //Q43
+ EEaddr=0x380000;
+ DCIaddr=0x3C0000;
+ DIAaddr=0x2C0000;
+ DIAlen=0x100;
+ UIDlen=0x40;
+ CONFIGlen=10;
+ }
+ else if(type==2){ //Q83-84
+ EEaddr=0x380000;
+ DCIaddr=0x3C0000;
+ DIAaddr=0x2C0000;
+ DIAlen=0x100;
+ UIDlen=0x40;
+ CONFIGlen=35;
+ }
+ else PrintMessage("unexpected parameter");
+ if(dim>0x1FFFFF||dim<0){
+ PrintMessage(strings[S_CodeLim]); //"Code size out of limits\r\n"
+ return;
+ }
+ if(dim2>0x800||dim2<0){
+ PrintMessage(strings[S_EELim]); //"EEPROM size out of limits\r\n"
+ return;
+ }
+ if(!CheckV33Regulator()){
+ PrintMessage(strings[S_noV33reg]); //Can't find 3.3V expansion board
+ return;
+ }
+ double vpp=8.5;
+ if(!StartHVReg(vpp)){
+ PrintMessage(strings[S_HVregErr]); //"HV regulator error\r\n"
+ return;
+ }
+ if(saveLog){
+ OpenLogFile(); //"log.txt"
+ fprintf(logfile,"Read18FKx(%d,%d,%d) (0x%X,0x%X,0x%X)\n",dim,dim2,options,dim,dim2,options);
+ }
+ size=dim;
+ if(memCODE) free(memCODE);
+ memCODE=(unsigned char*)malloc(size); //CODE
+ unsigned char* memDIA=(unsigned char*)malloc(DIAlen); //DIA
+ for(j=0;j<64;j++) memID[j]=0xFF;
+ for(j=0;j<14;j++) memCONFIG[j]=0xFF;
+ for(j=0;j<DIAlen;j++) memDIA[j]=0xFF;
+ unsigned int start=GetTickCount();
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T1T2;
+ bufferU[j++]=2; //T1=2u
+ bufferU[j++]=100; //T2=100u
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2000>>8;
+ bufferU[j++]=2000&0xff;
+ bufferU[j++]=EN_VPP_VCC; //enter program mode
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=EN_VPP_VCC; //VPP
+ bufferU[j++]=0x4;
+ bufferU[j++]=EN_VPP_VCC; //VDD+VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=WAIT_T3;
+ MemAddr=0x3FFFFc<<1; //devREV
+ bufferU[j++]=TX16;
+ bufferU[j++]=2;
+ bufferU[j++]=0x80;
+ bufferU[j++]=MemAddr>>16;
+ bufferU[j++]=(MemAddr>>8)&0xFF;
+ bufferU[j++]=MemAddr&0xFF;
+ bufferU[j++]=ICSP8_READ;
+ bufferU[j++]=READ_NVM_INC;
+ bufferU[j++]=ICSP8_READ;
+ bufferU[j++]=READ_NVM_INC;
+ MemAddr=DCIaddr<<1; //DCI
+ bufferU[j++]=TX16;
+ bufferU[j++]=2;
+ bufferU[j++]=0x80;
+ bufferU[j++]=MemAddr>>16;
+ bufferU[j++]=(MemAddr>>8)&0xFF;
+ bufferU[j++]=MemAddr&0xFF;
+ bufferU[j++]=ICSP8_READ;
+ bufferU[j++]=READ_NVM_INC;
+ bufferU[j++]=ICSP8_READ;
+ bufferU[j++]=READ_NVM_INC;
+ bufferU[j++]=ICSP8_READ;
+ bufferU[j++]=READ_NVM_INC;
+ bufferU[j++]=ICSP8_READ;
+ bufferU[j++]=READ_NVM_INC;
+ bufferU[j++]=ICSP8_READ;
+ bufferU[j++]=READ_NVM_INC;
+ bufferU[j++]=TX16;
+ bufferU[j++]=2;
+ bufferU[j++]=0x80;
+ bufferU[j++]=0x0;
+ bufferU[j++]=0x0;
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(4);
+ for(z=0;bufferI[z]!=ICSP8_READ&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ devREV=(bufferI[z+1]<<8)+bufferI[z+2];
+ }
+ for(z+=3;bufferI[z]!=ICSP8_READ&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ devID=(bufferI[z+1]<<8)+bufferI[z+2];
+ }
+ PrintMessage1("DevID: 0x%04X\r\n",devID);
+ PrintMessage1("RevID: 0x%04X\r\n",devREV);
+ PIC18_ID(devID+(devREV<<16));
+ PrintMessage("Device Configuration Information:\r\n");
+ for(z+=3;bufferI[z]!=ICSP8_READ&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ PrintMessage1("Erase row size: %d\r\n",(bufferI[z+1]<<8)+bufferI[z+2]);
+ }
+ for(z+=3;bufferI[z]!=ICSP8_READ&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ PrintMessage1("Write latches per row: %d\r\n",(bufferI[z+1]<<8)+bufferI[z+2]);
+ }
+ for(z+=3;bufferI[z]!=ICSP8_READ&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ PrintMessage1("User rows: %d\r\n",(bufferI[z+1]<<8)+bufferI[z+2]);
+ }
+ for(z+=3;bufferI[z]!=ICSP8_READ&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ PrintMessage1("EEPROM size: %d\r\n",(bufferI[z+1]<<8)+bufferI[z+2]);
+ sizeEE=(bufferI[z+1]<<8)+bufferI[z+2];
+ }
+ for(z+=3;bufferI[z]!=ICSP8_READ&&z<DIMBUF;z++);
+ if(z<DIMBUF-3){
+ PrintMessage1("Pin count: %d\r\n",(bufferI[z+1]<<8)+bufferI[z+2]);
+ }
+//****************** read code ********************
+ PrintMessage(strings[S_CodeReading1]); //read code ...
+ if(saveLog) fprintf(logfile,"%s\n",strings[S_CodeReading1]); //read code ...
+ PrintStatusSetup();
+ for(i=0,j=0;i<dim;i+=2){ //2 bytes per read
+ bufferU[j++]=ICSP8_READ;
+ bufferU[j++]=READ_NVM_INC;
+ if((j+1)/2*3+3>DIMBUF||i==dim-2){ //2B cmd -> 3B data
+ bufferU[j++]=FLUSH; //remember: FLUSH generates a response (even empty)!
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ for(z=0;z<DIMBUF-2;z++){
+ if(bufferI[z]==ICSP8_READ){
+ memCODE[k++]=bufferI[z+2]; //Low byte
+ memCODE[k++]=bufferI[z+1]; //High byte
+ z+=2;
+ }
+ }
+ PrintStatus(strings[S_CodeReading],(i+sizeEE+10+UIDlen+DIAlen)*100/(dim+sizeEE+10+UIDlen+DIAlen),i); //"Read: %d%%, addr. %03X"
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k,k); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ }
+ }
+ PrintStatusEnd();
+ if(k!=dim){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ReadCodeErr2],dim,k); //"Error reading code area, requested %d bytes, read %d\r\n"
+ }
+ else PrintMessage(strings[S_Compl]);
+//****************** read config area ********************
+ PrintMessage(strings[S_Read_CONFIG_A]); //read config ...
+ if(saveLog) fprintf(logfile,"%s\n",strings[S_Read_CONFIG_A]); //read config ...
+ MemAddr=0x300000<<1; //config area
+ bufferU[j++]=TX16;
+ bufferU[j++]=2;
+ bufferU[j++]=0x80;
+ bufferU[j++]=MemAddr>>16;
+ bufferU[j++]=(MemAddr>>8)&0xFF;
+ bufferU[j++]=MemAddr&0xFF;
+ k2=0;
+ for(i=0;i<CONFIGlen;i++){ //Config
+ bufferU[j++]=ICSP8_READ;
+ bufferU[j++]=READ_NVM_INC;
+ if((j+1)/2*3+3>DIMBUF||i==CONFIGlen-1){ //2B cmd -> 3B data
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ for(z=0;z<DIMBUF-2;z++){
+ if(bufferI[z]==ICSP8_READ){
+ memCONFIG[k2++]=bufferI[z+2]; //LSB
+ if(type==0) memCONFIG[k2++]=bufferI[z+1]; //MSB
+ z+=2;
+ }
+ }
+ PrintStatus(strings[S_CodeReading],(dim+sizeEE+i+UIDlen+DIAlen)*100/(dim+sizeEE+CONFIGlen+UIDlen+DIAlen),i); //"Read: %d%%, addr %03X"
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k2,k2); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ }
+ }
+ if(k2!=10){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ReadConfigErr],10,k2); //"Error reading config area, requested %d bytes, read %d\r\n"
+ }
+ else PrintMessage(strings[S_Compl]);
+//****************** read user ID ********************
+ if(saveLog) fprintf(logfile,"Read user ID\n");
+ MemAddr=0x200000<<1; //user ID
+ bufferU[j++]=TX16;
+ bufferU[j++]=2;
+ bufferU[j++]=0x80;
+ bufferU[j++]=MemAddr>>16;
+ bufferU[j++]=(MemAddr>>8)&0xFF;
+ bufferU[j++]=MemAddr&0xFF;
+ k2=0;
+ for(i=0;i<UIDlen;i+=2){
+ bufferU[j++]=ICSP8_READ;
+ bufferU[j++]=READ_NVM_INC;
+ if((j+1)/2*3+3>DIMBUF||i==UIDlen-2){ //2B cmd -> 3B data
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ for(z=0;z<DIMBUF-2;z++){
+ if(bufferI[z]==ICSP8_READ){
+ memID[k2++]=bufferI[z+2]; //Low byte
+ memID[k2++]=bufferI[z+1]; //High byte
+ z+=2;
+ }
+ }
+ PrintStatus(strings[S_CodeReading],(dim+sizeEE+10+i+DIAlen)*100/(dim+sizeEE+10+UIDlen+DIAlen),i); //"Read: %d%%, addr. %03X"
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k2,k2); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ }
+ }
+ if(k2!=UIDlen){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ReadConfigErr],UIDlen,k2); //"Error reading config area, requested %d bytes, read %d\r\n"
+ }
+//****************** read device info area (DIA) ********************
+ if(saveLog) fprintf(logfile,"Read device info area\n");
+ MemAddr=DIAaddr<<1; //DIA
+ bufferU[j++]=TX16;
+ bufferU[j++]=2;
+ bufferU[j++]=0x80;
+ bufferU[j++]=MemAddr>>16;
+ bufferU[j++]=(MemAddr>>8)&0xFF;
+ bufferU[j++]=MemAddr&0xFF;
+ k2=0;
+ for(i=0;i<DIAlen;i+=2){ //DIA
+ bufferU[j++]=ICSP8_READ;
+ bufferU[j++]=READ_NVM_INC;
+ if((j+1)/2*3+3>DIMBUF||i==DIAlen-2){ //2B cmd -> 3B data
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ for(z=0;z<DIMBUF-2;z++){
+ if(bufferI[z]==ICSP8_READ){
+ memDIA[k2++]=bufferI[z+2];
+ memDIA[k2++]=bufferI[z+1];
+ z+=2;
+ }
+ }
+ PrintStatus(strings[S_CodeReading],(dim+sizeEE+10+UIDlen+i)*100/(dim+sizeEE+10+UIDlen+DIAlen),i); //"Read: %d%%, addr. %03X"
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k2,k2); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ }
+ }
+ if(k2!=DIAlen){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ReadConfigErr],DIAlen,k2); //"Error reading config area, requested %d bytes, read %d\r\n"
+ }
+ //****************** read eeprom ********************
+ if(dim2){ //EEPROM
+ if(sizeEE>0x1000||sizeEE<0){ //Max 4K
+ PrintMessage(strings[S_EELim]); //"EEPROM size exceeds limits\r\n"
+ return;
+ }
+ if(memEE) free(memEE);
+ memEE=(unsigned char*)malloc(sizeEE); //EEPROM
+ for(i=0;i<sizeEE;i++) memEE[i]=0xFF;
+ PrintMessage(strings[S_ReadEE]); //Read EEPROM ...
+ if(saveLog) fprintf(logfile,"%s\n",strings[S_ReadEE]); //Read EEPROM ...
+ MemAddr=EEaddr<<1; //EE base address
+ bufferU[j++]=TX16;
+ bufferU[j++]=2;
+ bufferU[j++]=0x80;
+ bufferU[j++]=MemAddr>>16;
+ bufferU[j++]=(MemAddr>>8)&0xFF;
+ bufferU[j++]=MemAddr&0xFF;
+ for(i=k=0;i<sizeEE;i++){
+ bufferU[j++]=ICSP8_READ;
+ bufferU[j++]=READ_NVM_INC;
+ if((j+1)/2*3+3>DIMBUF||i==sizeEE-1){ //2B cmd -> 3B answer
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ for(z=0;z<DIMBUF-2;z++){
+ if(bufferI[z]==ICSP8_READ){
+ memEE[k++]=bufferI[z+2]; //LSB
+ z+=2;
+ }
+ }
+ PrintStatus(strings[S_CodeReading],(dim+i+10+UIDlen+DIAlen)*100/(dim+sizeEE+10+UIDlen+DIAlen),i); //"Read: %d%%, addr %03X"
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k,k); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ }
+ }
+ PrintStatusEnd();
+ if(k!=sizeEE){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ReadEEErr],sizeEE,k); //"Error reading EE area, ..."
+ }
+ else PrintMessage(strings[S_Compl]);
+ }
+//****************** exit ********************
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=1;
+ bufferU[j++]=EN_VPP_VCC; //0
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(1);
+ unsigned int stop=GetTickCount();
+ PrintStatusClear();
+//****************** visualize ********************
+ PrintMessage(strings[S_ConfigMem]); //"CONFIG"
+ for(i=0;i<UIDlen;i+=2){
+ if(memID[i]<0xFF||memID[i+1]<0xFF) PrintMessage4(strings[S_ChipID2],i,memID[i],i+1,memID[i+1]); //"ID%d: 0x%02X ID%d: 0x%02X\r\n"
+ }
+ if(type==0){ //K42 K83 etc.
+ for(i=0;i<5;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"
+ }
+ }
+ else if(type==1){ //Q43 etc.
+ for(i=0;i<10;i++) PrintMessage2("CONFIG%d: 0x%02X\r\n",i+1,memCONFIG[i]);
+ }
+ PrintMessage(strings[S_CodeMem]); //"\r\nCode memory:\r\n"
+ DisplayCODE18F(dim);
+ if(dim2){
+ DisplayEE(); //visualize
+ }
+ sprintf(str,strings[S_End],(stop-start)/1000.0); //"\r\nEnd (%.2f s)\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+}
+
+void Write18FKx(int dim,int dim2,int options,int nu1,int nu2, int nu3)
+// write 16 bit PIC 18FxxKx3 with new 8b commands
+// dim=program size (bytes) dim2=eeprom size (bytes)
+// options:
+// bit [3:0]
+// 0 = vpp before vdd (8.5V)
+// bit [7:4] memory layout
+// code config EE DCI DIA model program cycle delays ms (E,W,EE)
+// 0 5 0x310000 0x3FFF00 0x3F0000 K42 K83 multiple-word 25.5 2.8 5.6
+// 1 10 0x380000 0x3C0000 0x2C0000 Q40-43 one-word 11 0.075 11
+// 2 35 0x380000 0x3C0000 0x2C0000 Q83-84 one-word 11 0.075 11
+{
+ int k=0,k2,z=0,i,j,x=0,w=0;
+ int err=0;
+ int devID=0,devREV=0;
+ int MemAddr,rowN=0;
+ int EEaddr=0,DCIaddr=0,DIAaddr=0,DIAlen=0,UIDlen=0,CONFIGlen=0;
+ int type=(options>>4)&0xF;
+ if(type==0){ //K42 K83
+ EEaddr=0x310000;
+ DCIaddr=0x3FFF00;
+ DIAaddr=0x3F0000;
+ DIAlen=0x40;
+ UIDlen=0x10;
+ CONFIGlen=5;
+ }
+ else if(type==1){ //Q43
+ EEaddr=0x380000;
+ DCIaddr=0x3C0000;
+ DIAaddr=0x2C0000;
+ DIAlen=0x100;
+ UIDlen=0x40;
+ CONFIGlen=10;
+ }
+ else if(type==2){ //Q83-84
+ EEaddr=0x380000;
+ DCIaddr=0x3C0000;
+ DIAaddr=0x2C0000;
+ DIAlen=0x100;
+ UIDlen=0x40;
+ CONFIGlen=35;
+ }
+ else PrintMessage("unexpected parameter");
+ if(dim>0x1FFFFF||dim<0){
+ PrintMessage(strings[S_CodeLim]); //"Code size out of limits\r\n"
+ return;
+ }
+ if(dim2>0x800||dim2<0){
+ PrintMessage(strings[S_EELim]); //"EEPROM size out of limits\r\n"
+ return;
+ }
+ if(!CheckV33Regulator()){
+ PrintMessage(strings[S_noV33reg]); //Can't find 3.3V expansion board
+ return;
+ }
+ double vpp=8.5;
+ if(!StartHVReg(vpp)){
+ PrintMessage(strings[S_HVregErr]); //"HV regulator error\r\n"
+ return;
+ }
+ if(saveLog){
+ OpenLogFile(); //"log.txt"
+ fprintf(logfile,"Write18FKx(%d,%d,%d) (0x%X,0x%X,0x%X)\n",dim,dim2,options,dim,dim2,options);
+ }
+ if(dim>size) dim=size;
+ if(dim2>sizeEE) dim2=sizeEE;
+ if(dim<1){
+ PrintMessage(strings[S_NoCode]); //"Empty data area\r\n"
+ return;
+ }
+ unsigned int start=GetTickCount();
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T1T2;
+ bufferU[j++]=2; //T1=2u
+ bufferU[j++]=35; //T2 adjusted to obtain ~80us when needed
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=11000>>8;
+ bufferU[j++]=11000&0xff;
+ bufferU[j++]=EN_VPP_VCC; //enter program mode
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=EN_VPP_VCC; //VPP
+ bufferU[j++]=0x4;
+ bufferU[j++]=EN_VPP_VCC; //VDD+VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=WAIT_T3;
+ MemAddr=0x3FFFFc<<1; //devREV
+ bufferU[j++]=TX16;
+ bufferU[j++]=2;
+ bufferU[j++]=0x80;
+ bufferU[j++]=MemAddr>>16;
+ bufferU[j++]=(MemAddr>>8)&0xFF;
+ bufferU[j++]=MemAddr&0xFF;
+ bufferU[j++]=ICSP8_READ;
+ bufferU[j++]=READ_NVM_INC;
+ bufferU[j++]=ICSP8_READ;
+ bufferU[j++]=READ_NVM_INC;
+ MemAddr=DCIaddr<<1; //DCI
+ bufferU[j++]=TX16;
+ bufferU[j++]=2;
+ bufferU[j++]=0x80;
+ bufferU[j++]=MemAddr>>16;
+ bufferU[j++]=(MemAddr>>8)&0xFF;
+ bufferU[j++]=MemAddr&0xFF;
+ bufferU[j++]=ICSP8_READ;
+ bufferU[j++]=READ_NVM_INC;
+ bufferU[j++]=ICSP8_READ;
+ bufferU[j++]=READ_NVM_INC;
+ bufferU[j++]=ICSP8_READ;
+ bufferU[j++]=READ_NVM_INC;
+ bufferU[j++]=ICSP8_READ;
+ bufferU[j++]=READ_NVM_INC;
+ bufferU[j++]=ICSP8_READ;
+ bufferU[j++]=READ_NVM_INC;
+ bufferU[j++]=TX16;
+ bufferU[j++]=2;
+ bufferU[j++]=0x80;
+ bufferU[j++]=0x0;
+ bufferU[j++]=0x0;
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(14);
+ for(z=0;bufferI[z]!=ICSP8_READ&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ devREV=(bufferI[z+1]<<8)+bufferI[z+2];
+ }
+ for(z+=3;bufferI[z]!=ICSP8_READ&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ devID=(bufferI[z+1]<<8)+bufferI[z+2];
+ }
+ PrintMessage1("DevID: 0x%04X\r\n",devID);
+ PrintMessage1("RevID: 0x%04X\r\n",devREV);
+ PIC18_ID(devID+(devREV<<16));
+ PrintMessage("Device Configuration Information:\r\n");
+ for(z+=3;bufferI[z]!=ICSP8_READ&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ PrintMessage1("Erase row size: %d\r\n",(bufferI[z+1]<<8)+bufferI[z+2]);
+ }
+ for(z+=3;bufferI[z]!=ICSP8_READ&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ rowN=(bufferI[z+1]<<8)+bufferI[z+2];
+ PrintMessage1("Write latches per row: %d\r\n",rowN);
+ }
+ for(z+=3;bufferI[z]!=ICSP8_READ&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ PrintMessage1("User rows: %d\r\n",(bufferI[z+1]<<8)+bufferI[z+2]);
+ }
+ for(z+=3;bufferI[z]!=ICSP8_READ&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ PrintMessage1("EEPROM size: %d\r\n",(bufferI[z+1]<<8)+bufferI[z+2]);
+ sizeEE=(bufferI[z+1]<<8)+bufferI[z+2];
+ }
+ for(z+=3;bufferI[z]!=ICSP8_READ&&z<DIMBUF;z++);
+ if(z<DIMBUF-3){
+ PrintMessage1("Pin count: %d\r\n",(bufferI[z+1]<<8)+bufferI[z+2]);
+ }
+ j=0;
+//****************** erase memory ********************
+ PrintMessage(strings[S_StartErase]); //"Erase ... "
+ if(type==0){ //K42 K83
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=25500>>8;
+ bufferU[j++]=25500&0xff;
+ MemAddr=0x300000<<1; //address to erase Flash+User+Config
+ bufferU[j++]=TX16;
+ bufferU[j++]=2;
+ bufferU[j++]=0x80;
+ bufferU[j++]=MemAddr>>16;
+ bufferU[j++]=(MemAddr>>8)&0xFF;
+ bufferU[j++]=MemAddr&0xFF;
+ bufferU[j++]=ICSP8_SHORT;
+ bufferU[j++]=BULK_ERASE;
+ bufferU[j++]=WAIT_T3; //TERAB
+ MemAddr=0x310000<<1; //address to erase EEPROM
+ bufferU[j++]=TX16;
+ bufferU[j++]=2;
+ bufferU[j++]=0x80;
+ bufferU[j++]=MemAddr>>16;
+ bufferU[j++]=(MemAddr>>8)&0xFF;
+ bufferU[j++]=MemAddr&0xFF;
+ bufferU[j++]=ICSP8_SHORT;
+ bufferU[j++]=BULK_ERASE;
+ bufferU[j++]=WAIT_T3; //TERAB
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2800>>8;
+ bufferU[j++]=2800&0xff;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(52);
+ }
+ else if(type==1){ //Q43
+ bufferU[j++]=ICSP8_LOAD;
+ bufferU[j++]=BULK_ERASE;
+ bufferU[j++]=0;
+ bufferU[j++]=0xF;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(1);
+ msDelay(12); //bulk erase delay
+ }
+ PrintMessage(strings[S_Compl]); //"completed\r\n"
+//****************** write code ********************
+ PrintMessage(strings[S_StartCodeProg]); //"code write ... "
+ PrintStatusSetup();
+ if(saveLog){
+ fprintf(logfile,"WRITE CODE\ndim=%d(0x%X)\n",dim,dim); //
+ }
+ if(type==1){ //Q43
+ j=0;
+ bufferU[j++]=TX16;
+ bufferU[j++]=2;
+ bufferU[j++]=0x80;
+ bufferU[j++]=0x0;
+ bufferU[j++]=0x0;
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ for(i=k=0;i<dim;i+=2){
+ if(memCODE[i]<0xFF||memCODE[i+1]<0xFF){
+ bufferU[j++]=ICSP8_LOAD;
+ bufferU[j++]=PROGRAM_DATA;
+ bufferU[j++]=memCODE[i+1]; //High byte
+ bufferU[j++]=memCODE[i]; //Low byte
+ bufferU[j++]=WAIT_T2; //Tprogram 75us
+ bufferU[j++]=ICSP8_READ;
+ bufferU[j++]=READ_NVM_INC;
+ }
+ else{
+ for(x=0;i+x<dim&&memCODE[i+x]==0xFF&&memCODE[i+x+1]==0xFF;x+=2);
+ if(x>9){ //set new address
+ i+=x;
+ MemAddr=i<<1;
+ bufferU[j++]=TX16;
+ bufferU[j++]=2;
+ bufferU[j++]=0x80;
+ bufferU[j++]=MemAddr>>16;
+ bufferU[j++]=(MemAddr>>8)&0xFF;
+ bufferU[j++]=MemAddr&0xFF;
+ i-=2;
+ }
+ else{
+ bufferU[j++]=ICSP8_SHORT;
+ bufferU[j++]=INC_ADDR8;
+ }
+ }
+ if(j>DIMBUF-8||i==dim-2){
+ PrintStatus(strings[S_CodeWriting],i*100/(dim+dim2),i); //"Writing: %d%%, add. %03X"
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ for(z=0;z<DIMBUF-4;z++){
+ if(bufferI[z]==ICSP8_SHORT&&memCODE[k]==0xff&&memCODE[k+1]==0xff) k+=2;
+ else if(bufferI[z]==TX16){ //need to find the next valid address
+ for(;k<dim&&memCODE[k]==0xFF&&memCODE[k+1]==0xFF;k+=2);
+ }
+ else if(bufferI[z]==ICSP8_LOAD&&bufferI[z+2]==ICSP8_READ){
+ if(memCODE[k]!=bufferI[z+4]||memCODE[k+1]!=bufferI[z+3]){
+ PrintMessage("\r\n");
+ PrintMessage3(strings[S_CodeWError2],k,(memCODE[k+1]<<8)+memCODE[k],(bufferI[z+3]<<8)+bufferI[z+4]); //"Error writing address %3X: written %04X, read %04X\r\n"
+ err++;
+ if(max_err&&err>max_err){
+ PrintMessage1(strings[S_MaxErr],err); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ i=dim;
+ z=DIMBUF;
+ }
+ }
+ k+=2;
+ z+=4;
+ }
+ }
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,err); //"i=%d, k=%d, errors=%d,\n"
+ }
+ }
+ }
+ err+=i-k;
+ }
+ else if(type==0){ //K42 K83
+ int valid;
+ for(;dim>0&&memCODE[dim-1]==0xff&&memCODE[dim-2]==0xff;dim-=2); //skip empty space at end
+ if(dim%rowN) dim+=rowN-dim%rowN; //grow to N byte multiple
+ if(dim>size){
+ memCODE=(unsigned char*)realloc(memCODE,dim);
+ for(;size<dim;size++) memCODE[size]=0xFF;
+ }
+ for(i=k=0,j=0;i<dim;i+=rowN){
+ for(valid=0;i<dim&&!valid;i+=valid?0:rowN){ //skip empty locations (N words)
+ valid=0;
+ for(k=0;k<rowN;k++){ //check row
+ if(memCODE[i+k]<0xff){
+ valid=1;
+ k=rowN;
+ }
+ }
+ }
+ MemAddr=i<<1;
+ bufferU[j++]=TX16; //load new address
+ bufferU[j++]=2;
+ bufferU[j++]=0x80;
+ bufferU[j++]=MemAddr>>16;
+ bufferU[j++]=(MemAddr>>8)&0xFF;
+ bufferU[j++]=MemAddr&0xFF;
+ for(k=0;k<rowN;k+=2){ //load all latches
+ bufferU[j++]=ICSP8_LOAD;
+ bufferU[j++]=k<(rowN-2)?LOAD_NVM_INC:LOAD_NVM;
+ bufferU[j++]=memCODE[i+k+1]; //High byte
+ bufferU[j++]=memCODE[i+k]; //Low byte
+ if(j>DIMBUF-5){
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ }
+ }
+ if(i<dim){
+ bufferU[j++]=ICSP8_SHORT;
+ bufferU[j++]=BEGIN_INT_PROG; //internally timed, T=2.8ms
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(6);
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,0,0); //"i=%d, k=%d 0=%d\n"
+ }
+ PrintStatus(strings[S_CodeWriting],i*100/(dim*2+dim2),i); //"Writing: %d%%, addr. %03X"
+ }
+ }
+ PrintStatusEnd();
+ PrintMessage(strings[S_Compl]); //"completed\r\n"
+ //****************** verify code ********************
+ PrintMessage(strings[S_CodeV]); //"Verifying code ... "
+ PrintStatusSetup();
+ if(saveLog) fprintf(logfile,"%s\n",strings[S_CodeV]);
+ j=0;
+ bufferU[j++]=TX16;
+ bufferU[j++]=2;
+ bufferU[j++]=0x80;
+ bufferU[j++]=0x0;
+ bufferU[j++]=0x0;
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ for(i=k=0;i<dim;i+=2){
+ if(j==0){ //skip empty locations (only at the beginning of a packet)
+ for(x=0;i+x<dim&&memCODE[i+x]==0xFF&&memCODE[i+x+1]==0xFF;x+=2);
+ if(x>9){ //set new address
+ i+=x;
+ k=i;
+ MemAddr=i<<1;
+ bufferU[j++]=TX16;
+ bufferU[j++]=2;
+ bufferU[j++]=0x80;
+ bufferU[j++]=MemAddr>>16;
+ bufferU[j++]=(MemAddr>>8)&0xFF;
+ bufferU[j++]=MemAddr&0xFF;
+ }
+ }
+ bufferU[j++]=ICSP8_READ;
+ bufferU[j++]=READ_NVM_INC;
+ if((j+1)/2*3+3>DIMBUF||i==dim-2){ //2B cmd -> 3B data
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ for(z=0;z<DIMBUF-2;z++){
+ if(bufferI[z]==ICSP8_READ){
+ if(memCODE[k]!=bufferI[z+2]||memCODE[k+1]!=bufferI[z+1]){
+ PrintMessage3(strings[S_CodeWError2],k,memCODE[k]+(memCODE[k+1]<<8),(bufferI[z+1]<<8)+bufferI[z+2]); //"Error writing address %3X: written %04X, read %04X\r\n"
+ err++;
+ }
+ z+=2;
+ k+=2;
+ }
+ }
+ PrintStatus(strings[S_CodeV2],(i+dim)/(dim*2+dim2)*100,i); //"Verify: %d%%, addr. %04X"
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,err); //"i=%d, k=%d, errors=%d\n"
+ }
+ if(err>=max_err){
+ PrintMessage1(strings[S_MaxErr],err); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ i=dim;
+ }
+ }
+ }
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=5600>>8;
+ bufferU[j++]=5600&0xff;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(1);
+ j=0;
+ }
+ PrintStatusEnd();
+ PrintMessage1(strings[S_ComplErr],err); //"completed, %d errors\r\n"
+//****************** write and verify EEPROM ********************
+ if(dim2){
+ PrintMessage(strings[S_EEAreaW]); //"Write EEPROM ... "
+ PrintStatusSetup();
+ if(saveLog) fprintf(logfile,"WRITE EEPROM\ndim2=%d(0x%X)\n",dim2,dim2);
+ int errEE=0;
+ j=0;
+ MemAddr=EEaddr<<1;
+ bufferU[j++]=TX16;
+ bufferU[j++]=2;
+ bufferU[j++]=0x80;
+ bufferU[j++]=MemAddr>>16;
+ bufferU[j++]=(MemAddr>>8)&0xFF;
+ bufferU[j++]=MemAddr&0xFF;
+ for(i=k=0;i<dim2;i++){
+ if(memEE[i]<0xFF){
+ if(type==1){ //Q43
+ bufferU[j++]=ICSP8_LOAD;
+ bufferU[j++]=PROGRAM_DATA;
+ bufferU[j++]=0;
+ bufferU[j++]=memEE[i];
+ }
+ else if(type==0){ //K42 K83
+ bufferU[j++]=ICSP8_LOAD;
+ bufferU[j++]=LOAD_NVM;
+ bufferU[j++]=0; //High byte
+ bufferU[j++]=memEE[i]; //Low byte
+ bufferU[j++]=ICSP8_SHORT;
+ bufferU[j++]=BEGIN_INT_PROG; //internally timed
+ }
+ bufferU[j++]=WAIT_T3; //Tprogram 11ms or 5.6ms
+ bufferU[j++]=ICSP8_READ;
+ bufferU[j++]=READ_NVM_INC;
+ w++;
+ }
+ else{
+ bufferU[j++]=ICSP8_SHORT;
+ bufferU[j++]=INC_ADDR8;
+ }
+ if(j>DIMBUF-8||i==dim2-1){
+ PrintStatus(strings[S_CodeWriting],(i+dim)*100/(dim+dim2),i+EEaddr); //"Writing: %d%%, addr. %03X"
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ w*=type==1?11:5.6; //total write time
+ PacketIO(w+10);
+ for(z=0;z<DIMBUF-4;z++){
+ if(bufferI[z]==ICSP8_SHORT&&memEE[k]==0xff) k++;
+ else if(bufferI[z]==ICSP8_LOAD){
+ w=type==1?bufferI[z+4]:bufferI[z+5];
+ if(memEE[k]!=w){
+ PrintMessage("\r\n");
+ PrintMessage3(strings[S_CodeWError2],k,memEE[k],w); //"Error writing address %3X: written %04X, read %04X\r\n"
+ errEE++;
+ if(max_err&&err+errEE>max_err){
+ PrintMessage1(strings[S_MaxErr],err+errEE); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ PrintMessage(strings[S_IntW]); //"Write interrupted"
+ i=dim2;
+ z=DIMBUF;
+ }
+ }
+ k++;
+ z+=type==1?4:5;
+ }
+ }
+ j=0;
+ w=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,errEE); //"i=%d, k=%d, errors=%d,\n"
+ }
+ }
+ }
+ errEE+=i-k;
+ err+=errEE;
+ PrintStatusEnd();
+ PrintMessage1(strings[S_ComplErr],errEE); //"completed, %d errors\r\n"
+ }
+//****************** write and verify ID ********************
+ #define IDaddr 0x200000
+ if(programID){
+ PrintMessage(strings[S_IDW]); //"Write ID ... "
+ if(saveLog) fprintf(logfile,"Write ID\n");
+ int errID=0;
+ j=0;
+ MemAddr=IDaddr<<1;
+ bufferU[j++]=TX16;
+ bufferU[j++]=2;
+ bufferU[j++]=0x80;
+ bufferU[j++]=MemAddr>>16;
+ bufferU[j++]=(MemAddr>>8)&0xFF;
+ bufferU[j++]=MemAddr&0xFF;
+ for(i=k=0;i<UIDlen;i+=2){
+ if(memID[i]<0xFF||memID[i+1]<0xFF){
+ if(type==1){ //Q43
+ bufferU[j++]=ICSP8_LOAD;
+ bufferU[j++]=PROGRAM_DATA;
+ bufferU[j++]=memID[i+1];
+ bufferU[j++]=memID[i];
+ }
+ else if(type==0){ //K42 K83
+ bufferU[j++]=ICSP8_LOAD;
+ bufferU[j++]=LOAD_NVM;
+ bufferU[j++]=memID[i+1];
+ bufferU[j++]=memID[i];
+ bufferU[j++]=ICSP8_SHORT;
+ bufferU[j++]=BEGIN_INT_PROG; //internally timed
+ }
+ bufferU[j++]=WAIT_T3; //Tprogram 11ms or 5.6ms
+ bufferU[j++]=ICSP8_READ;
+ bufferU[j++]=READ_NVM_INC;
+ }
+ else{
+ bufferU[j++]=ICSP8_SHORT;
+ bufferU[j++]=INC_ADDR8;
+ }
+ if(j>DIMBUF-8||i==UIDlen-2){
+ PrintStatus(strings[S_CodeWriting],99,IDaddr+i); //"Writing: %d%%, add. %03X"
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(80);
+ for(z=0;z<DIMBUF-4;z++){
+ if(bufferI[z]==ICSP8_SHORT&&memID[k]==0xff&&memID[k+1]==0xff) k+=2;
+ else if(bufferI[z]==ICSP8_LOAD){
+ if(type==1) w=(bufferI[z+3]<<8)+bufferI[z+4];
+ else if(type==0) w=(bufferI[z+4]<<8)+bufferI[z+5];
+ x=(memID[k+1]<<8)+memID[k];
+ if(x!=w){
+ PrintMessage("\r\n");
+ PrintMessage3(strings[S_CodeWError2],k,x,w); //"Error writing address %3X: written %04X, read %04X\r\n"
+ errID++;
+ if(max_err&&err+errID>max_err){
+ PrintMessage1(strings[S_MaxErr],err+errID); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ PrintMessage(strings[S_IntW]); //"Write interrupted"
+ i=UIDlen;
+ z=DIMBUF;
+ }
+ }
+ k+=2;
+ z+=type==1?4:5;
+ }
+ }
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,errID); //"i=%d, k=%d, errors=%d,\n"
+ }
+ }
+ }
+ errID+=i-k;
+ err+=errID;
+ PrintStatusEnd();
+ PrintMessage1(strings[S_ComplErr],errID); //"completed, %d errors\r\n"
+ }
+//****************** write and verify CONFIG ********************
+ #define CONFIGaddr 0x300000
+ if(err<max_err){
+ PrintMessage(strings[S_ConfigW]); //"Write CONFIG ..."
+ if(saveLog) fprintf(logfile,"Write CONFIG\n");
+ int errC=0;
+ j=0;
+ MemAddr=CONFIGaddr<<1;
+ bufferU[j++]=TX16;
+ bufferU[j++]=2;
+ bufferU[j++]=0x80;
+ bufferU[j++]=MemAddr>>16;
+ bufferU[j++]=(MemAddr>>8)&0xFF;
+ bufferU[j++]=MemAddr&0xFF;
+ for(i=k=0;i<CONFIGlen;i++){
+ if(type==1){ //Q43
+ bufferU[j++]=ICSP8_LOAD;
+ bufferU[j++]=PROGRAM_DATA;
+ bufferU[j++]=0;
+ bufferU[j++]=memCONFIG[i];
+ }
+ else if(type==0){ //K42 K83
+ bufferU[j++]=ICSP8_LOAD;
+ bufferU[j++]=LOAD_NVM;
+ bufferU[j++]=memCONFIG[i*2+1]; //High byte
+ bufferU[j++]=memCONFIG[i*2]; //Low byte
+ bufferU[j++]=ICSP8_SHORT;
+ bufferU[j++]=BEGIN_INT_PROG; //internally timed
+ }
+ bufferU[j++]=WAIT_T3; //Tprogram 11ms or 5.6ms
+ bufferU[j++]=ICSP8_READ;
+ bufferU[j++]=READ_NVM_INC;
+ if(j>DIMBUF-8||i==CONFIGlen-1){
+ PrintStatus(strings[S_CodeWriting],99,i+CONFIGaddr); //"Writing: %d%%, addr. %03X"
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(80);
+ for(z=0;z<DIMBUF-4;z++){
+ if(bufferI[z]==ICSP8_LOAD){
+ if(type==1){ //Q43 single byte
+ w=bufferI[z+4];
+ x=memCONFIG[k];
+ }
+ else if(type==0){ //K42 K83 2 bytes
+ w=(bufferI[z+4]<<8)+bufferI[z+5];
+ x=(memCONFIG[k+1]<<8)+memCONFIG[k];
+ }
+ if(~x&w){ //error if written 0 and read 1 (~Written&Read)
+ PrintMessage("\r\n");
+ PrintMessage3(strings[S_CodeWError2],k+CONFIGaddr,x,w); //"Error writing address %3X: written %04X, read %04X\r\n"
+ errC++;
+ if(max_err&&err+errC>max_err){
+ PrintMessage1(strings[S_MaxErr],err+errC); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ PrintMessage(strings[S_IntW]); //"Write interrupted"
+ i=dim2;
+ z=DIMBUF;
+ }
+ }
+ if(type==1){ //Q43 single byte
+ k++;
+ z+=4;
+ }
+ else if(type==0){ //K42 K83 2 bytes
+ k+=2;
+ z+=5;
+ }
+ }
+ }
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i,i,k,k,errC); //"i=%d, k=%d, errors=%d,\n"
+ }
+ }
+ }
+ errC+=10-k;
+ err+=errC;
+ PrintStatusEnd();
+ PrintMessage1(strings[S_ComplErr],errC); //"completed, %d errors\r\n"
+ }
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=1;
+ bufferU[j++]=EN_VPP_VCC; //0
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(1);
+ unsigned int stop=GetTickCount();
+ sprintf(str,strings[S_EndErr],(stop-start)/1000.0,err,err!=1?strings[S_ErrPlur]:strings[S_ErrSing]); //"\r\nEnd (%.2f s) %d %s\r\n\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+ PrintStatusClear(); //clear status report
+}
+
+
diff --git a/progP18.h b/progP18.h
new file mode 100644
index 0000000..c937bfe
--- /dev/null
+++ b/progP18.h
@@ -0,0 +1,6 @@
+void Read18Fx(int dim,int dim2,int options);
+void Read18FKx(int dim,int dim2,int options);
+void Write18Fx(int dim,int dim2,int wbuf,int eraseW1,int eraseW2,int options);
+void Write18FKx(int dim,int dim2,int options,int nu1,int nu2, int nu3);
+void DisplayCODE18F(int dim);
+
diff --git a/progP24.c b/progP24.c
new file mode 100644
index 0000000..435b931
--- /dev/null
+++ b/progP24.c
@@ -0,0 +1,3917 @@
+/**
+ * \file progP24F.c - algorithms to program the PIC24 family of microcontrollers
+ * Copyright (C) 2009-2021 Alberto Maccioni
+ *
+ * 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/>
+ */
+
+/*
+ ICSP Code(KWord) EE(B) Config Code_er Row Row_wr EE_er EE_wr Conf_wr wr_seq
+24F0xKAxxx HV|LV 1.375-5.5 512 00-10(8b) 4064 32 4004 4050 4004 4004 NO
+24FJxxGA0xx LV 5.5-44 NO Code-2(16b) 404F 64 4001 - - 4003 NO
+24FJxxGA1x/GB0x LV 11-22 NO Code-4(16b) 404F 64 4001 - - 4003 NO
+xDA/GB2/GA3/GC " 22-87 " " "
+(new TABLPAG)
+24FJxxGB1x LV 22-87 NO Code-3(16b) 404F 64 4001 - - 4003 NO
+24HJ-33FJ LV 2-88 NO 00-12/16(8b) 404F 64 4001 - - 4000 NO
+24E-33E LV 11-88 NO Code-20(8b) 400F 2 4001 - - 4001 55-AA
+(new TABLPAG, new algorithm)
+30Fxx10-16 HV2 4-48 0-4K 00-0C(16b) 407F 32 4001 seq. 4004 4008 55-AA
+30F2020-23 LV5V 2-4 NO 00-0E(16b) 407F 32 4001 - - 4008 55-AA
+
+*/
+
+#include "common.h"
+
+void CheckData(int a,int b,int addr,int *err)
+{
+ if(a!=b){
+#ifdef _MSC_VER
+ CString str;
+#endif
+ PrintMessage(strings[S_NL]);
+ PrintMessage4(strings[S_CodeVError],addr,addr,a,b); //"Error writing address %4X: written %02X, read %02X\r\n"
+ (*err)++;
+ }
+}
+
+struct ID24{
+ int id;
+ char *device;
+} PIC24LIST[]={
+ {0x0040,"30F2010"},
+ {0x0041,"24HJ64GP206"},
+ {0x0047,"24HJ64GP210"},
+ {0x0049,"24HJ64GP506"},
+ {0x004B,"24HJ64GP510"},
+ {0x005D,"24HJ128GP206"},
+ {0x005F,"24HJ128GP210"},
+ {0x0061,"24HJ128GP506"},
+ {0x0063,"24HJ128GP510"},
+ {0x0065,"24HJ128GP306"},
+ {0x0067,"24HJ128GP310"},
+ {0x0071,"24HJ256GP206"},
+ {0x0073,"24HJ256GP210"},
+ {0x007B,"24HJ256GP610"},
+ {0x0080,"30F5011"},
+ {0x0081,"30F5013"},
+ {0x0089,"33FJ64MC506"},
+ {0x008A,"33FJ64MC508"},
+ {0x008B,"33FJ64MC510"},
+ {0x0091,"33FJ64MC706"},
+ {0x0097,"33FJ64MC710"},
+ {0x00A1,"33FJ128MC506"},
+ {0x00A3,"33FJ128MC510"},
+ {0x00A9,"33FJ128MC706"},
+ {0x00AE,"33FJ128MC708"},
+ {0x00AF,"33FJ128MC710"},
+ {0x00B7,"33FJ256MC510"},
+ {0x00BF,"33FJ256MC710"},
+ {0x00C1,"30F3012/33FJ64GP206"},
+ {0x00C3,"30F3013"},
+ {0x00CD,"33FJ64GP306"},
+ {0x00CF,"33FJ64GP310"},
+ {0x00D5,"33FJ64GP706"},
+ {0x00D6,"33FJ64GP708"},
+ {0x00D7,"33FJ64GP710"},
+ {0x00D9,"33FJ128GP206"},
+ {0x00E5,"33FJ128GP306"},
+ {0x00E7,"33FJ128GP310"},
+ {0x00ED,"33FJ128GP706"},
+ {0x00EE,"33FJ128GP708"},
+ {0x00EF,"33FJ128GP710"},
+ {0x00F5,"33FJ256GP506"},
+ {0x00F7,"33FJ256GP510"},
+ {0x00FF,"33FJ256GP710"},
+ {0x0100,"30F4012"},
+ {0x0101,"30F4011"},
+ {0x0141,"30F4013"},
+ {0x0160,"30F3014"},
+ {0x0188,"30F6010"},
+ {0x0192,"30F6011"},
+ {0x0193,"30F6012"},
+ {0x0197,"30F6013"},
+ {0x0198,"30F6014"},
+ {0x01C0,"30F3010"},
+ {0x01C1,"30F3011"},
+ {0x0200,"30F5015"},
+ {0x0201,"30F5016"},
+ {0x0240,"30F2011"},
+ {0x0241,"30F2012"},
+ {0x0280,"30F6015"},
+ {0x0281,"30F6010A"},
+ {0x02C0,"30F6011A"},
+ {0x02C1,"30F6013A"},
+ {0x02C2,"30F6012A"},
+ {0x02C3,"30F6014A"},
+ {0x0400,"30F2020"},
+ {0x0403,"30F2023"},
+ {0x0404,"30F1010"},
+ {0x0405,"24FJ64GA006"},
+ {0x0406,"24FJ96GA006"},
+ {0x0407,"24FJ128GA006"},
+ {0x0408,"24FJ64GA008"},
+ {0x0409,"24FJ96GA008"},
+ {0x040A,"24FJ128GA008"},
+ {0x040B,"24FJ64GA010"},
+ {0x040C,"24FJ96GA010"},
+ {0x040D,"24FJ128GA010"},
+ {0x0444,"24FJ16GA002"},
+ {0x0445,"24FJ32GA002"},
+ {0x0446,"24FJ48GA002"},
+ {0x0447,"24FJ64GA002"},
+ {0x044C,"24FJ16GA004"},
+ {0x044D,"24FJ32GA004"},
+ {0x044E,"24FJ48GA004"},
+ {0x044F,"24FJ64GA004"},
+ {0x0601,"33FJ32MC302"},
+ {0x0603,"33FJ32MC304"},
+ {0x0605,"33FJ32GP302"},
+ {0x0607,"33FJ32GP304"},
+ {0x0611,"33FJ64MC202"},
+ {0x0613,"33FJ64MC204"},
+ {0x0615,"33FJ64GP202"},
+ {0x0617,"33FJ64GP204"},
+ {0x0619,"33FJ64MC802"},
+ {0x061B,"33FJ64MC804"},
+ {0x061D,"33FJ64GP802"},
+ {0x061F,"33FJ64GP804"},
+ {0x0621,"33FJ128MC202"},
+ {0x0623,"33FJ128MC204"},
+ {0x0625,"33FJ128GP202"},
+ {0x0627,"33FJ128GP204"},
+ {0x0629,"33FJ128MC802"},
+ {0x062B,"33FJ128MC804"},
+ {0x062D,"33FJ128GP802"},
+ {0x062F,"33FJ128GP804"},
+ {0x0645,"24HJ32GP302"},
+ {0x0647,"24HJ32GP304"},
+ {0x0655,"24HJ64GP202"},
+ {0x0657,"24HJ64GP204"},
+ {0x0665,"24HJ128GP202"},
+ {0x0667,"24HJ128GP204"},
+ {0x0675,"24HJ64GP502"},
+ {0x0677,"24HJ64GP504"},
+ {0x067D,"24HJ128GP502"},
+ {0x067F,"24HJ128GP504"},
+ {0x0771,"24HJ256GP206A"},
+ {0x0773,"24HJ256GP210A"},
+ {0x077B,"24HJ256GP610A"},
+ {0x07B7,"33FJ256MC510A"},
+ {0x07BF,"33FJ256MC710A"},
+ {0x07F5,"33FJ256GP506A"},
+ {0x07F7,"33FJ256GP510A"},
+ {0x07FF,"33FJ256GP710A"},
+ {0x0800,"33FJ12MC201"},
+ {0x0801,"33FJ12MC202"},
+ {0x0802,"33FJ12GP201"},
+ {0x0803,"33FJ12GP202"},
+ {0x080A,"24HJ12GP201"},
+ {0x080B,"24HJ12GP202"},
+ {0x0C00,"33FJ06GS101"},
+ {0x0C01,"33FJ06GS102"},
+ {0x0C02,"33FJ06GS202"},
+ {0x0C03,"33FJ16GS502"},
+ {0x0C04,"33FJ16GS402"},
+ {0x0C05,"33FJ16GS504"},
+ {0x0C06,"33FJ16GS404"},
+ {0x0D00,"24F04KA201"},
+ {0x0D01,"24F16KA101"},
+ {0x0D02,"24F04KA200"},
+ {0x0D03,"24F16KA102"},
+ {0x0D08,"24F08KA101"},
+ {0x0D0A,"24F08KA102"},
+ {0x0F03,"33FJ16MC304"},
+ {0x0F07,"33FJ16GP304"},
+ {0x0F09,"33FJ32MC202"},
+ {0x0F0B,"33FJ32MC204"},
+ {0x0F0D,"33FJ32GP202"},
+ {0x0F0F,"33FJ32GP204"},
+ {0x0F17,"24HJ16GP304"},
+ {0x0F1D,"24HJ32GP202"},
+ {0x0F1F,"24HJ32GP204"},
+ {0x1001,"24FJ64GB106"},
+ {0x1003,"24FJ64GB108"},
+ {0x1007,"24FJ64GB110"},
+ {0x1008,"24FJ128GA106"},
+ {0x1009,"24FJ128GB106"},
+ {0x100A,"24FJ128GA100"},
+ {0x100B,"24FJ128GB108"},
+ {0x100E,"24FJ128GA110"},
+ {0x100F,"24FJ128GB110"},
+ {0x1010,"24FJ192GA106"},
+ {0x1011,"24FJ192GB106"},
+ {0x1012,"24FJ192GA108"},
+ {0x1013,"24FJ192GB108"},
+ {0x1016,"24FJ192GA110"},
+ {0x1017,"24FJ192GB110"},
+ {0x1018,"24FJ256GA106"},
+ {0x1019,"24FJ256GB106"},
+ {0x101A,"24FJ256GA108"},
+ {0x101B,"24FJ256GB108"},
+ {0x101E,"24FJ256GA110"},
+ {0x101F,"24FJ256GB110"},
+ {0x1780,"33EP512MC204"},
+ {0x1781,"33EP512MC202"},
+ {0x1783,"33EP512MC206"},
+ {0x1784,"33EP512MC504"},
+ {0x1785,"33EP512MC502"},
+ {0x1787,"33EP512MC506"},
+ {0x178F,"33EP512GP506"},
+ {0x1790,"24EP512MC204"},
+ {0x1791,"24EP512MC202"},
+ {0x1793,"24EP512MC206"},
+ {0x1798,"24EP512GP204"},
+ {0x1799,"24EP512GP202"},
+ {0x179B,"24EP512GP206"},
+ {0x178C,"33EP512GP504"},
+ {0x178D,"33EP512GP502"},
+ {0x1C00,"33EP32MC204"},
+ {0x1C01,"33EP32MC202"},
+ {0x1C02,"33EP32MC203"},
+ {0x1C04,"33EP32MC504"},
+ {0x1C05,"33EP32MC502"},
+ {0x1C06,"33EP32MC503"},
+ {0x1C0C,"33EP32GP504"},
+ {0x1C0D,"33EP32GP502"},
+ {0x1C0E,"33EP32GP503"},
+ {0x1C10,"24EP32MC204"},
+ {0x1C11,"24EP32MC202"},
+ {0x1C12,"24EP32MC203"},
+ {0x1C18,"24EP32GP204"},
+ {0x1C19,"24EP32GP202"},
+ {0x1C1A,"24EP32GP203"},
+ {0x1D20,"33EP64MC204"},
+ {0x1D21,"33EP64MC202"},
+ {0x1D22,"33EP64MC203"},
+ {0x1D23,"33EP64MC206"},
+ {0x1D24,"33EP64MC504"},
+ {0x1D25,"33EP64MC502"},
+ {0x1D26,"33EP64MC503"},
+ {0x1D27,"33EP64MC506"},
+ {0x1D2C,"33EP64GP504"},
+ {0x1D2D,"33EP64GP502"},
+ {0x1D2E,"33EP64GP503"},
+ {0x1D2F,"33EP64GP506"},
+ {0x1D30,"24EP64MC204"},
+ {0x1D31,"24EP64MC202"},
+ {0x1D32,"24EP64MC203"},
+ {0x1D33,"24EP64MC206"},
+ {0x1D38,"24EP64GP204"},
+ {0x1D39,"24EP64GP202"},
+ {0x1D3A,"24EP64GP203"},
+ {0x1D3B,"24EP64GP206"},
+ {0x1E40,"33EP128MC204"},
+ {0x1E41,"33EP128MC202"},
+ {0x1E43,"33EP128MC206"},
+ {0x1E44,"33EP128MC504"},
+ {0x1E45,"33EP128MC502"},
+ {0x1E47,"33EP128MC506"},
+ {0x1E4C,"33EP128GP504"},
+ {0x1E4D,"33EP128GP502"},
+ {0x1E4F,"33EP128GP506"},
+ {0x1E50,"24EP128MC204"},
+ {0x1E51,"24EP128MC202"},
+ {0x1E53,"24EP128MC206"},
+ {0x1E58,"24EP128GP204"},
+ {0x1E59,"24EP128GP202"},
+ {0x1E5B,"24EP128GP206"},
+ {0x1F60,"33EP256MC204"},
+ {0x1F61,"33EP256MC202"},
+ {0x1F63,"33EP256MC206"},
+ {0x1F64,"33EP256MC504"},
+ {0x1F65,"33EP256MC502"},
+ {0x1F67,"33EP256MC506"},
+ {0x1F6C,"33EP256GP504"},
+ {0x1F6D,"33EP256GP502"},
+ {0x1F6F,"33EP256GP506"},
+ {0x1F70,"24EP256MC204"},
+ {0x1F71,"24EP256MC202"},
+ {0x1F73,"24EP256MC206"},
+ {0x1F78,"24EP256GP204"},
+ {0x1F79,"24EP256GP202"},
+ {0x1F7B,"24EP256GP206"},
+ {0x4000,"33FJ32GS406"},
+ {0x4001,"33FJ64GS406"},
+ {0x4002,"33FJ32GS606"},
+ {0x4003,"33FJ64GS606"},
+ {0x4004,"33FJ32GS608"},
+ {0x4005,"33FJ64GS608"},
+ {0x4008,"33FJ32GS610"},
+ {0x4009,"33FJ64GS610"},
+ {0x4100,"24FJ128GB206"},
+ {0x4102,"24FJ128GB210"},
+ {0x4104,"24FJ256GB206"},
+ {0x4106,"24FJ256GB210"},
+ {0x4108,"24FJ128DA206"},
+ {0x4109,"24FJ128DA106"},
+ {0x410A,"24FJ128DA210"},
+ {0x410B,"24FJ128DA110"},
+ {0x410C,"24FJ256DA206"},
+ {0x410D,"24FJ256DA106"},
+ {0x410E,"24FJ256DA210"},
+ {0x410F,"24FJ256DA110"},
+ {0x4202,"24FJ32GA102"},
+ {0x4203,"24FJ32GB002"},
+ {0x4206,"24FJ64GA102"},
+ {0x4207,"24FJ64GB002"},
+ {0x420A,"24FJ32GA104"},
+ {0x420B,"24FJ32GB004"},
+ {0x420E,"24FJ64GA104"},
+ {0x420F,"24FJ64GB004"},
+ {0x46C0,"24FJ64GA306"},
+ {0x46C2,"24FJ128GA306"},
+ {0x46C4,"24FJ64GA308"},
+ {0x46C6,"24FJ128GA308"},
+ {0x46C8,"24FJ64GA310"},
+ {0x46CA,"24FJ128GA310"},
+ {0x4884,"24FJ64GC010"},
+ {0x4885,"24FJ128GC010"},
+ {0x4888,"24FJ64GC006"},
+ {0x4889,"24FJ128GC006"},
+ {0x488A,"24FJ64GC008"},
+ {0x488B,"24FJ128GC008"},
+};
+
+void PIC24_ID(int id)
+{
+ char s[64];
+ int i;
+ for(i=0;i<sizeof(PIC24LIST)/sizeof(PIC24LIST[0]);i++){
+ if(id==PIC24LIST[i].id){
+ strcpy(s,PIC24LIST[i].device);
+ strcat(s,"\r\n");
+ PrintMessage(s);
+ return;
+ }
+ }
+ PrintMessage(strings[S_nodev]); //"Unknown device\r\n");
+}
+
+void DisplayCODE24F(int dim){
+// display 16 bit PIC CODE memory
+ char s[256]="",t[256]="";
+ char* aux=(char*)malloc((dim/COL+1)*2*(16+COL*9));
+ aux[0]=0;
+ int valid=0,empty=1,i,j,d,lines=0;
+ for(i=0;i<dim&&i<size;i+=COL*2){
+ valid=0;
+ for(j=i;j<i+COL*2&&j<dim;j+=4){
+ d=(memCODE[j+3]<<24)+(memCODE[j+2]<<16)+(memCODE[j+1]<<8)+memCODE[j];
+ sprintf(t,"%08X ",d);
+ strcat(s,t);
+ if(d!=0xffffffff) valid=1;
+ }
+ if(valid){
+ sprintf(t,"%06X: %s\r\n",i/2,s);
+ empty=0;
+ strcat(aux,t);
+ lines++;
+ if(lines>500){ //limit number of lines printed
+ strcat(aux,"(...)\r\n");
+ i=(dim<size?dim:size)-COL*4;
+ lines=490;
+ }
+ }
+ s[0]=0;
+ }
+ if(empty) PrintMessage(strings[S_Empty]); //empty
+ else PrintMessage(aux);
+ free(aux);
+}
+
+void DisplayEE24F(){
+// display EE memory with address offset by 0x7FF000
+ char s[256],t[256],v[256],*aux;
+ int valid=0,empty=1;
+ int i,j;
+#ifdef __GTK_H__
+ char *g ;
+#endif
+ s[0]=0;
+ v[0]=0;
+ aux=(char*)malloc(0x1000/COL*(16+COL*5));
+ aux[0]=0;
+ for(i=0;i<0x1000&&i<sizeEE;i+=COL){
+ valid=0;
+ for(j=i;j<i+COL&&j<0x1000&&i<sizeEE;j+=2){
+ sprintf(t,"%02X %02X ",memEE[j],memEE[j+1]);
+ strcat(s,t);
+ sprintf(t,"%c",isprint(memEE[j])&&(memEE[j]<0xFF)?memEE[j]:'.');
+#ifdef __GTK_H__
+ g=g_locale_to_utf8(t,-1,NULL,NULL,NULL);
+ if(g) strcat(v,g);
+ g_free(g);
+#else
+ strcat(v,t);
+#endif
+ if(memEE[j]<0xff) valid=1;
+ sprintf(t,"%c",isprint(memEE[j+1])&&(memEE[j+1]<0xFF)?memEE[j+1]:'.');
+#ifdef __GTK_H__
+ g=g_locale_to_utf8(t,-1,NULL,NULL,NULL);
+ if(g) strcat(v,g);
+ g_free(g);
+#else
+ strcat(v,t);
+#endif
+ if(memEE[j+1]<0xff) valid=1;
+ }
+ if(valid){
+ sprintf(t,"%04X: %s %s\r\n",i+0xF000,s,v); //back to the device address
+ strcat(aux,t);
+ empty=0;
+ }
+ s[0]=0;
+ v[0]=0;
+ }
+ if(empty) PrintMessage(strings[S_Empty]); //empty
+ else PrintMessage(aux);
+ free(aux);
+}
+
+void Read24Fx(int dim,int dim2,int options,int appIDaddr,int executiveArea){
+// read 16 bit PIC 24Fxxxx
+// deviceID @ 0xFF0000
+// dim=program size (16 bit words)
+// dim2=eeprom size (in bytes, area starts at 0x800000-size)
+// options:
+// bit [3:0]
+// 0 = low voltage ICSP entry
+// 1 = High voltage ICSP entry (6V)
+// 2 = High voltage ICSP entry (12V) + PIC30F sequence (additional NOPs)
+// 3 = low voltage ICSP entry (5V power supply)
+// bit [7:4]
+// 0 = config area in the last 2 program words
+// 1 = config area in the last 3 program words
+// 2 = config area in the last 4 program words
+// 3 = 0xF80000 to 0xF80010 except 02 (24F)
+// 4 = 0xF80000 to 0xF80016 (24H-33F)
+// 5 = 0xF80000 to 0xF8000C (x16 bit, 30F)
+// 6 = 0xF80000 to 0xF8000E (30FSMPS)
+// bit [8]
+// 0 = standard TABLPAG address
+// 1 = new TABLPAG address
+// appIDaddr = application ID word lower address (high is 0x80)
+// executiveArea = size of executive area (16 bit words, starting at 0x800000)
+ int k=0,k2=0,z=0,i,j;
+ int entry=options&0xF;
+ int config=(options>>4)&0xF;
+ int EEbaseAddr=0x1000-dim2;
+ int newTABLPAG=options&0x100?1:0;
+ if(FWVersion<0x700){
+ PrintMessage1(strings[S_FWver2old],"0.7.0"); //"This firmware is too old. Version %s is required\r\n"
+ return;
+ }
+ if(entry<2&&!CheckV33Regulator()){ //except 30Fxx which is on 5V
+ PrintMessage(strings[S_noV33reg]); //Can't find 3.3V expansion board
+ return;
+ }
+ if(saveLog){
+ OpenLogFile();
+ fprintf(logfile,"Read24Fx(%d,%d,%d,%d,%d) (0x%X,0x%X,0x%X,0x%X,0x%X)\n",dim,dim2,options,appIDaddr,executiveArea,dim,dim2,options,appIDaddr,executiveArea);
+ }
+ dim*=2; //from words to bytes
+ if(dim>0x80000||dim<0){
+ PrintMessage(strings[S_CodeLim]); //"Code size out of limits\r\n"
+ return;
+ }
+ if(dim2>0x4000||dim2<0){
+ PrintMessage(strings[S_EELim]); //"EEPROM size out of limits\r\n"
+ return;
+ }
+ unsigned char *memExec=0;
+ executiveArea*=2;
+ if(executiveArea) memExec=(unsigned char *)malloc(executiveArea);
+ for(i=0;i<executiveArea;i++) memExec[i]=0xFF;
+ size=dim;
+ sizeEE=0x1000;
+ if(memCODE) free(memCODE);
+ memCODE=(unsigned char*)malloc(size); //CODE
+ if(memEE) free(memEE);
+ memEE=(unsigned char*)malloc(0x1000); //EEPROM
+ memset(memCODE,0xFF,dim);
+ memset(memEE,0xFF,0x1000);
+ if(config>2){ //only if separate config area
+ sizeCONFIG=48;
+ for(i=0;i<48;i++) memCONFIG[i]=0xFF;
+ }
+ if((entry==1)||(entry==2)){ //High voltage programming: 3.3V + 1.5V + R drop + margin
+ if(!StartHVReg(entry==2?12:6)){ //12V only for 30Fxx !!!
+ PrintMessage(strings[S_HVregErr]); //"HV regulator error\r\n"
+ return;
+ }
+ }
+ else StartHVReg(-1); //LVP: current limited to (5-0.7-3.6)/10k = 50uA
+ unsigned int start=GetTickCount();
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=10000>>8;
+ bufferU[j++]=10000&0xff;
+ bufferU[j++]=EN_VPP_VCC; //enter program mode
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=WAIT_T2;
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC; //VDD + VPP
+ bufferU[j++]=0x5;
+ if((entry==0)||(entry==3)){ //LVP: pulse on MCLR
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ }
+ else PrintMessage(strings[S_HVICSP]); //"High Voltage ICSP\r\n"
+ bufferU[j++]=WAIT_T3; //>10ms before key (GA3xx-GC0xx)
+ bufferU[j++]=TX16;
+ bufferU[j++]=2;
+ bufferU[j++]=0x4D;
+ bufferU[j++]=0x43;
+ bufferU[j++]=0x48;
+ bufferU[j++]=0x51;
+ bufferU[j++]=WAIT_T3; //min 1ms
+ bufferU[j++]=EN_VPP_VCC; //VDD + VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=30000>>8;
+ bufferU[j++]=30000&0xff;
+ bufferU[j++]=WAIT_T3; //min 25ms
+ if(entry==2){ //30Fx entry
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC; //VDD + VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=ICSP_NOP;
+ }
+ else{
+ //Additional 5 clock cycles upon entering program mode
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0; //CK=0
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x4; //CK=1
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0; //CK=0
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x4; //CK=1
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0; //CK=0
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x4; //CK=1
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0; //CK=0
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x4; //CK=1
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0; //CK=0
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x4; //CK=1
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0; //CK=0
+ }
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX; //GOTO 0x200
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(55);
+ j=0;
+ //Read DeviceID @0xFF0000, DevRev @0xFF0002
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=4;
+ bufferU[j++]=0x20; //MOV XXXX,W0
+ bufferU[j++]=0x0F;
+ bufferU[j++]=0xF0; //0xFF
+ bufferU[j++]=0x88; //MOV W0,TABLPAG
+ if(newTABLPAG){
+ bufferU[j++]=0x02;
+ bufferU[j++]=0xA0;
+ }
+ else{
+ bufferU[j++]=0x01;
+ bufferU[j++]=0x90;
+ }
+ bufferU[j++]=0x20; //MOV XXXX,W6
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x06; //0x0000
+ bufferU[j++]=0x20; //MOV #VISI,W7
+ bufferU[j++]=0x78;
+ bufferU[j++]=0x47;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX; //GOTO 0x200
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ int w0=0,w1=0;
+ for(z=0;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2) w0=(bufferI[z+1]<<8)+bufferI[z+2];
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2) w1=(bufferI[z+1]<<8)+bufferI[z+2];
+ PrintMessage2("DevID: 0x%04X\r\nDevRev: 0x%04X\r\n",w0,w1);
+ PIC24_ID(w0);
+ //Read ApplicationID @ appIDaddr
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=0x44; //append 1 NOP
+ bufferU[j++]=0x20; //MOV XXXX,W0
+ bufferU[j++]=0x08;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x88; //MOV W0,TABLPAG
+ if(newTABLPAG){
+ bufferU[j++]=0x02;
+ bufferU[j++]=0xA0;
+ }
+ else{
+ bufferU[j++]=0x01;
+ bufferU[j++]=0x90;
+ }
+ bufferU[j++]=0x20+((appIDaddr>>12)&0xF); //MOV XXXX,W6
+ bufferU[j++]=(appIDaddr>>4)&0xFF;
+ bufferU[j++]=((appIDaddr<<4)&0xF0)+6;
+ bufferU[j++]=0x20; //MOV #VISI,W7
+ bufferU[j++]=0x78;
+ bufferU[j++]=0x47;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0x96;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //GOTO 0x200
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=4;
+ bufferU[j++]=0x20; //MOV XXXX,W0
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x88; //MOV W0,TABLPAG
+ if(newTABLPAG){
+ bufferU[j++]=0x02;
+ bufferU[j++]=0xA0;
+ }
+ else{
+ bufferU[j++]=0x01;
+ bufferU[j++]=0x90;
+ }
+ bufferU[j++]=0x20; //MOV 0,W6
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x06;
+ bufferU[j++]=0x20; //MOV #VISI,W7
+ bufferU[j++]=0x78;
+ bufferU[j++]=0x47;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ for(z=0;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2) w0=(bufferI[z+1]<<8)+bufferI[z+2];
+ PrintMessage2("ApplicationID @ 0x80%04X: 0x%04X\r\n",appIDaddr,w0);
+//****************** read code ********************
+ PrintMessage(strings[S_CodeReading1]); //code read ...
+ PrintStatusSetup();
+//Read 6 24 bit words packed in 9 16 bit words
+//memory address advances by 24 bytes because of alignment
+ int High=0;
+ for(i=0;i<dim;i+=24){
+ if((i>>17)!=High){ //advance page
+ bufferU[j++]=SIX; //MOV XXXX,W0
+ bufferU[j++]=0x20;
+ bufferU[j++]=(i>>21)&0xFF;
+ bufferU[j++]=(i>>13)&0xF0;
+ bufferU[j++]=SIX; //MOV W0,TABLPAG
+ bufferU[j++]=0x88;
+ if(newTABLPAG){
+ bufferU[j++]=0x02;
+ bufferU[j++]=0xA0;
+ }
+ else{
+ bufferU[j++]=0x01;
+ bufferU[j++]=0x90;
+ }
+ bufferU[j++]=SIX; //GOTO 0x200
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ High=i>>17;
+ }
+ bufferU[j++]=SIX_LONG; //GOTO 0x200
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0x96;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDH.B [W6++],[W7++]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0xDB;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=SIX_LONG; //TBLRDH.B [++W6],[W7--]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0xD3;
+ bufferU[j++]=0xD6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ if(i<dim-16){ //skip last read (dim is never multiple of 6)
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0x96;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDH.B [W6++],[W7++]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0xDB;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=SIX_LONG; //TBLRDH.B [++W6],[W7--]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0xD3;
+ bufferU[j++]=0xD6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ }
+ if(i<dim-8){ //skip last read (dim is never multiple of 6)
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0x96;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDH.B [W6++],[W7++]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0xDB;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=SIX_LONG; //TBLRDH.B [++W6],[W7--]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0xD3;
+ bufferU[j++]=0xD6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ }
+
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(3);
+ for(z=0;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ memCODE[k+1]=bufferI[z+1]; //M0
+ memCODE[k]=bufferI[z+2]; //L0
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ memCODE[k+2]=bufferI[z+2]; //H0
+ memCODE[k+6]=bufferI[z+1]; //H1
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ memCODE[k+5]=bufferI[z+1]; //M1
+ memCODE[k+4]=bufferI[z+2]; //L1
+ k+=8;
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ memCODE[k+1]=bufferI[z+1]; //M2
+ memCODE[k+0]=bufferI[z+2]; //L2
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ memCODE[k+2]=bufferI[z+2]; //H2
+ memCODE[k+6]=bufferI[z+1]; //H3
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ memCODE[k+5]=bufferI[z+1]; //M3
+ memCODE[k+4]=bufferI[z+2]; //L3
+ k+=8;
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ memCODE[k+1]=bufferI[z+1]; //M4
+ memCODE[k+0]=bufferI[z+2]; //L4
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ memCODE[k+2]=bufferI[z+2]; //H4
+ memCODE[k+6]=bufferI[z+1]; //H5
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ memCODE[k+5]=bufferI[z+1]; //M5
+ memCODE[k+4]=bufferI[z+2]; //L5
+ k+=8;
+ }
+ PrintStatus(strings[S_CodeReading2],i*100/dim,i/2); //"Read: %d%%, addr. %05X"
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k,k); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ }
+ PrintStatusEnd();
+ if(k!=dim){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ReadCodeErr2],dim,k); //"Error reading code area, requested %d bytes, read %d\r\n"
+ }
+ else PrintMessage(strings[S_Compl]);
+//****************** read config area ********************
+ if(config>2){ //config area @ 0xF80000
+ if(saveLog) fprintf(logfile,"\nCONFIG:\n");
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=4;
+ bufferU[j++]=0x20; //MOV XXXX,W0
+ bufferU[j++]=0x0F;
+ bufferU[j++]=0x80;
+ bufferU[j++]=0x88; //MOV W0,TABLPAG
+ if(newTABLPAG){
+ bufferU[j++]=0x02;
+ bufferU[j++]=0xA0;
+ }
+ else{
+ bufferU[j++]=0x01;
+ bufferU[j++]=0x90;
+ }
+ bufferU[j++]=0x20; //MOV XXXX,W6
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x06;
+ bufferU[j++]=0x20; //MOV #VISI,W7
+ bufferU[j++]=0x78;
+ bufferU[j++]=0x47;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(3);
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],0xF80000,0xF80000,0,0); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ //save 0xF800000 to 0xF80010
+ for(i=0,z=0;i<9;i++){
+ for(;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ memCONFIG[i*4]=bufferI[z+2]; //Low byte
+ memCONFIG[i*4+1]=bufferI[z+1]; //High byte
+ z+=3;
+ }
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(3);
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],0xF80000,0xF80000,0,0); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ //save 0xF800012 to 0xF80016
+ for(i=9,z=0;i<12;i++){
+ for(;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ memCONFIG[i*4]=bufferI[z+2]; //Low byte
+ memCONFIG[i*4+1]=bufferI[z+1]; //High byte
+ z+=3;
+ }
+ PrintStatusClear();
+ }
+//****************** read eeprom ********************
+ if(dim2){
+ if(saveLog) fprintf(logfile,"\nEEPROM:\n");
+ PrintMessage(strings[S_ReadEE]); //read eeprom ...
+ PrintStatusSetup();
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=0x45; //append 1 NOP
+ bufferU[j++]=0x20; //MOV #0x7F,W0
+ bufferU[j++]=0x07;
+ bufferU[j++]=0xF0;
+ bufferU[j++]=0x88; //MOV W0,TABLPAG
+ if(newTABLPAG){
+ bufferU[j++]=0x02;
+ bufferU[j++]=0xA0;
+ }
+ else{
+ bufferU[j++]=0x01;
+ bufferU[j++]=0x90;
+ }
+ bufferU[j++]=0x2F; //MOV #<ADDR[15:0]>,W6 (base address)
+ bufferU[j++]=(EEbaseAddr>>4)&0xFF;
+ bufferU[j++]=(EEbaseAddr&0xF0)+6;
+ bufferU[j++]=0x20; //MOV #VISI,W7
+ bufferU[j++]=0x78;
+ bufferU[j++]=0x47;
+ bufferU[j++]=0x04; //GOTO 0x200
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ for(k2=0,i=0;i<dim2;i+=2){
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ if(j>DIMBUF-6||i==dim2-2){
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(3);
+ j=0;
+ for(z=0;z<DIMBUF-2;z++){
+ if(bufferI[z]==REGOUT){
+ memEE[EEbaseAddr+k2++]=bufferI[z+2];
+ memEE[EEbaseAddr+k2++]=bufferI[z+1];
+ z+=3;
+ //k2+=2; //skip high word
+ }
+ }
+ PrintStatus(strings[S_CodeReading],(i+dim)*100/(dim+dim2),i); //"Read: %d%%, addr. %03X"
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k2,k2); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ }
+ }
+ PrintStatusEnd();
+ if(k2!=dim2){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ReadEEErr],dim2,k2); //"Error reading EEPROM area, requested %d bytes, read %d\r\n"
+ }
+ else PrintMessage(strings[S_Compl]);
+ }
+//****************** read executive area ********************
+ if(executiveArea){
+ j=0;
+ PrintMessage(strings[S_Read_EXE_A]); //read executive area ...
+ PrintStatusSetup();
+ if(saveLog) fprintf(logfile,"\nExecutive area:\n");
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=0x45; //append 1 NOP
+ bufferU[j++]=0x20; //MOV XXXX,W0
+ bufferU[j++]=0x08;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x88; //MOV W0,TABLPAG
+ if(newTABLPAG){
+ bufferU[j++]=0x02;
+ bufferU[j++]=0xA0;
+ }
+ else{
+ bufferU[j++]=0x01;
+ bufferU[j++]=0x90;
+ }
+ bufferU[j++]=0x20; //MOV XXXX,W6
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x06;
+ bufferU[j++]=0x20; //MOV #VISI,W7
+ bufferU[j++]=0x78;
+ bufferU[j++]=0x47;
+ bufferU[j++]=0x04; //GOTO 0x200
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ for(i=0,k=0;i<executiveArea;i+=16){
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0x96;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDH.B [W6++],[W7++]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0xDB;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=SIX_LONG; //TBLRDH.B [++W6],[W7--]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0xD3;
+ bufferU[j++]=0xD6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0x96;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDH.B [W6++],[W7++]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0xDB;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=SIX_LONG; //TBLRDH.B [++W6],[W7--]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0xD3;
+ bufferU[j++]=0xD6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG;
+ bufferU[j++]=0x04; //GOTO 0x200
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(3);
+ j=0;
+ for(z=0;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ memExec[k+1]=bufferI[z+1]; //M0
+ memExec[k]=bufferI[z+2]; //L0
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ memExec[k+2]=bufferI[z+2]; //H0
+ memExec[k+6]=bufferI[z+1]; //H1
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ memExec[k+5]=bufferI[z+1]; //M1
+ memExec[k+4]=bufferI[z+2]; //L1
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ memExec[k+9]=bufferI[z+1]; //M2
+ memExec[k+8]=bufferI[z+2]; //L2
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ memExec[k+10]=bufferI[z+2]; //H2
+ memExec[k+14]=bufferI[z+1]; //H3
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ memExec[k+13]=bufferI[z+1]; //M3
+ memExec[k+12]=bufferI[z+2]; //L3
+ }
+ k+=16;
+ PrintStatus(strings[S_CodeReading2],i*100/executiveArea,0x800000+i/2); //"Read: %d%%, addr. %05X"
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k,k); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ }
+ PrintStatusEnd();
+ if(k!=executiveArea){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ReadCodeErr2],executiveArea,k); //"Error reading code area, requested %d bytes, read %d\r\n"
+ }
+ else PrintMessage(strings[S_Compl]);
+ }
+ PrintMessage("\r\n");
+//****************** exit ********************
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2000>>8;
+ bufferU[j++]=2000&0xff;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=EN_VPP_VCC; //0
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ unsigned int stop=GetTickCount();
+ PrintStatusClear();
+//****************** visualize ********************
+ if(config>2){ //only if separate config area
+ PrintMessage(strings[S_ConfigMem]); //"\r\nConfig Memory:\r\n"
+ if(config==3||config==4||config==6){
+ PrintMessage1("0xF80000: FBS = 0x%02X\r\n",memCONFIG[0]);
+ if(config==4){ //0xF80000-16
+ PrintMessage1("0xF80002: FSS = 0x%02X\r\n",memCONFIG[4]);
+ }
+ PrintMessage1("0xF80004: FGS = 0x%02X\r\n",memCONFIG[8]);
+ PrintMessage1("0xF80006: FOSCSEL = 0x%02X\r\n",memCONFIG[12]);
+ PrintMessage1("0xF80008: FOSC = 0x%02X\r\n",memCONFIG[16]);
+ PrintMessage1("0xF8000A: FWDT = 0x%02X\r\n",memCONFIG[20]);
+ PrintMessage1("0xF8000C: FPOR = 0x%02X\r\n",memCONFIG[24]);
+ PrintMessage1("0xF8000E: FICD = 0x%02X\r\n",memCONFIG[28]);
+ if(config==3){ //0xF80000-10 except 02
+ PrintMessage1("0xF80010: FDS = 0x%02X\r\n",memCONFIG[32]);
+ }
+ else if(config==4){ //0xF80000-16
+ PrintMessage1("0xF80010: UID0 = 0x%02X\r\n",memCONFIG[32]);
+ PrintMessage1("0xF80012: UID1 = 0x%02X\r\n",memCONFIG[36]);
+ PrintMessage1("0xF80014: UID2 = 0x%02X\r\n",memCONFIG[40]);
+ PrintMessage1("0xF80016: UID3 = 0x%02X\r\n",memCONFIG[44]);
+ }
+ }
+ else if(config==5){ //0xF80000-0C (16 bit)
+ PrintMessage2("0xF80000: FOSC = 0x%02X%02X\r\n",memCONFIG[1],memCONFIG[0]);
+ PrintMessage2("0xF80002: FWDT = 0x%02X%02X\r\n",memCONFIG[5],memCONFIG[4]);
+ PrintMessage2("0xF80004: FBORPOR = 0x%02X%02X\r\n",memCONFIG[9],memCONFIG[8]);
+ PrintMessage2("0xF80006: FBS = 0x%02X%02X\r\n",memCONFIG[13],memCONFIG[12]);
+ PrintMessage2("0xF80008: FSS = 0x%02X%02X\r\n",memCONFIG[17],memCONFIG[16]);
+ PrintMessage2("0xF8000A: FGS = 0x%02X%02X\r\n",memCONFIG[21],memCONFIG[20]);
+ PrintMessage2("0xF8000C: FICD = 0x%02X%02X\r\n",memCONFIG[25],memCONFIG[24]);
+ }
+ }
+ else{
+ //last 2 program words
+ PrintMessage2("CONFIG1: 0x%04X\r\nCONFIG2: 0x%04X\r\n",(memCODE[dim-3]<<8)+memCODE[dim-4]\
+ ,(memCODE[dim-7]<<8)+memCODE[dim-8]);
+ if(config==1){ //last 3 program words
+ PrintMessage1("CONFIG3: 0x%04X\r\n",(memCODE[dim-11]<<8)+memCODE[dim-12]);
+ }
+ if(config==2){ //last 4 program words
+ PrintMessage1("CONFIG4: 0x%04X\r\n",(memCODE[dim-15]<<8)+memCODE[dim-16]);
+ }
+ }
+ PrintMessage(strings[S_CodeMem]); //"\r\nCode memory:\r\n"
+ DisplayCODE24F(dim);
+ if(dim2){
+ PrintMessage(strings[S_EEMem]); //"\r\nEEPROM memory:\r\n"
+ DisplayEE24F();
+ }
+ if(executiveArea){
+ char s[256],t[256];
+ int d,valid,empty=1;
+ char* aux=(char*)malloc((dim/COL+1)*2*(16+COL*9));
+ aux[0]=0;
+ s[0]=0;
+ empty=1;
+ PrintMessage(strings[S_ExeMem]); //"\r\nExecutive memory:\r\n"
+ for(i=0;i<executiveArea;i+=COL*2){
+ valid=0;
+ for(j=i;j<i+COL*2&&j<executiveArea;j+=4){
+ d=(memExec[j+3]<<24)+(memExec[j+2]<<16)+(memExec[j+1]<<8)+memExec[j];
+ sprintf(t,"%08X ",d);
+ strcat(s,t);
+ if(d!=0xffffffff) valid=1;
+ }
+ if(valid){
+ sprintf(t,"%06X: %s\r\n",i/2,s);
+ empty=0;
+ strcat(aux,t);
+ }
+ s[0]=0;
+ }
+ if(empty) PrintMessage(strings[S_Empty]); //empty
+ else PrintMessage(aux);
+ free(aux);
+ }
+ sprintf(str,strings[S_End],(stop-start)/1000.0); //"\r\nEnd (%.2f s)\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+}
+
+void Read24Ex(int dim,int dim2,int options,int appIDaddr,int executiveArea){
+// read 16 bit PIC 24Exxxx
+// deviceID @ 0xFF0000
+// dim=program size (16 bit words)
+// dim2=dummy parameter
+// options: not used
+// appIDaddr = application ID word lower address (high is 0x80)
+// executiveArea = size of executive area (16 bit words, starting at 0x800000)
+ int k=0,z=0,i,j;
+ unsigned char UID[16];
+ for(i=0;i<16;i++) UID[i]=0xFF;
+ if(FWVersion<0x900){
+ PrintMessage1(strings[S_FWver2old],"0.9.0"); //"This firmware is too old. Version %s is required\r\n"
+ return;
+ }
+ if(!CheckV33Regulator()){
+ PrintMessage(strings[S_noV33reg]); //Can't find 3.3V expansion board
+ return;
+ }
+ if(saveLog){
+ OpenLogFile();
+ fprintf(logfile,"Read24Ex(%d,%d,%d,%d,%d) (0x%X,0x%X,0x%X,0x%X,0x%X)\n",dim,dim2,options,appIDaddr,executiveArea,dim,dim2,options,appIDaddr,executiveArea);
+ }
+ dim*=2; //from words to bytes
+ if(dim>0x100000||dim<0){
+ PrintMessage(strings[S_CodeLim]); //"Code size out of limits\r\n"
+ return;
+ }
+ unsigned char *memExec=0;
+ executiveArea*=2;
+ if(executiveArea) memExec=(unsigned char *)malloc(executiveArea);
+ for(i=0;i<executiveArea;i++) memExec[i]=0xFF;
+ size=dim;
+ if(memCODE) free(memCODE);
+ memCODE=(unsigned char*)malloc(size); //CODE
+ memset(memCODE,0xFF,dim);
+ StartHVReg(-1); //LVP: current limited to (5-0.7-3.6)/10k = 50uA
+ unsigned int start=GetTickCount();
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2000>>8;
+ bufferU[j++]=2000&0xff;
+ bufferU[j++]=EN_VPP_VCC; //enter program mode
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=WAIT_T2;
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC; //VDD + VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=TX16;
+ bufferU[j++]=2;
+ bufferU[j++]=0x4D;
+ bufferU[j++]=0x43;
+ bufferU[j++]=0x48;
+ bufferU[j++]=0x51;
+ bufferU[j++]=WAIT_T3; //min 1ms
+ bufferU[j++]=EN_VPP_VCC; //VDD + VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=55000>>8;
+ bufferU[j++]=55000&0xff;
+ bufferU[j++]=WAIT_T3; //min 50ms
+ //Additional 5 clock cycles upon entering program mode
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0; //CK=0
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x4; //CK=1
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0; //CK=0
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x4; //CK=1
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0; //CK=0
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x4; //CK=1
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0; //CK=0
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x4; //CK=1
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0; //CK=0
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x4; //CK=1
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0; //CK=0
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX; //GOTO 0x200
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(65);
+ j=0;
+ //Read DeviceID @0xFF0000, DevRev @0xFF0002
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=4;
+ bufferU[j++]=0x20; //MOV XXXX,W0
+ bufferU[j++]=0x0F;
+ bufferU[j++]=0xF0; //0xFF
+ bufferU[j++]=0x88; //MOV W0,TABLPAG
+ bufferU[j++]=0x02;
+ bufferU[j++]=0xA0;
+ bufferU[j++]=0x20; //MOV XXXX,W6
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x06; //0x0000
+ bufferU[j++]=0x20; //MOV #VISI,W7
+ bufferU[j++]=0xF8;
+ bufferU[j++]=0x87;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX_LONG5; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG5; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG5; //GOTO 0x200
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ int w0=0,w1=0;
+ for(z=0;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2) w0=(bufferI[z+1]<<8)+bufferI[z+2];
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2) w1=(bufferI[z+1]<<8)+bufferI[z+2];
+ PrintMessage2("DevID: 0x%04X\r\nDevRev: 0x%04X\r\n",w0,w1);
+ PIC24_ID(w0);
+ //Read ApplicationID @ appIDaddr
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=0x4;
+ bufferU[j++]=0x20; //MOV XXXX,W0
+ bufferU[j++]=0x08;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x88; //MOV W0,TABLPAG
+ bufferU[j++]=0x02;
+ bufferU[j++]=0xA0;
+ bufferU[j++]=0x20+((appIDaddr>>12)&0xF); //MOV XXXX,W6
+ bufferU[j++]=(appIDaddr>>4)&0xFF;
+ bufferU[j++]=((appIDaddr<<4)&0xF0)+6;
+ bufferU[j++]=0x20; //MOV #VISI,W7
+ bufferU[j++]=0xF8;
+ bufferU[j++]=0x87;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX_LONG5; //TBLRDL [W6],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0x96;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG5; //GOTO 0x200
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=4;
+ bufferU[j++]=0x20; //MOV XXXX,W0
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x88; //MOV W0,TABLPAG
+ bufferU[j++]=0x02;
+ bufferU[j++]=0xA0;
+ bufferU[j++]=0x20; //MOV 0,W6
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x06;
+ bufferU[j++]=0x20; //MOV #VISI,W7
+ bufferU[j++]=0xF8;
+ bufferU[j++]=0x87;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ for(z=0;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2) w0=(bufferI[z+1]<<8)+bufferI[z+2];
+ PrintMessage2("ApplicationID @ 0x80%04X: 0x%04X\r\n",appIDaddr,w0);
+//****************** read code ********************
+ PrintMessage(strings[S_CodeReading1]); //code read ...
+ PrintStatusSetup();
+//Read 6 24 bit words packed in 9 16 bit words
+//memory address advances by 24 bytes because of alignment
+ int High=0;
+ for(i=0;i<dim;i+=24){
+ if((i>>17)!=High){ //advance page
+ bufferU[j++]=SIX; //MOV XXXX,W0
+ bufferU[j++]=0x20;
+ bufferU[j++]=(i>>21)&0xFF;
+ bufferU[j++]=(i>>13)&0xF0;
+ bufferU[j++]=SIX; //MOV W0,TABLPAG
+ bufferU[j++]=0x88;
+ bufferU[j++]=0x02;
+ bufferU[j++]=0xA0;
+ bufferU[j++]=SIX_LONG; //GOTO 0x200
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ High=i>>17;
+ }
+ bufferU[j++]=SIX_LONG5; //GOTO 0x200
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=SIX_LONG5; //TBLRDL [W6],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0x96;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG5; //TBLRDH.B [W6++],[W7++]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0xDB;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=SIX_LONG5; //TBLRDH.B [++W6],[W7--]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0xD3;
+ bufferU[j++]=0xD6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG5; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ if(i<dim-16){ //skip last read (dim is never multiple of 6)
+ bufferU[j++]=SIX_LONG5; //TBLRDL [W6],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0x96;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG5; //TBLRDH.B [W6++],[W7++]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0xDB;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=SIX_LONG5; //TBLRDH.B [++W6],[W7--]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0xD3;
+ bufferU[j++]=0xD6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG5; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ }
+ if(i<dim-8){ //skip last read (dim is never multiple of 6)
+ bufferU[j++]=SIX_LONG5; //TBLRDL [W6],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0x96;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG5; //TBLRDH.B [W6++],[W7++]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0xDB;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=SIX_LONG5; //TBLRDH.B [++W6],[W7--]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0xD3;
+ bufferU[j++]=0xD6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG5; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(4);
+ for(z=0;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ memCODE[k+1]=bufferI[z+1]; //M0
+ memCODE[k]=bufferI[z+2]; //L0
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ memCODE[k+2]=bufferI[z+2]; //H0
+ memCODE[k+6]=bufferI[z+1]; //H1
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ memCODE[k+5]=bufferI[z+1]; //M1
+ memCODE[k+4]=bufferI[z+2]; //L1
+ k+=8;
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ memCODE[k+1]=bufferI[z+1]; //M2
+ memCODE[k+0]=bufferI[z+2]; //L2
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ memCODE[k+2]=bufferI[z+2]; //H2
+ memCODE[k+6]=bufferI[z+1]; //H3
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ memCODE[k+5]=bufferI[z+1]; //M3
+ memCODE[k+4]=bufferI[z+2]; //L3
+ k+=8;
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ memCODE[k+1]=bufferI[z+1]; //M4
+ memCODE[k+0]=bufferI[z+2]; //L4
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ memCODE[k+2]=bufferI[z+2]; //H4
+ memCODE[k+6]=bufferI[z+1]; //H5
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ memCODE[k+5]=bufferI[z+1]; //M5
+ memCODE[k+4]=bufferI[z+2]; //L5
+ k+=8;
+ }
+ PrintStatus(strings[S_CodeReading2],i*100/dim,i/2); //"Read: %d%%, addr. %05X"
+ if(RWstop) i=dim;
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k,k); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ }
+ PrintStatusEnd();
+ if(k!=dim){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ReadCodeErr2],dim,k); //"Error reading code area, requested %d bytes, read %d\r\n"
+ }
+ else PrintMessage(strings[S_Compl]);
+//****************** read executive area ********************
+ if(executiveArea){
+ j=0;
+ PrintMessage(strings[S_Read_EXE_A]); //read executive area ...
+ PrintStatusSetup();
+ if(saveLog) fprintf(logfile,"\nExecutive area:\n");
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=0x45; //append 1 NOP
+ bufferU[j++]=0x20; //MOV XXXX,W0
+ bufferU[j++]=0x08;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x88; //MOV W0,TABLPAG
+ bufferU[j++]=0x02;
+ bufferU[j++]=0xA0;
+ bufferU[j++]=0x20; //MOV XXXX,W6
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x06;
+ bufferU[j++]=0x20; //MOV #VISI,W7
+ bufferU[j++]=0xF8;
+ bufferU[j++]=0x87;
+ bufferU[j++]=0x04; //GOTO 0x200
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ for(i=0,k=0;i<executiveArea;i+=16){
+ bufferU[j++]=SIX_LONG5; //TBLRDL [W6],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0x96;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG5; //TBLRDH.B [W6++],[W7++]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0xDB;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=SIX_LONG5; //TBLRDH.B [++W6],[W7--]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0xD3;
+ bufferU[j++]=0xD6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG5; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG5; //TBLRDL [W6],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0x96;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG5; //TBLRDH.B [W6++],[W7++]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0xDB;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=SIX_LONG5; //TBLRDH.B [++W6],[W7--]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0xD3;
+ bufferU[j++]=0xD6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG5; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG;
+ bufferU[j++]=0x04; //GOTO 0x200
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(3);
+ j=0;
+ for(z=0;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ memExec[k+1]=bufferI[z+1]; //M0
+ memExec[k]=bufferI[z+2]; //L0
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ memExec[k+2]=bufferI[z+2]; //H0
+ memExec[k+6]=bufferI[z+1]; //H1
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ memExec[k+5]=bufferI[z+1]; //M1
+ memExec[k+4]=bufferI[z+2]; //L1
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ memExec[k+9]=bufferI[z+1]; //M2
+ memExec[k+8]=bufferI[z+2]; //L2
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ memExec[k+10]=bufferI[z+2]; //H2
+ memExec[k+14]=bufferI[z+1]; //H3
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ memExec[k+13]=bufferI[z+1]; //M3
+ memExec[k+12]=bufferI[z+2]; //L3
+ }
+ k+=16;
+ PrintStatus(strings[S_CodeReading2],i*100/executiveArea,0x800000+i/2); //"Read: %d%%, addr. %05X"
+ if(RWstop) i=dim;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k,k); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ }
+ PrintStatusEnd();
+ if(k!=executiveArea){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ReadCodeErr2],executiveArea,k); //"Error reading code area, requested %d bytes, read %d\r\n"
+ }
+ else PrintMessage(strings[S_Compl]);
+ }
+ PrintMessage("\r\n");
+//****************** read user ID ********************
+ j=0;
+ if(saveLog) fprintf(logfile,"\nUser ID:\n");
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=0x45; //append 1 NOP
+ bufferU[j++]=0x20; //MOV XXXX,W0
+ bufferU[j++]=0x08;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x88; //MOV W0,TABLPAG
+ bufferU[j++]=0x02;
+ bufferU[j++]=0xA0;
+ bufferU[j++]=0x20; //MOV XXXX,W6
+ bufferU[j++]=0xFF;
+ bufferU[j++]=0x86;
+ bufferU[j++]=0x20; //MOV #VISI,W7
+ bufferU[j++]=0xF8;
+ bufferU[j++]=0x87;
+ bufferU[j++]=0x04; //GOTO 0x200
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ bufferU[j++]=SIX_LONG5; //TBLRDL [W6],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0x96;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG5; //TBLRDH.B [W6++],[W7++]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0xDB;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=SIX_LONG5; //TBLRDH.B [++W6],[W7--]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0xD3;
+ bufferU[j++]=0xD6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG5; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG5; //TBLRDL [W6],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0x96;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG5; //TBLRDH.B [W6++],[W7++]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0xDB;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=SIX_LONG5; //TBLRDH.B [++W6],[W7--]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0xD3;
+ bufferU[j++]=0xD6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG5; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG5;
+ bufferU[j++]=0x04; //GOTO 0x200
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(3);
+ j=0;
+ k=0;
+ for(z=0;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ UID[k+1]=bufferI[z+1]; //M0
+ UID[k]=bufferI[z+2]; //L0
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ UID[k+2]=bufferI[z+2]; //H0
+ UID[k+6]=bufferI[z+1]; //H1
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ UID[k+5]=bufferI[z+1]; //M1
+ UID[k+4]=bufferI[z+2]; //L1
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ UID[k+9]=bufferI[z+1]; //M2
+ UID[k+8]=bufferI[z+2]; //L2
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ UID[k+10]=bufferI[z+2]; //H2
+ UID[k+14]=bufferI[z+1]; //H3
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ UID[k+13]=bufferI[z+1]; //M3
+ UID[k+12]=bufferI[z+2]; //L3
+ }
+ PrintMessage("\r\n");
+//****************** exit ********************
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2000>>8;
+ bufferU[j++]=2000&0xff;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=EN_VPP_VCC; //0
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ unsigned int stop=GetTickCount();
+ PrintStatusClear();
+//****************** visualize ********************
+ for(i=0;i<10;i++) PrintMessage3("CONFIG%d(0x%05X): 0x%02X\r\n",i,(dim-40+i*4)/2,memCODE[dim-40+i*4]);
+ PrintMessage(strings[S_CodeMem]); //"\r\nCode memory:\r\n"
+ DisplayCODE24F(dim);
+ if(executiveArea){
+ char s[256],t[256];
+ int d,valid,empty=1;
+ char* aux=(char*)malloc((executiveArea/COL+1)*2*(16+COL*9));
+ aux[0]=0;
+ s[0]=0;
+ empty=1;
+ PrintMessage(strings[S_ExeMem]); //"\r\nExecutive memory:\r\n"
+ for(i=0;i<executiveArea;i+=COL*2){
+ valid=0;
+ for(j=i;j<i+COL*2&&j<executiveArea;j+=4){
+ d=(memExec[j+3]<<24)+(memExec[j+2]<<16)+(memExec[j+1]<<8)+memExec[j];
+ sprintf(t,"%08X ",d);
+ strcat(s,t);
+ if(d!=0xffffffff) valid=1;
+ }
+ if(valid){
+ sprintf(t,"%06X: %s\r\n",i/2,s);
+ empty=0;
+ strcat(aux,t);
+ }
+ s[0]=0;
+ }
+ if(empty) PrintMessage(strings[S_Empty]); //empty
+ else PrintMessage(aux);
+ free(aux);
+ }
+ for(i=0;i<4;i++){
+ if(UID[i*4]!=0xFF||UID[i*4+1]!=0xFF) PrintMessage2("UserID%d=%04X",i,(UID[i*4]<<8)+UID[i*4+1]);
+ }
+ sprintf(str,strings[S_End],(stop-start)/1000.0); //"\r\nEnd (%.2f s)\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+}
+
+
+void Write24Fx(int dim,int dim2,int options,int appIDaddr,int rowSize, double wait){
+// write 16 bit PIC 24Fxxxx
+// deviceID @ 0xFF0000
+// dim=program size (16 bit words)
+// dim2=eeprom size (in bytes, area starts at 0x800000-size)
+// options:
+// bit [3:0]
+// 0 = low voltage ICSP entry
+// 1 = High voltage ICSP entry (6V)
+// 2 = High voltage ICSP entry (12V) + PIC30F sequence (additional NOPs)
+// 3 = low voltage ICSP entry (5V power supply)
+// bit [7:4]
+// 0 = config area in the last 2 program words
+// 1 = config area in the last 3 program words
+// 2 = config area in the last 4 program words
+// 3 = 0xF80000 to 0xF80010 except 02 (24F)
+// 4 = 0xF80000 to 0xF80016 (24H-33F)
+// 5 = 0xF80000 to 0xF8000C (x16 bit, 30F)
+// 6 = 0xF80000 to 0xF8000E (30FSMPS)
+// bit [11:8]
+// 0 = code erase word is 0x4064, row write is 0x4004
+// 1 = code erase word is 0x404F, row write is 0x4001
+// 2 = code erase word is 0x407F, row write is 0x4001, 55AA unlock and external timing (2 ms)
+// 3 = code erase word is 0x407F, row write is 0x4001, 55AA unlock and external timing (200 ms)
+// bit [15:12]
+// 0 = eeprom erase word is 0x4050, write word is 0x4004
+// 1 = eeprom erased with bulk erase, write word is 0x4004
+// 2 = eeprom erased with special sequence, write word is 0x4004
+// bit [19:16]
+// 0 = config write is 0x4000
+// 1 = config write is 0x4003
+// 2 = config write is 0x4004
+// 3 = config write is 0x4008
+// bit [20]
+// 0 = standard TABLPAG address
+// 1 = new TABLPAG address
+// appIDaddr = application ID word lower address (high is 0x80)
+// rowSize = row size in instruction words (a row is written altogether)
+// wait = write delay in ms
+ int k=0,k2=0,z=0,i,j;
+ int entry=options&0xF;
+ int config=(options>>4)&0xF;
+ int EEbaseAddr=0x1000-dim2;
+ int newTABLPAG=options&0x100000?1:0;
+ int err=0;
+ if(FWVersion<0x700){
+ PrintMessage1(strings[S_FWver2old],"0.7.0"); //"This firmware is too old. Version %s is required\r\n"
+ return;
+ }
+ if(entry<2&&!CheckV33Regulator()){ //except 30Fxx which is on 5V
+ PrintMessage(strings[S_noV33reg]); //Can't find 3.3V expansion board
+ return;
+ }
+ if(saveLog){
+ OpenLogFile();
+ fprintf(logfile,"Write24Fx(%d,%d,%d,%d,%d,%.1f) (0x%X,0x%X,0x%X,0x%X,0x%X,%.3f)\n"
+ ,dim,dim2,options,appIDaddr,rowSize,wait,dim,dim2,options,appIDaddr,rowSize,wait);
+ }
+ dim*=2; //from words to bytes
+ if(dim>0x80000||dim<0){
+ PrintMessage(strings[S_CodeLim]); //"Code size out of limits\r\n"
+ return;
+ }
+ if(dim2>0x1000||dim2<0){
+ PrintMessage(strings[S_EELim]); //"EEPROM size out of limits\r\n"
+ return;
+ }
+ j=size;
+ if(j%(rowSize*4)){ //grow to an integer number of rows
+ size=(j/(rowSize*4)+1)*rowSize*4;
+ memCODE=(unsigned char*)realloc(memCODE,size);
+ for(;j<size;j++) memCODE[j]=0xFF;
+ }
+ if(dim>size) dim=size;
+ if(sizeEE<0x1000) dim2=0;
+ if(dim<1){
+ PrintMessage(strings[S_NoCode]); //"Empty code area\r\n"
+ return;
+ }
+ if((entry==1)||(entry==2)){ //High voltage programming: 3.3V + 1.5V + R drop + margin
+ if(!StartHVReg(entry==2?12:6)){ //12V only for 30Fxx !!!
+ PrintMessage(strings[S_HVregErr]); //"HV regulator error\r\n"
+ return;
+ }
+ }
+ else StartHVReg(-1); //LVP: current limited to (5-0.7-3.6)/10k = 50uA
+ if(config>2){ //only if separate config area
+ PrintMessage(strings[S_ConfigMem]); //"\r\nConfig Memory:\r\n"
+ if(config==3||config==4||config==6){
+ PrintMessage1("0xF80000: FBS = 0x%02X\r\n",memCONFIG[0]);
+ if(config==4){ //0xF80000-16
+ PrintMessage1("0xF80002: FSS = 0x%02X\r\n",memCONFIG[4]);
+ }
+ PrintMessage1("0xF80004: FGS = 0x%02X\r\n",memCONFIG[8]);
+ PrintMessage1("0xF80006: FOSCSEL = 0x%02X\r\n",memCONFIG[12]);
+ PrintMessage1("0xF80008: FOSC = 0x%02X\r\n",memCONFIG[16]);
+ PrintMessage1("0xF8000A: FWDT = 0x%02X\r\n",memCONFIG[20]);
+ PrintMessage1("0xF8000C: FPOR = 0x%02X\r\n",memCONFIG[24]);
+ PrintMessage1("0xF8000E: FICD = 0x%02X\r\n",memCONFIG[28]);
+ if(config==3){ //0xF80000-10 except 02
+ PrintMessage1("0xF80010: FDS = 0x%02X\r\n",memCONFIG[32]);
+ }
+ else if(config==4){ //0xF80000-16
+ PrintMessage1("0xF80010: UID0 = 0x%02X\r\n",memCONFIG[32]);
+ PrintMessage1("0xF80012: UID1 = 0x%02X\r\n",memCONFIG[36]);
+ PrintMessage1("0xF80014: UID2 = 0x%02X\r\n",memCONFIG[40]);
+ PrintMessage1("0xF80016: UID3 = 0x%02X\r\n",memCONFIG[44]);
+ }
+ }
+ else if(config==5){ //0xF80000-0C (16 bit)
+ PrintMessage2("0xF80000: FOSC = 0x%02X%02X\r\n",memCONFIG[1],memCONFIG[0]);
+ PrintMessage2("0xF80002: FWDT = 0x%02X%02X\r\n",memCONFIG[5],memCONFIG[4]);
+ PrintMessage2("0xF80004: FBORPOR = 0x%02X%02X\r\n",memCONFIG[9],memCONFIG[8]);
+ PrintMessage2("0xF80006: FBS = 0x%02X%02X\r\n",memCONFIG[13],memCONFIG[12]);
+ PrintMessage2("0xF80008: FSS = 0x%02X%02X\r\n",memCONFIG[17],memCONFIG[16]);
+ PrintMessage2("0xF8000A: FGS = 0x%02X%02X\r\n",memCONFIG[21],memCONFIG[20]);
+ PrintMessage2("0xF8000C: FICD = 0x%02X%02X\r\n",memCONFIG[25],memCONFIG[24]);
+ }
+ }
+ else{
+ //last 2 program words
+ PrintMessage2("CONFIG1: 0x%04X\r\nCONFIG2: 0x%04X\r\n",(memCODE[dim-3]<<8)+memCODE[dim-4]\
+ ,(memCODE[dim-7]<<8)+memCODE[dim-8]);
+ if(config==1){ //last 3 program words
+ PrintMessage1("CONFIG3: 0x%04X\r\n",(memCODE[dim-11]<<8)+memCODE[dim-12]);
+ }
+ if(config==2){ //last 4 program words
+ PrintMessage1("CONFIG4: 0x%04X\r\n",(memCODE[dim-15]<<8)+memCODE[dim-16]);
+ }
+ }
+ unsigned int start=GetTickCount();
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2000>>8;
+ bufferU[j++]=2000&0xff;
+ bufferU[j++]=EN_VPP_VCC; //enter program mode
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=WAIT_T2;
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC; //VDD + VPP
+ bufferU[j++]=0x5;
+ if((entry==0)||(entry==3)){ //LVP: pulse on MCLR
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ }
+ else PrintMessage(strings[S_HVICSP]); //"High Voltage ICSP\r\n"
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=TX16;
+ bufferU[j++]=2;
+ bufferU[j++]=0x4D;
+ bufferU[j++]=0x43;
+ bufferU[j++]=0x48;
+ bufferU[j++]=0x51;
+ bufferU[j++]=WAIT_T3; //min 1ms
+ bufferU[j++]=EN_VPP_VCC; //VDD + VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=30000>>8;
+ bufferU[j++]=30000&0xff;
+ bufferU[j++]=WAIT_T3; //min 25ms
+ if(entry==2){ //30Fx entry
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC; //VDD + VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=ICSP_NOP;
+ }
+ else{
+ //Additional 5 clock cycles upon entering program mode
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0; //CK=0
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x4; //CK=1
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0; //CK=0
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x4; //CK=1
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0; //CK=0
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x4; //CK=1
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0; //CK=0
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x4; //CK=1
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0; //CK=0
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x4; //CK=1
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0; //CK=0
+ }
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX; //GOTO 0x200
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(37);
+ j=0;
+ //Read DeviceID @0xFF0000, DevRev @0xFF0002
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=4;
+ bufferU[j++]=0x20; //MOV XXXX,W0
+ bufferU[j++]=0x0F;
+ bufferU[j++]=0xF0; //0xFF
+ bufferU[j++]=0x88; //MOV W0,TABLPAG
+ if(newTABLPAG){
+ bufferU[j++]=0x02;
+ bufferU[j++]=0xA0;
+ }
+ else{
+ bufferU[j++]=0x01;
+ bufferU[j++]=0x90;
+ }
+ bufferU[j++]=0x20; //MOV XXXX,W6
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x06; //0x0000
+ bufferU[j++]=0x20; //MOV #VISI,W7
+ bufferU[j++]=0x78;
+ bufferU[j++]=0x47;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX; //GOTO 0x200
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ int w0=0,w1=0;
+ for(z=0;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2) w0=(bufferI[z+1]<<8)+bufferI[z+2];
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2) w1=(bufferI[z+1]<<8)+bufferI[z+2];
+ PrintMessage2("DevID: 0x%04X\r\nDevRev: 0x%04X\r\n",w0,w1);
+ PIC24_ID(w0);
+ //Read ApplicationID @ appIDaddr
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=0x44; //append 1 NOP
+ bufferU[j++]=0x20; //MOV XXXX,W0
+ bufferU[j++]=0x08;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x88; //MOV W0,TABLPAG
+ if(newTABLPAG){
+ bufferU[j++]=0x02;
+ bufferU[j++]=0xA0;
+ }
+ else{
+ bufferU[j++]=0x01;
+ bufferU[j++]=0x90;
+ }
+ bufferU[j++]=0x20+((appIDaddr>>12)&0xF); //MOV XXXX,W6
+ bufferU[j++]=(appIDaddr>>4)&0xFF;
+ bufferU[j++]=((appIDaddr<<4)&0xF0)+6;
+ bufferU[j++]=0x20; //MOV #VISI,W7
+ bufferU[j++]=0x78;
+ bufferU[j++]=0x47;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0x96;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //GOTO 0x200
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2000>>8;
+ bufferU[j++]=2000&0xff;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ for(z=0;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2) w0=(bufferI[z+1]<<8)+bufferI[z+2];
+ PrintMessage2("ApplicationID @ 0x80%04X: 0x%04X\r\n",appIDaddr,w0);
+//****************** erase memory ********************
+ PrintMessage(strings[S_StartErase]); //"Erase ... "
+ if(saveLog) fprintf(logfile,"\nERASE:\n");
+ int erase=(options&0xF00)>>8;
+ //bulk erase command
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=4;
+ bufferU[j++]=0x24; //MOV XXXX,W10
+ if(erase==0){ //0x4064
+ bufferU[j++]=0x06;
+ bufferU[j++]=0x4A;
+ }
+ else if(erase==1){ //0x404F
+ bufferU[j++]=0x04;
+ bufferU[j++]=0xFA;
+ }
+ else if(erase>=2){ //0x407F
+ bufferU[j++]=0x07;
+ bufferU[j++]=0xFA;
+ }
+ bufferU[j++]=0x88; //MOV W10,NVMCON
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x0A;
+ bufferU[j++]=0x20; //MOV XXXX,W0
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x88; //MOV W0,TABLPAG
+ if(newTABLPAG){
+ bufferU[j++]=0x02;
+ bufferU[j++]=0xA0;
+ }
+ else{
+ bufferU[j++]=0x01;
+ bufferU[j++]=0x90;
+ }
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX_LONG; //TBLWTL W0,[W0] (dummy write)
+ bufferU[j++]=0xBB;
+ bufferU[j++]=0x08;
+ bufferU[j++]=0x00;
+ if(erase>=2){ //30Fx, unlock and external timing
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=4;
+ bufferU[j++]=0x20; //MOV 0x55,W8
+ bufferU[j++]=0x05;
+ bufferU[j++]=0x58;
+ bufferU[j++]=0x88; //MOV W8,NVMKEY
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x38;
+ bufferU[j++]=0x20; //MOV 0xAA,W8
+ bufferU[j++]=0x0A;
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0x88; //MOV W8,NVMKEY
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x38;
+ bufferU[j++]=SIX_LONG; //BSET NVMCON,#WR
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0xE7;
+ bufferU[j++]=0x61;
+ bufferU[j++]=WAIT_T3;
+ if(erase==3){ //200 ms timing
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(20);
+ msDelay(200);
+ j=0;
+ }
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX_LONG; //BCLR NVMCON,#WR
+ bufferU[j++]=0xA9;
+ bufferU[j++]=0xE7;
+ bufferU[j++]=0x61;
+ }
+ else{ //internal timing
+ bufferU[j++]=SIX_LONG; //BSET NVMCON,#WR
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0xE7;
+ bufferU[j++]=0x61;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=SIX; //MOV NVMCON,W2
+ bufferU[j++]=0x80;
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x02;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX; //MOV W2,VISI
+ bufferU[j++]=0x88;
+ bufferU[j++]=0x3C;
+ bufferU[j++]=0x22;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=REGOUT;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(7);
+ j=0;
+ for(z=0;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ w0=bufferI[z+1]&0x80;
+ //Wait for erase completion (max 1s)
+ bufferU[j++]=SIX; //MOV NVMCON,W2
+ bufferU[j++]=0x80;
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x02;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX; //MOV W2,VISI
+ bufferU[j++]=0x88;
+ bufferU[j++]=0x3C;
+ bufferU[j++]=0x22;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ j=0;
+ for(i=0;erase<2&&i<100&&w0;i++){
+ PacketIO(5);
+ for(z=0;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ w0=bufferI[z+1]&0x80;
+ msDelay(10);
+ }
+ if(saveLog) fprintf(logfile,"\nErase time: %dms\n",i*12);
+//****************** prepare write ********************
+ msDelay(10);
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=5;
+ bufferU[j++]=0x24; //MOV XXXX,W10
+ bufferU[j++]=0x00;
+ bufferU[j++]=erase>0?0x1A:0x4A; //0x4001/0x4004
+ bufferU[j++]=0x88; //MOV W10,NVMCON
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x0A;
+ bufferU[j++]=0x20; //MOV XXXX,W0
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x88; //MOV W0,TABLPAG
+ if(newTABLPAG){
+ bufferU[j++]=0x02;
+ bufferU[j++]=0xA0;
+ }
+ else{
+ bufferU[j++]=0x01;
+ bufferU[j++]=0x90;
+ }
+ bufferU[j++]=0x04; //GOTO 0x200
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ j=0;
+ PrintMessage(strings[S_Compl]); //"completed\r\n"
+//****************** write code ********************
+ PrintMessage(strings[S_StartCodeProg]); //"Write code ... "
+ if(saveLog) fprintf(logfile,"\nWRITE CODE:\n");
+ PrintStatusSetup();
+// instruction words are stored in code memory array as follows:
+// L0 M0 H0 FF L1 M1 H1 FF
+ int valid,High=0;
+ for(i=0,k=0;i<dim;i+=4*4){ //write 4 instruction words
+ if(k==0){ //skip row if empty
+ for(valid=0;!valid&&i<dim;i+=valid?0:rowSize*4){
+ for(k2=0;k2<rowSize*4&&!valid;k2++) if(memCODE[i+k2]<0xFF) valid=1;
+ }
+ if(i>=dim) break;
+ }
+ if((i>>17)!=High){ //advance page
+ bufferU[j++]=SIX; //MOV XXXX,W0
+ bufferU[j++]=0x20;
+ bufferU[j++]=(i>>21)&0xFF;
+ bufferU[j++]=(i>>13)&0xF0;
+ bufferU[j++]=SIX; //MOV W0,TABLPAG
+ bufferU[j++]=0x88;
+ if(newTABLPAG){
+ bufferU[j++]=0x02;
+ bufferU[j++]=0xA0;
+ }
+ else{
+ bufferU[j++]=0x01;
+ bufferU[j++]=0x90;
+ }
+ bufferU[j++]=SIX; //GOTO 0x200
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ High=i>>17;
+ }
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=8;
+ bufferU[j++]=0x20+((i>>13)&0xF); //MOV i/2,W7
+ bufferU[j++]=(i>>5)&0xFF;
+ bufferU[j++]=((i<<3)&0xF0)+7;
+ bufferU[j++]=0x20+((memCODE[i+1]>>4)&0xF); //MOV LSW0,W0
+ bufferU[j++]=((memCODE[i+1]<<4)&0xF0)+((memCODE[i]>>4)&0xF);
+ bufferU[j++]=(memCODE[i]<<4)&0xF0;
+ bufferU[j++]=0x20+((memCODE[i+6]>>4)&0xF); //MOV MSB1:MSB0,W1
+ bufferU[j++]=((memCODE[i+6]<<4)&0xF0)+((memCODE[i+2]>>4)&0xF);
+ bufferU[j++]=((memCODE[i+2]<<4)&0xF0)+1;
+ bufferU[j++]=0x20+((memCODE[i+5]>>4)&0xF); //MOV LSW1,W2
+ bufferU[j++]=((memCODE[i+5]<<4)&0xF0)+((memCODE[i+4]>>4)&0xF);
+ bufferU[j++]=((memCODE[i+4]<<4)&0xF0)+2;
+ bufferU[j++]=0x20+((memCODE[i+9]>>4)&0xF); //MOV LSW2,W3
+ bufferU[j++]=((memCODE[i+9]<<4)&0xF0)+((memCODE[i+8]>>4)&0xF);
+ bufferU[j++]=((memCODE[i+8]<<4)&0xF0)+3;
+ bufferU[j++]=0x20+((memCODE[i+14]>>4)&0xF); //MOV MSB3:MSB2,W4
+ bufferU[j++]=((memCODE[i+14]<<4)&0xF0)+((memCODE[i+10]>>4)&0xF);
+ bufferU[j++]=((memCODE[i+10]<<4)&0xF0)+4;
+ bufferU[j++]=0x20+((memCODE[i+13]>>4)&0xF); //MOV LSW3,W5
+ bufferU[j++]=((memCODE[i+13]<<4)&0xF0)+((memCODE[i+12]>>4)&0xF);
+ bufferU[j++]=((memCODE[i+12]<<4)&0xF0)+5;
+ bufferU[j++]=0xEB; //CLR W6
+ bufferU[j++]=0x03;
+ bufferU[j++]=0x00;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=0x88; //Append 2 NOP
+ bufferU[j++]=0xBB; //TBLWTL [W6++],[W7]
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=0xBB; //TBLWTH.B [W6++],[W7++]
+ bufferU[j++]=0xDB;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=0xBB; //TBLWTH.B [W6++],[++W7]
+ bufferU[j++]=0xEB;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=0xBB; //TBLWTL [W6++],[W7++]
+ bufferU[j++]=0x1B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=0xBB; //TBLWTL [W6++],[W7]
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=0xBB; //TBLWTH.B [W6++],[W7++]
+ bufferU[j++]=0xDB;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=0xBB; //TBLWTH.B [W6++],[++W7]
+ bufferU[j++]=0xEB;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=0xBB; //TBLWTL [W6++],[W7++]
+ bufferU[j++]=0x1B;
+ bufferU[j++]=0xB6;
+ k++;
+ if(k==rowSize/4){ //Write row
+ if(erase>1){ //30Fx, unlock and external timing
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(3);
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k,k); //"i=%d, k=%d 0=%d\n"
+ }
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=6;
+ bufferU[j++]=0x24; //MOV XXXX,W10
+ bufferU[j++]=0x00;
+ bufferU[j++]=erase>0?0x1A:0x4A; //0x4001/0x4004
+ bufferU[j++]=0x88; //MOV W10,NVMCON
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x0A;
+ bufferU[j++]=0x20; //MOV 0x55,W8
+ bufferU[j++]=0x05;
+ bufferU[j++]=0x58;
+ bufferU[j++]=0x88; //MOV W8,NVMKEY
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x38;
+ bufferU[j++]=0x20; //MOV 0xAA,W8
+ bufferU[j++]=0x0A;
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0x88; //MOV W8,NVMKEY
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x38;
+ bufferU[j++]=SIX_LONG; //BSET NVMCON,#WR
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0xE7;
+ bufferU[j++]=0x61;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX_LONG; //BCLR NVMCON,#WR
+ bufferU[j++]=0xA9;
+ bufferU[j++]=0xE7;
+ bufferU[j++]=0x61;
+ bufferU[j++]=SIX_LONG; //GOTO 0x200
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ }
+ else{ //internal timing
+ bufferU[j++]=SIX_LONG; //GOTO 0x200
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=SIX_LONG; //BSET NVMCON,#WR
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0xE7;
+ bufferU[j++]=0x61;
+ }
+ k=0;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(3);
+ j=0;
+ PrintStatus(strings[S_CodeWriting2],i*100/(dim+dim2),i/2); //"Write: %d%%,addr. %04X"
+ if(RWstop) i=dim;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i/2,i/2,k,k); //"i=%d, k=%d 0=%d\n"
+ }
+ }
+ PrintStatusEnd();
+ PrintMessage(strings[S_Compl]); //"completed\r\n"
+//****************** verify code ********************
+ PrintMessage(strings[S_CodeV]); //"Verify code ... "
+ if(saveLog) fprintf(logfile,"\nVERIFY CODE:\n");
+ PrintStatusSetup();
+//Read 4 24 bit words packed in 6 16 bit words
+//memory address advances by 16 bytes because of alignment
+ High=0xE0000000;
+ int r0=0,r1=0,r2=0,r3=0,w3,w2;
+ for(i=0;i<dim;i+=16){
+ //skip row if empty
+ for(valid=0;!valid&&i<dim;i+=valid?0:16){
+ for(k2=0;k2<16&&!valid;k2++) if(memCODE[i+k2]<0xFF) valid=1;
+ }
+ if(i>=dim) break;
+ if((i>>17)!=High){ //advance page
+ bufferU[j++]=SIX; //MOV XXXX,W0
+ bufferU[j++]=0x20;
+ bufferU[j++]=(i>>21)&0xFF;
+ bufferU[j++]=(i>>13)&0xF0;
+ bufferU[j++]=SIX; //MOV W0,TABLPAG
+ bufferU[j++]=0x88;
+ if(newTABLPAG){
+ bufferU[j++]=0x02;
+ bufferU[j++]=0xA0;
+ }
+ else{
+ bufferU[j++]=0x01;
+ bufferU[j++]=0x90;
+ }
+ bufferU[j++]=SIX; //GOTO 0x200
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ High=i>>17;
+ }
+ bufferU[j++]=SIX; //MOV i/2,W6
+ bufferU[j++]=0x20+((i>>13)&0xF);
+ bufferU[j++]=(i>>5)&0xFF;
+ bufferU[j++]=((i<<3)&0xF0)+6;
+ bufferU[j++]=SIX; //MOV #VISI,W7
+ bufferU[j++]=0x20;
+ bufferU[j++]=0x78;
+ bufferU[j++]=0x47;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0x96;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDH.B [W6++],[W7++]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0xDB;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=SIX_LONG; //TBLRDH.B [++W6],[W7--]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0xD3;
+ bufferU[j++]=0xD6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0x96;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDH.B [W6++],[W7++]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0xDB;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=SIX_LONG; //TBLRDH.B [++W6],[W7--]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0xD3;
+ bufferU[j++]=0xD6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //GOTO 0x200
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(3);
+ PrintStatus(strings[S_CodeV2],i*100/(dim+dim2),i/2); //"Verify: %d%%, addr. %04X"
+ if(RWstop) i=dim;
+ for(z=0;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ r0=(bufferI[z+1]<<8)+bufferI[z+2];
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ r0+=bufferI[z+2]<<16;
+ r1=bufferI[z+1]<<16;
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ r1+=(bufferI[z+1]<<8)+bufferI[z+2];
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ r2=(bufferI[z+1]<<8)+bufferI[z+2];
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ r2+=bufferI[z+2]<<16;
+ r3=bufferI[z+1]<<16;
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ r3+=(bufferI[z+1]<<8)+bufferI[z+2];
+ }
+ w0=(memCODE[i+2]<<16)+(memCODE[i+1]<<8)+memCODE[i];
+ w1=(memCODE[i+6]<<16)+(memCODE[i+5]<<8)+memCODE[i+4];
+ w2=(memCODE[i+10]<<16)+(memCODE[i+9]<<8)+memCODE[i+8];
+ w3=(memCODE[i+14]<<16)+(memCODE[i+13]<<8)+memCODE[i+12];
+ CheckData(w0,r0,i/2,&err);
+ CheckData(w1,r1,i/2+2,&err);
+ CheckData(w2,r2,i/2+4,&err);
+ CheckData(w3,r3,i/2+6,&err);
+ PrintStatus(strings[S_CodeV2],i*100/dim,i/2); //"Verify: %d%%, addr. %05X"
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i/2,i/2,k,k,err); //"i=%d, k=%d, errori=%d\n"
+ }
+ if(err>=max_err) break;
+ }
+ PrintStatusEnd();
+ PrintMessage1(strings[S_ComplErr],err); //"completed: %d errors\r\n"
+ if(err>=max_err){
+ PrintMessage1(strings[S_MaxErr],err); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ }
+//****************** erase, write and verify EEPROM ********************
+ if(dim2&&err<max_err){
+ //EEPROM @ 0x7F(EEbaseAddr)
+ PrintMessage(strings[S_EEAreaW]); //"Write EEPROM ... "
+ PrintStatusSetup();
+ if(saveLog) fprintf(logfile,"\nWRITE EEPROM:\n");
+ int eewrite=(options&0xf000)>>12;
+ if(eewrite==0){ //24FxxKAxx
+ bufferU[j++]=SIX; //MOV 0x4050,W10
+ bufferU[j++]=0x24;
+ bufferU[j++]=0x05;
+ bufferU[j++]=0x0A;
+ bufferU[j++]=SIX; //MOV W10,NVMCON
+ bufferU[j++]=0x88;
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x0A;
+ bufferU[j++]=SIX; //MOV 0x7F,W0
+ bufferU[j++]=0x20;
+ bufferU[j++]=0x07;
+ bufferU[j++]=0xF0;
+ bufferU[j++]=SIX; //MOV W0,TABLPAG
+ bufferU[j++]=0x88;
+ if(newTABLPAG){
+ bufferU[j++]=0x02;
+ bufferU[j++]=0xA0;
+ }
+ else{
+ bufferU[j++]=0x01;
+ bufferU[j++]=0x90;
+ }
+ bufferU[j++]=SIX; //MOV EEbaseAddr,W0
+ bufferU[j++]=0x2F;
+ bufferU[j++]=EEbaseAddr>>4;
+ bufferU[j++]=0x00;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX; //TBLWTL W0,[W0]
+ bufferU[j++]=0xBB;
+ bufferU[j++]=0x08;
+ bufferU[j++]=0x00;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;/**/
+ //Erase EEPROM
+ bufferU[j++]=SIX; //BSET NVMCON,#WR
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0xE7;
+ bufferU[j++]=0x61;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=SIX; //MOV 0x4004,W10
+ bufferU[j++]=0x24;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x4A;
+ bufferU[j++]=SIX; //MOV W10,NVMCON
+ bufferU[j++]=0x88;
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x0A;
+ bufferU[j++]=SIX; //GOTO 0x200
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(9);
+ j=0;
+ }
+ else if(eewrite==2){ //separate erase
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=6;
+ bufferU[j++]=0x24; //MOV 4046,W10
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x6A;
+ bufferU[j++]=0x88; //MOV W10,NVMCON
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x0A;
+ bufferU[j++]=0x20; //MOV 0x55,W8
+ bufferU[j++]=0x05;
+ bufferU[j++]=0x58;
+ bufferU[j++]=0x88; //MOV W8,NVMKEY
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x38;
+ bufferU[j++]=0x20; //MOV 0xAA,W8
+ bufferU[j++]=0x0A;
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0x88; //MOV W8,NVMKEY
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x38;
+ bufferU[j++]=SIX_LONG; //BSET NVMCON,#WR
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0xE7;
+ bufferU[j++]=0x61;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX_LONG; //BCLR NVMCON,#WR
+ bufferU[j++]=0xA9;
+ bufferU[j++]=0xE7;
+ bufferU[j++]=0x61;
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=6;
+ bufferU[j++]=0x24; //MOV 4056,W10
+ bufferU[j++]=0x05;
+ bufferU[j++]=0x6A;
+ bufferU[j++]=0x88; //MOV W10,NVMCON
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x0A;
+ bufferU[j++]=0x20; //MOV 0x55,W8
+ bufferU[j++]=0x05;
+ bufferU[j++]=0x58;
+ bufferU[j++]=0x88; //MOV W8,NVMKEY
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x38;
+ bufferU[j++]=0x20; //MOV 0xAA,W8
+ bufferU[j++]=0x0A;
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0x88; //MOV W8,NVMKEY
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x38;
+ bufferU[j++]=SIX_LONG; //BSET NVMCON,#WR
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0xE7;
+ bufferU[j++]=0x61;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX_LONG; //BCLR NVMCON,#WR
+ bufferU[j++]=0xA9;
+ bufferU[j++]=0xE7;
+ bufferU[j++]=0x61;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(6);
+ j=0;
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=6;
+ bufferU[j++]=0x24; //MOV 4066,W10
+ bufferU[j++]=0x06;
+ bufferU[j++]=0x6A;
+ bufferU[j++]=0x88; //MOV W10,NVMCON
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x0A;
+ bufferU[j++]=0x20; //MOV 0x55,W8
+ bufferU[j++]=0x05;
+ bufferU[j++]=0x58;
+ bufferU[j++]=0x88; //MOV W8,NVMKEY
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x38;
+ bufferU[j++]=0x20; //MOV 0xAA,W8
+ bufferU[j++]=0x0A;
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0x88; //MOV W8,NVMKEY
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x38;
+ bufferU[j++]=SIX_LONG; //BSET NVMCON,#WR
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0xE7;
+ bufferU[j++]=0x61;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX_LONG; //BCLR NVMCON,#WR
+ bufferU[j++]=0xA9;
+ bufferU[j++]=0xE7;
+ bufferU[j++]=0x61;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(4);
+ j=0;
+ }
+ else if(eewrite==1){ //30Fxx
+ bufferU[j++]=SIX; //MOV 0x7F,W0
+ bufferU[j++]=0x20;
+ bufferU[j++]=0x07;
+ bufferU[j++]=0xF0;
+ bufferU[j++]=SIX; //MOV W0,TABLPAG
+ bufferU[j++]=0x88;
+ if(newTABLPAG){
+ bufferU[j++]=0x02;
+ bufferU[j++]=0xA0;
+ }
+ else{
+ bufferU[j++]=0x01;
+ bufferU[j++]=0x90;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(1);
+ j=0;
+ }
+ //Write EEPROM
+ for(k2=0,i=0x1000-dim2;i<0x1000;i+=2){ //write 1 word (2 bytes)
+ if(memEE[i]<0xFF||memEE[i+1]<0xFF){
+ bufferU[j++]=SIX; //MOV i,W7
+ bufferU[j++]=0x2F;
+ bufferU[j++]=i>>4;
+ bufferU[j++]=((i<<4)&0xF0)+7;
+ bufferU[j++]=SIX; //MOV XXXX,W0
+ bufferU[j++]=0x20+((memEE[i+1]>>4)&0xF);
+ bufferU[j++]=((memEE[i+1]<<4)&0xF0)+((memEE[i]>>4)&0xF);
+ bufferU[j++]=(memEE[i]<<4)&0xF0;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX_LONG; //TBLWTL W0,[W7++]
+ bufferU[j++]=0xBB;
+ bufferU[j++]=0x1B;
+ bufferU[j++]=0x80;
+ if(eewrite==0){ //24FxxKAxx
+ bufferU[j++]=SIX_LONG; //BSET NVMCON,#WR
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0xE7;
+ bufferU[j++]=0x61;
+ }
+ else if(eewrite==1){ //30Fxxxx
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=6;
+ bufferU[j++]=0x24; //MOV 0x4004,W10
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x4A;
+ bufferU[j++]=0x88; //MOV W10,NVMCON
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x0A;
+ bufferU[j++]=0x20; //MOV 0x55,W8
+ bufferU[j++]=0x05;
+ bufferU[j++]=0x58;
+ bufferU[j++]=0x88; //MOV W8,NVMKEY
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x38;
+ bufferU[j++]=0x20; //MOV 0xAA,W8
+ bufferU[j++]=0x0A;
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0x88; //MOV W8,NVMKEY
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x38;
+ bufferU[j++]=SIX_LONG; //BSET NVMCON,#WR
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0xE7;
+ bufferU[j++]=0x61;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX_LONG; //BCLR NVMCON,#WR
+ bufferU[j++]=0xA9;
+ bufferU[j++]=0xE7;
+ bufferU[j++]=0x61;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(wait+2);
+ j=0;
+ PrintStatus(strings[S_CodeWriting],(i-0x1000+dim2)*100/(dim2),i); //"Scrittura: %d%%, ind. %03X"
+ if(RWstop) i=dim;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k,k); //"i=%d, k=%d 0=%d\n"
+ }
+ }
+ }
+ //Verify EEPROM
+ if(saveLog) fprintf(logfile,"\nVERIFY EEPROM:\n");
+ bufferU[j++]=SIX; //MOV 0xFE00,W6
+ bufferU[j++]=0x2F;
+ bufferU[j++]=EEbaseAddr>>4;
+ bufferU[j++]=0x06;
+ bufferU[j++]=SIX; //MOV #VISI,W7
+ bufferU[j++]=0x20;
+ bufferU[j++]=0x78;
+ bufferU[j++]=0x47;
+ bufferU[j++]=SIX; //GOTO 0x200
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=ICSP_NOP;
+ int errE=0;
+ for(i=k2=EEbaseAddr;i<EEbaseAddr+dim2;i+=2){
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ if(j>DIMBUF-7||i==dim2-4){
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(3);
+ for(z=0;z<DIMBUF-2;z++){
+ if(bufferI[z]==REGOUT){
+ CheckData(memEE[k2],bufferI[z+2],i,&errE);
+ CheckData(memEE[k2+1],bufferI[z+1],i+1,&errE);
+ z+=3;
+ k2+=2;
+ }
+ }
+ PrintStatus(strings[S_CodeReading],(i-EEbaseAddr)*100/(dim2),i); //"Read: %d%%, addr. %03X"
+ if(RWstop) i=EEbaseAddr+dim2;
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k2,k2); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ }
+ }
+ PrintStatusEnd();
+ PrintMessage1(strings[S_ComplErr],errE); //"completed: %d errors \r\n"
+ err+=errE;
+ PrintStatusClear();
+ }
+//****************** write CONFIG ********************
+ int written, read;
+ j=0;
+ if(config>2&&config<5&&err<max_err){ //config area @ 0xF80000
+ PrintMessage(strings[S_ConfigW]); //"Write CONFIG ..."
+ if(saveLog) fprintf(logfile,"\nWRITE CONFIG:\n");
+ int confword=(options&0xF0000)>>16;
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=6;
+ bufferU[j++]=0x20; //MOV 0xF8,W0
+ bufferU[j++]=0x0F;
+ bufferU[j++]=0x80;
+ bufferU[j++]=0x88; //MOV W0,TABLPAG
+ if(newTABLPAG){
+ bufferU[j++]=0x02;
+ bufferU[j++]=0xA0;
+ }
+ else{
+ bufferU[j++]=0x01;
+ bufferU[j++]=0x90;
+ }
+ bufferU[j++]=0x24; //MOV 0x400x,W10
+ bufferU[j++]=0x00;
+ if(confword==0)bufferU[j++]=0x0A; //0x4000
+ else if(confword==1)bufferU[j++]=0x3A; //0x4003
+ else if(confword==2)bufferU[j++]=0x4A; //0x4004
+ else if(confword==3)bufferU[j++]=0x8A; //0x4008
+ bufferU[j++]=0x88; //MOV W10,NVMCON
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x0A;
+ bufferU[j++]=0x20; //MOV 0,W7
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x07;
+ bufferU[j++]=0x04; //GOTO 0x200
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=ICSP_NOP;
+ for(i=0;i<12;i++){
+ //Write CONFIG
+ bufferU[j++]=SIX; //MOV XXXX,W0
+ bufferU[j++]=0x20;
+ bufferU[j++]=(memCONFIG[i*4]>>4)&0xF;
+ bufferU[j++]=(memCONFIG[i*4]<<4)&0xF0;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX_LONG; //TBLWTL W0,[W7++]
+ bufferU[j++]=0xBB;
+ bufferU[j++]=0x1B;
+ bufferU[j++]=0x80;
+ if(memCONFIG[i*4]<0xFF){ //write if not empty
+ bufferU[j++]=SIX_LONG; //BSET NVMCON,#WR
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0xE7;
+ bufferU[j++]=0x61;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ msDelay(27);
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,0,0); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ }
+ //Verify write
+ int errC=0;
+ bufferU[j++]=SIX;
+ bufferU[j++]=0x20; //MOV XXXX,W6
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x06;
+ bufferU[j++]=SIX;
+ bufferU[j++]=0x20; //MOV #VISI,W7
+ bufferU[j++]=0x78;
+ bufferU[j++]=0x47;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(3);
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],0xF80000,0xF80000,0,0); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ for(i=0,z=0;i<9;i++){
+ for(;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ written=memCONFIG[i*4];
+ read=bufferI[z+2]; //Low byte
+ if(~written&read)CheckData(written,read,0xF80000+i*2,&errC);
+ z+=3;
+ }
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(3);
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],0xF80000,0xF80000,0,0); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ for(z=0;i<12;i++){
+ for(;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ written=memCONFIG[i*4];
+ read=bufferI[z+2]; //Low byte
+ if(~written&read)CheckData(written,read,0xF80000+i*2,&errC);
+ z+=3;
+ }
+ PrintMessage1(strings[S_ComplErr],errC); //"completed: %d errors \r\n"
+ PrintStatusClear();
+ err+=errC;
+ }
+ else if(config>=5&&err<max_err){ //16 bit config area (30Fxxxx)
+ PrintMessage(strings[S_ConfigW]); //"Write CONFIG ..."
+ if(saveLog) fprintf(logfile,"\nWRITE CONFIG:\n");
+ int Nconf=config==5?7:8;
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=4;
+ bufferU[j++]=0x20; //MOV 0xF8,W0
+ bufferU[j++]=0x0F;
+ bufferU[j++]=0x80;
+ bufferU[j++]=0x88; //MOV W0,TABLPAG
+ if(newTABLPAG){
+ bufferU[j++]=0x02;
+ bufferU[j++]=0xA0;
+ }
+ else{
+ bufferU[j++]=0x01;
+ bufferU[j++]=0x90;
+ }
+ bufferU[j++]=0x20; //MOV 0,W7
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x07;
+ bufferU[j++]=0x04; //GOTO 0x200
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=ICSP_NOP;
+ for(i=0;i<Nconf;i++){
+ //Erase CONFIG
+ bufferU[j++]=SIX; //MOV 0xFFFF,W0
+ bufferU[j++]=0x2F;
+ bufferU[j++]=0xFF;
+ bufferU[j++]=0xF0;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX_LONG; //TBLWTL W0,[W7++]
+ bufferU[j++]=0xBB;
+ bufferU[j++]=0x1B;
+ bufferU[j++]=0x80;
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=6;
+ bufferU[j++]=0x24; //MOV 0x400x,W10
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x8A; //0x4008
+ bufferU[j++]=0x88; //MOV W10,NVMCON
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x0A;
+ bufferU[j++]=0x20; //MOV 0x55,W8
+ bufferU[j++]=0x05;
+ bufferU[j++]=0x58;
+ bufferU[j++]=0x88; //MOV W8,NVMKEY
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x38;
+ bufferU[j++]=0x20; //MOV 0xAA,W8
+ bufferU[j++]=0x0A;
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0x88; //MOV W8,NVMKEY
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x38;
+ bufferU[j++]=SIX_LONG; //BSET NVMCON,#WR
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0xE7;
+ bufferU[j++]=0x61;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX_LONG; //BCLR NVMCON,#WR
+ bufferU[j++]=0xA9;
+ bufferU[j++]=0xE7;
+ bufferU[j++]=0x61;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(3);
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,0,0); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ }
+ bufferU[j++]=SIX;
+ bufferU[j++]=0x20; //MOV 0,W7
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x07;
+ for(i=0;i<Nconf;i++){
+ int value=memCONFIG[i*4]+(memCONFIG[i*4+1]<<8);
+ //Write CONFIG
+ bufferU[j++]=SIX; //MOV XXXX,W0
+ bufferU[j++]=0x20+(value>>12);
+ bufferU[j++]=(value>>4);
+ bufferU[j++]=(value<<4);
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX_LONG; //TBLWTL W0,[W7++]
+ bufferU[j++]=0xBB;
+ bufferU[j++]=0x1B;
+ bufferU[j++]=0x80;
+ if(value<0xFFFF){ //write if not empty
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=6;
+ bufferU[j++]=0x24; //MOV 0x400x,W10
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x8A; //0x4008
+ bufferU[j++]=0x88; //MOV W10,NVMCON
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x0A;
+ bufferU[j++]=0x20; //MOV 0x55,W8
+ bufferU[j++]=0x05;
+ bufferU[j++]=0x58;
+ bufferU[j++]=0x88; //MOV W8,NVMKEY
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x38;
+ bufferU[j++]=0x20; //MOV 0xAA,W8
+ bufferU[j++]=0x0A;
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0x88; //MOV W8,NVMKEY
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x38;
+ bufferU[j++]=SIX_LONG; //BSET NVMCON,#WR
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0xE7;
+ bufferU[j++]=0x61;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX_LONG; //BCLR NVMCON,#WR
+ bufferU[j++]=0xA9;
+ bufferU[j++]=0xE7;
+ bufferU[j++]=0x61;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(3);
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,0,0); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ }
+ //Verify write
+ int errC=0;
+ bufferU[j++]=SIX;
+ bufferU[j++]=0x20; //MOV XXXX,W6
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x06;
+ bufferU[j++]=SIX;
+ bufferU[j++]=0x20; //MOV #VISI,W7
+ bufferU[j++]=0x78;
+ bufferU[j++]=0x47;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(3);
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],0xF80000,0xF80000,0,0); //"i=%d(0x%X), k=%d(0x%X)\n"
+ }
+ for(i=0,z=0;i<7;i++){
+ for(;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ written=memCONFIG[i*4+1]+(memCONFIG[i*4]<<8);
+ read=bufferI[z+1]+(bufferI[z+2]<<8);
+ if(~written&read)CheckData(written,read,0xF80000+i*2,&errC); //16 bit
+ z+=3;
+ }
+ PrintMessage1(strings[S_ComplErr],errC); //"completed: %d errors \r\n"
+ PrintStatusClear();
+ err+=errC;
+ }
+//****************** exit ********************
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=EN_VPP_VCC; //0
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ unsigned int stop=GetTickCount();
+ sprintf(str,strings[S_EndErr],(stop-start)/1000.0,err,err!=1?strings[S_ErrPlur]:strings[S_ErrSing]); //"\r\nEnd (%.2f s) %d %s\r\n\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+ PrintStatusClear(); //clear status report
+}
+
+void Write24Ex(int dim,int dim2,int options,int appIDaddr,int rowSize, double wait){
+// write 16 bit PIC 24Exxxx
+// deviceID @ 0xFF0000
+// dim = program size (16 bit words)
+// dim2 = dummy parameter
+// options = dummy parameter
+// appIDaddr = dummy parameter
+// rowSize = dummy parameter
+// wait = dummy parameter
+ int k=0,k2=0,z=0,i,j;
+ int err=0;
+ if(FWVersion<0x900){
+ PrintMessage1(strings[S_FWver2old],"0.9.0"); //"This firmware is too old. Version %s is required\r\n"
+ return;
+ }
+ if(!CheckV33Regulator()){
+ PrintMessage(strings[S_noV33reg]); //Can't find 3.3V expansion board
+ return;
+ }
+ if(saveLog){
+ OpenLogFile();
+ fprintf(logfile,"Write24Ex(%d,%d,%d,%d,%d,%.1f) (0x%X,0x%X,0x%X,0x%X,0x%X,%.3f)\n"
+ ,dim,dim2,options,appIDaddr,rowSize,wait,dim,dim2,options,appIDaddr,rowSize,wait);
+ }
+ dim*=2; //from words to bytes
+ if(dim>0x100000||dim<0){
+ PrintMessage(strings[S_CodeLim]); //"Code size out of limits\r\n"
+ return;
+ }
+ if(dim>size) for(i=size;i<dim;i++) memCODE[i]=0xFF; //fill with 0xFF to avoid unintended writing
+ if(dim<1){
+ PrintMessage(strings[S_NoCode]); //"Empty code area\r\n"
+ return;
+ }
+ StartHVReg(-1); //LVP: current limited to (5-0.7-3.6)/10k = 50uA
+ //last 10 program words
+ for(i=0;i<10;i++) PrintMessage3("CONFIG%d(0x%05X): 0x%02X\r\n",i,(dim-40+i*4)/2,memCODE[dim-40+i*4]);
+ unsigned int start=GetTickCount();
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2000>>8;
+ bufferU[j++]=2000&0xff;
+ bufferU[j++]=EN_VPP_VCC; //enter program mode
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=WAIT_T2;
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC; //VDD + VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=TX16;
+ bufferU[j++]=2;
+ bufferU[j++]=0x4D;
+ bufferU[j++]=0x43;
+ bufferU[j++]=0x48;
+ bufferU[j++]=0x51;
+ bufferU[j++]=WAIT_T3; //min 1ms
+ bufferU[j++]=EN_VPP_VCC; //VDD + VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=55000>>8;
+ bufferU[j++]=55000&0xff;
+ bufferU[j++]=WAIT_T3; //min 50ms
+ //Additional 5 clock cycles upon entering program mode
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0; //CK=0
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x4; //CK=1
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0; //CK=0
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x4; //CK=1
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0; //CK=0
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x4; //CK=1
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0; //CK=0
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x4; //CK=1
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0; //CK=0
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x4; //CK=1
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0; //CK=0
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX; //GOTO 0x200
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(65);
+ j=0;
+ //Read DeviceID @0xFF0000, DevRev @0xFF0002
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=4;
+ bufferU[j++]=0x20; //MOV XXXX,W0
+ bufferU[j++]=0x0F;
+ bufferU[j++]=0xF0; //0xFF
+ bufferU[j++]=0x88; //MOV W0,TABLPAG
+ bufferU[j++]=0x02;
+ bufferU[j++]=0xA0;
+ bufferU[j++]=0x20; //MOV XXXX,W6
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x06; //0x0000
+ bufferU[j++]=0x20; //MOV #VISI,W7
+ bufferU[j++]=0xF8;
+ bufferU[j++]=0x87;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX_LONG5; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG5; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG5; //GOTO 0x200
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ int w0=0,w1=0;
+ for(z=0;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2) w0=(bufferI[z+1]<<8)+bufferI[z+2];
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2) w1=(bufferI[z+1]<<8)+bufferI[z+2];
+ PrintMessage2("DevID: 0x%04X\r\nDevRev: 0x%04X\r\n",w0,w1);
+ PIC24_ID(w0);
+ //Read ApplicationID @ appIDaddr
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=0x44; //append 1 NOP
+ bufferU[j++]=0x20; //MOV XXXX,W0
+ bufferU[j++]=0x08;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x88; //MOV W0,TABLPAG
+ bufferU[j++]=0x02;
+ bufferU[j++]=0xA0;
+ bufferU[j++]=0x20+((appIDaddr>>12)&0xF); //MOV XXXX,W6
+ bufferU[j++]=(appIDaddr>>4)&0xFF;
+ bufferU[j++]=((appIDaddr<<4)&0xF0)+6;
+ bufferU[j++]=0x20; //MOV #VISI,W7
+ bufferU[j++]=0xF8;
+ bufferU[j++]=0x87;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX_LONG5; //TBLRDL [W6],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0x96;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG5; //GOTO 0x200
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2000>>8;
+ bufferU[j++]=2000&0xff;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ for(z=0;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2) w0=(bufferI[z+1]<<8)+bufferI[z+2];
+ PrintMessage2("ApplicationID @ 0x80%04X: 0x%04X\r\n",appIDaddr,w0);
+//****************** erase memory ********************
+ PrintMessage(strings[S_StartErase]); //"Erase ... "
+ if(saveLog) fprintf(logfile,"\nERASE:\n");
+ //bulk erase command
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=2;
+ bufferU[j++]=0x24; //MOV 400D,W10
+ bufferU[j++]=0x00;
+ bufferU[j++]=0xDA;
+ bufferU[j++]=0x88; //MOV W10,NVMCON
+ bufferU[j++]=0x39;
+ bufferU[j++]=0x4A;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX; //MOV NVMCON,W0
+ bufferU[j++]=0x80;
+ bufferU[j++]=0x39;
+ bufferU[j++]=0x40;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX; //MOV W0,VISI
+ bufferU[j++]=0x88;
+ bufferU[j++]=0x7C;
+ bufferU[j++]=0x40;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=4;
+ bufferU[j++]=0x20; //MOV 0x55,W1
+ bufferU[j++]=0x05;
+ bufferU[j++]=0x51;
+ bufferU[j++]=0x88; //MOV W1,NVMKEY
+ bufferU[j++]=0x39;
+ bufferU[j++]=0x71;
+ bufferU[j++]=0x20; //MOV 0xAA,W1
+ bufferU[j++]=0x0A;
+ bufferU[j++]=0xA1;
+ bufferU[j++]=0x88; //MOV W8,NVMKEY
+ bufferU[j++]=0x39;
+ bufferU[j++]=0x71;
+ bufferU[j++]=SIX_LONG5; //BSET NVMCON,#WR
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0xE7;
+ bufferU[j++]=0x29;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX; //MOV NVMCON,W0
+ bufferU[j++]=0x80;
+ bufferU[j++]=0x39;
+ bufferU[j++]=0x40;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX; //MOV W0,VISI
+ bufferU[j++]=0x88;
+ bufferU[j++]=0x7C;
+ bufferU[j++]=0x40;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(4);
+ j=0;
+ for(z=0;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ w0=bufferI[z+1]&0x80;
+ w0=1;
+ //Wait for erase completion (max 500m)
+ bufferU[j++]=SIX; //MOV NVMCON,W0
+ bufferU[j++]=0x80;
+ bufferU[j++]=0x39;
+ bufferU[j++]=0x40;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX; //MOV W0,VISI
+ bufferU[j++]=0x88;
+ bufferU[j++]=0x7C;
+ bufferU[j++]=0x40;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ j=0;
+ for(i=0;i<50&&w0;i++){
+ PacketIO(5);
+ for(z=0;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ w0=bufferI[z+1]&0x80;
+ msDelay(10);
+ }
+ if(saveLog) fprintf(logfile,"ERASE TIME: %d ms\n",i*10);
+ msDelay(70);/*erase time seems always too low*/
+//****************** prepare write ********************
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX;
+ bufferU[j++]=0x04; //GOTO 0x200
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=4;
+ bufferU[j++]=0x20; //MOV 0xFA,W12
+ bufferU[j++]=0x0F;
+ bufferU[j++]=0xAC;
+ bufferU[j++]=0x88; //MOV W12,TABLPAG
+ bufferU[j++]=0x02;
+ bufferU[j++]=0xAC;
+ bufferU[j++]=0x24; //MOV XXXX,W10
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x1A; //0x4001
+ bufferU[j++]=0x88; //MOV W10,NVMCON
+ bufferU[j++]=0x39;
+ bufferU[j++]=0x4A;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ PrintMessage(strings[S_Compl]); //"completed\r\n"
+//****************** write code ********************
+ PrintMessage(strings[S_StartCodeProg]); //"Write code ... "
+ if(saveLog) fprintf(logfile,"\nWRITE CODE:\n");
+ PrintStatusSetup();
+ int valid,High=0;
+// instruction words are stored in code memory array as follows:
+// L0 M0 H0 FF L1 M1 H1 FF ...
+// use 2 write latches @ 0xFA0000
+ for(i=0,k=0;i<dim;i+=2*4){ //write 2 instruction words
+ //skip row if empty
+ for(valid=0;!valid&&i<dim;i+=valid?0:2*4){
+ for(k2=0;k2<2*4&&!valid;k2++) if(memCODE[i+k2]<0xFF) valid=1;
+ }
+ if(i>=dim) break;
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=5;
+ bufferU[j++]=0xEB; //CLR W6
+ bufferU[j++]=0x03;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0xEB; //CLR W7
+ bufferU[j++]=0x03;
+ bufferU[j++]=0x80;
+ bufferU[j++]=0x20+((memCODE[i+1]>>4)&0xF); //MOV LSW0,W0
+ bufferU[j++]=((memCODE[i+1]<<4)&0xF0)+((memCODE[i]>>4)&0xF);
+ bufferU[j++]=(memCODE[i]<<4)&0xF0;
+ bufferU[j++]=0x20+((memCODE[i+6]>>4)&0xF); //MOV MSB1:MSB0,W1
+ bufferU[j++]=((memCODE[i+6]<<4)&0xF0)+((memCODE[i+2]>>4)&0xF);
+ bufferU[j++]=((memCODE[i+2]<<4)&0xF0)+1;
+ bufferU[j++]=0x20+((memCODE[i+5]>>4)&0xF); //MOV LSW1,W2
+ bufferU[j++]=((memCODE[i+5]<<4)&0xF0)+((memCODE[i+4]>>4)&0xF);
+ bufferU[j++]=((memCODE[i+4]<<4)&0xF0)+2;
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=0x84; //Append 2 NOP
+ bufferU[j++]=0xBB; //TBLWTL [W6++],[W7]
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=0xBB; //TBLWTH.B [W6++],[W7++]
+ bufferU[j++]=0xDB;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=0xBB; //TBLWTH.B [W6++],[++W7]
+ bufferU[j++]=0xEB;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=0xBB; //TBLWTL [W6++],[W7++]
+ bufferU[j++]=0x1B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=8;
+ bufferU[j++]=0x20+((i>>13)&0xF); //MOV i/2,W3
+ bufferU[j++]=(i>>5)&0xFF;
+ bufferU[j++]=((i<<3)&0xF0)+3;
+ bufferU[j++]=0x20; //MOV i/2/64K,W4
+ bufferU[j++]=(i>>21)&0xFF;
+ bufferU[j++]=((i>>13)&0xF0)+4;
+ bufferU[j++]=0x88; //MOV W3,NVMADR
+ bufferU[j++]=0x39;
+ bufferU[j++]=0x53;
+ bufferU[j++]=0x88; //MOV W4,NVMADRU
+ bufferU[j++]=0x39;
+ bufferU[j++]=0x64;
+ bufferU[j++]=0x20; //MOV 0x55,W1
+ bufferU[j++]=0x05;
+ bufferU[j++]=0x51;
+ bufferU[j++]=0x88; //MOV W1,NVMKEY
+ bufferU[j++]=0x39;
+ bufferU[j++]=0x71;
+ bufferU[j++]=0x20; //MOV 0xAA,W1
+ bufferU[j++]=0x0A;
+ bufferU[j++]=0xA1;
+ bufferU[j++]=0x88; //MOV W1,NVMKEY
+ bufferU[j++]=0x39;
+ bufferU[j++]=0x71;
+ bufferU[j++]=SIX_LONG5; //BSET NVMCON,#WR
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0xE7;
+ bufferU[j++]=0x29;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ PrintStatus(strings[S_CodeWriting2],i*100/(dim+dim2),i/2); //"Write: %d%%,addr. %04X"
+ if(RWstop) i=dim;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i/2,i/2,k,k); //"i=%d, k=%d 0=%d\n"
+ }
+ //GOTO 0x200 is necessary to correctly write (???)
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX; //MOV NVMCON,W2
+ bufferU[j++]=0x80;
+ bufferU[j++]=0x39;
+ bufferU[j++]=0x42;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX; //MOV W2,VISI
+ bufferU[j++]=0x88;
+ bufferU[j++]=0x7C;
+ bufferU[j++]=0x42;
+ bufferU[j++]=REGOUT;/**/
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX;
+ bufferU[j++]=0x04; //GOTO 0x200
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ j=0;
+ PacketIO(2);
+ }
+ PrintStatusEnd();
+ PrintMessage(strings[S_Compl]); //"completed\r\n"
+//****************** verify code ********************
+ PrintMessage(strings[S_CodeV]); //"Verify code ... "
+ if(saveLog) fprintf(logfile,"\nVERIFY CODE:\n");
+ PrintStatusSetup();
+//Read 4 24 bit words packed in 6 16 bit words
+//memory address advances by 16 bytes because of alignment
+ High=0xE0000000;
+ int r0=0,r1=0,r2=0,r3=0,w3,w2;
+ for(i=0;i<dim;i+=16){
+ //skip row if empty
+ for(valid=0;!valid&&i<dim;i+=valid?0:16){
+ for(k2=0;k2<16&&!valid;k2++) if(memCODE[i+k2]<0xFF) valid=1;
+ }
+ if(i>=dim) break;
+ if((i>>17)!=High){ //advance page
+ bufferU[j++]=SIX; //MOV XXXX,W0
+ bufferU[j++]=0x20;
+ bufferU[j++]=(i>>21)&0xFF;
+ bufferU[j++]=(i>>13)&0xF0;
+ bufferU[j++]=SIX; //MOV W0,TABLPAG
+ bufferU[j++]=0x88;
+ bufferU[j++]=0x02;
+ bufferU[j++]=0xA0;
+ bufferU[j++]=SIX_LONG; //GOTO 0x200
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ High=i>>17;
+ }
+ bufferU[j++]=SIX; //MOV i/2,W6
+ bufferU[j++]=0x20+((i>>13)&0xF);
+ bufferU[j++]=(i>>5)&0xFF;
+ bufferU[j++]=((i<<3)&0xF0)+6;
+ bufferU[j++]=SIX; //MOV #VISI,W7
+ bufferU[j++]=0x20;
+ bufferU[j++]=0xF8;
+ bufferU[j++]=0x87;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX_LONG5; //TBLRDL [W6],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0x96;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG5; //TBLRDH.B [W6++],[W7++]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0xDB;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=SIX_LONG5; //TBLRDH.B [++W6],[W7--]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0xD3;
+ bufferU[j++]=0xD6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG5; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG5; //TBLRDL [W6],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0x96;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG5; //TBLRDH.B [W6++],[W7++]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0xDB;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=SIX_LONG5; //TBLRDH.B [++W6],[W7--]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0xD3;
+ bufferU[j++]=0xD6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG5; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG5; //GOTO 0x200
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(4);
+ PrintStatus(strings[S_CodeV2],i*100/(dim+dim2),i/2); //"Verify: %d%%, addr. %04X"
+ if(RWstop) i=dim;
+ for(z=0;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ r0=(bufferI[z+1]<<8)+bufferI[z+2];
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ r0+=bufferI[z+2]<<16;
+ r1=bufferI[z+1]<<16;
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ r1+=(bufferI[z+1]<<8)+bufferI[z+2];
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ r2=(bufferI[z+1]<<8)+bufferI[z+2];
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ r2+=bufferI[z+2]<<16;
+ r3=bufferI[z+1]<<16;
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ r3+=(bufferI[z+1]<<8)+bufferI[z+2];
+ }
+ w0=(memCODE[i+2]<<16)+(memCODE[i+1]<<8)+memCODE[i];
+ w1=(memCODE[i+6]<<16)+(memCODE[i+5]<<8)+memCODE[i+4];
+ w2=(memCODE[i+10]<<16)+(memCODE[i+9]<<8)+memCODE[i+8];
+ w3=(memCODE[i+14]<<16)+(memCODE[i+13]<<8)+memCODE[i+12];
+ CheckData(w0,r0,i/2,&err);
+ CheckData(w1,r1,i/2+2,&err);
+ CheckData(w2,r2,i/2+4,&err);
+ CheckData(w3,r3,i/2+6,&err);
+ PrintStatus(strings[S_CodeV2],i*100/dim,i/2); //"Verify: %d%%, addr. %05X"
+ j=0;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i/2,i/2,k,k,err); //"i=%d, k=%d, errori=%d\n"
+ }
+ if(err>=max_err) break;
+ }
+ PrintStatusEnd();
+ PrintMessage1(strings[S_ComplErr],err); //"completed: %d errors\r\n"
+ if(err>=max_err){
+ PrintMessage1(strings[S_MaxErr],err); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ }
+//****************** exit ********************
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=EN_VPP_VCC; //0
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ unsigned int stop=GetTickCount();
+ sprintf(str,strings[S_EndErr],(stop-start)/1000.0,err,err!=1?strings[S_ErrPlur]:strings[S_ErrSing]); //"\r\nEnd (%.2f s) %d %s\r\n\r\n"
+ PrintMessage(str);
+ if(saveLog){
+ fprintf(logfile,str);
+ CloseLogFile();
+ }
+ PrintStatusClear(); //clear status report
+}
diff --git a/progP24.h b/progP24.h
new file mode 100644
index 0000000..1db78f7
--- /dev/null
+++ b/progP24.h
@@ -0,0 +1,7 @@
+void Read24Fx(int dim,int dim2,int options,int appIDaddr,int executiveArea);
+void Write24Fx(int dim,int dim2,int options,int appIDaddr,int rowSize, double wait);
+void DisplayCODE24F(int dim);
+void DisplayEE24F();
+void Read24Ex(int dim,int dim2,int options,int appIDaddr,int executiveArea);
+void Write24Ex(int dim,int dim2,int options,int appIDaddr,int rowSize, double wait);
+
diff --git a/progP32.c b/progP32.c
new file mode 100644
index 0000000..9416eed
--- /dev/null
+++ b/progP32.c
@@ -0,0 +1,2454 @@
+/**
+ * \file progP32.c - algorithms to program the PIC32 family of microcontrollers
+ * Copyright (C) 2019 Alberto Maccioni
+ *
+ * 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"
+
+/*#ifdef _MSC_VER
+void COpenProgDlg::CheckData(int a,int b,int addr,int *err)
+#else
+void CheckData(int a,int b,int addr,int *err)
+#endif
+{
+ if(a!=b){
+#ifdef _MSC_VER
+ CString str;
+#endif
+ PrintMessage(strings[S_NL]);
+ PrintMessage4(strings[S_CodeVError],addr,addr,a,b); //"Error writing address %4X: written %02X, read %02X\r\n"
+ (*err)++;
+ }
+}
+*/
+struct ID32{
+ int id;
+ char *device;
+} PIC32LIST[]={
+ {0x0938053,"PIC32MX360F512L"},
+ {0x0934053,"PIC32MX360F256L"},
+ {0x092D053,"PIC32MX340F128L"},
+ {0x092A053,"PIC32MX320F128L"},
+ {0x0916053,"PIC32MX340F512H"},
+ {0x0912053,"PIC32MX340F256H"},
+ {0x090D053,"PIC32MX340F128H"},
+ {0x090A053,"PIC32MX320F128H"},
+ {0x0906053,"PIC32MX320F064H"},
+ {0x0902053,"PIC32MX320F032H"},
+ {0x0978053,"PIC32MX460F512L"},
+ {0x0974053,"PIC32MX460F256L"},
+ {0x096D053,"PIC32MX440F128L"},
+ {0x0952053,"PIC32MX440F256H"},
+ {0x0956053,"PIC32MX440F512H"},
+ {0x094D053,"PIC32MX440F128H"},
+ {0x0942053,"PIC32MX420F032H"},
+ {0x04317053,"PIC32MX575F256H"},
+ {0x0430B053,"PIC32MX675F256H"},
+ {0x04303053,"PIC32MX775F256H"},
+ {0x04309053,"PIC32MX575F512H"},
+ {0x0430C053,"PIC32MX675F512H"},
+ {0x04325053,"PIC32MX695F512H"},
+ {0x0430D053,"PIC32MX775F512H"},
+ {0x0430E053,"PIC32MX795F512H"},
+ {0x04333053,"PIC32MX575F256L"},
+ {0x04305053,"PIC32MX675F256L"},
+ {0x04312053,"PIC32MX775F256L"},
+ {0x0430F053,"PIC32MX575F512L"},
+ {0x04311053,"PIC32MX675F512L"},
+ {0x04341053,"PIC32MX695F512L"},
+ {0x04307053,"PIC32MX775F512L"},
+ {0x04307053,"PIC32MX795F512L"},
+ {0x04400053,"PIC32MX534F064H"},
+ {0x04401053,"PIC32MX564F064H"},
+ {0x04403053,"PIC32MX564F128H"},
+ {0x04405053,"PIC32MX664F064H"},
+ {0x04407053,"PIC32MX664F128H"},
+ {0x0440B053,"PIC32MX764F128H"},
+ {0x0440C053,"PIC32MX534F064L"},
+ {0x0440D053,"PIC32MX564F064L"},
+ {0x0440F053,"PIC32MX564F128L"},
+ {0x04411053,"PIC32MX664F064L"},
+ {0x04413053,"PIC32MX664F128L"},
+ {0x04417053,"PIC32MX764F128L"},
+ {0x04A07053,"PIC32MX110F016B"},
+ {0x04A09053,"PIC32MX110F016C"},
+ {0x04A0B053,"PIC32MX110F016D"},
+ {0x04A01053,"PIC32MX210F016B"},
+ {0x04A03053,"PIC32MX210F016C"},
+ {0x04A05053,"PIC32MX210F016D"},
+ {0x04A06053,"PIC32MX120F032B"},
+ {0x04A08053,"PIC32MX120F032C"},
+ {0x04A0A053,"PIC32MX120F032D"},
+ {0x04A00053,"PIC32MX220F032B"},
+ {0x04A02053,"PIC32MX220F032C"},
+ {0x04A04053,"PIC32MX220F032D"},
+ {0x04D07053,"PIC32MX130F064B"},
+ {0x04D09053,"PIC32MX130F064C"},
+ {0x04D0B053,"PIC32MX130F064D"},
+ {0x04D01053,"PIC32MX230F064B"},
+ {0x04D03053,"PIC32MX230F064C"},
+ {0x04D05053,"PIC32MX230F064D"},
+ {0x04D06053,"PIC32MX150F128B"},
+ {0x04D08053,"PIC32MX150F128C"},
+ {0x04D0A053,"PIC32MX150F128D"},
+ {0x04D00053,"PIC32MX250F128B"},
+ {0x04D02053,"PIC32MX250F128C"},
+ {0x04D04053,"PIC32MX250F128D"},
+ {0x06610053,"PIC32MX170F256B"},
+ {0x0661A053,"PIC32MX170F256D"},
+ {0x06600053,"PIC32MX270F256B"},
+ {0x0660A053,"PIC32MX270F256D"},
+ {0x0660C053,"PIC32MX270F256DB"},
+ {0x06703053,"PIC32MX130F256B"},
+ {0x06705053,"PIC32MX130F256D"},
+ {0x06700053,"PIC32MX230F256B"},
+ {0x06702053,"PIC32MX230F256D"},
+ {0x05600053,"PIC32MX330F064H"},
+ {0x05601053,"PIC32MX330F064L"},
+ {0x05704053,"PIC32MX350F256H"},
+ {0x05705053,"PIC32MX350F256L"},
+ {0x05602053,"PIC32MX430F064H"},
+ {0x05603053,"PIC32MX430F064L"},
+ {0x05706053,"PIC32MX450F256H"},
+ {0x05707053,"PIC32MX450F256L"},
+ {0x0570C053,"PIC32MX350F128H"},
+ {0x0570D053,"PIC32MX350F128L"},
+ {0x0570E053,"PIC32MX450F128H"},
+ {0x0570F053,"PIC32MX450F128L"},
+ {0x05808053,"PIC32MX370F512H"},
+ {0x05809053,"PIC32MX370F512L"},
+ {0x0580A053,"PIC32MX470F512H"},
+ {0x0580B053,"PIC32MX470F512L"},
+ {0x05710053,"PIC32MX450F256HB"},
+ {0x05811053,"PIC32MX470F512LB"},
+ {0x05103053,"PIC32MZ1024ECG064"},
+ {0x05108053,"PIC32MZ1024ECH064"},
+ {0x05130053,"PIC32MZ1024ECM064"},
+ {0x05104053,"PIC32MZ2048ECG064"},
+ {0x05109053,"PIC32MZ2048ECH064"},
+ {0x05131053,"PIC32MZ2048ECM064"},
+ {0x0510D053,"PIC32MZ1024ECG100"},
+ {0x05112053,"PIC32MZ1024ECH100"},
+ {0x0513A053,"PIC32MZ1024ECM100"},
+ {0x0510E053,"PIC32MZ2048ECG100"},
+ {0x05113053,"PIC32MZ2048ECH100"},
+ {0x0513B053,"PIC32MZ2048ECM100"},
+ {0x05117053,"PIC32MZ1024ECG124"},
+ {0x0511C053,"PIC32MZ1024ECH124"},
+ {0x05144053,"PIC32MZ1024ECM124"},
+ {0x05118053,"PIC32MZ2048ECG124"},
+ {0x0511D053,"PIC32MZ2048ECH124"},
+ {0x05145053,"PIC32MZ2048ECM124"},
+ {0x05121053,"PIC32MZ1024ECG144"},
+ {0x05126053,"PIC32MZ1024ECH144"},
+ {0x0514E053,"PIC32MZ1024ECM144"},
+ {0x05122053,"PIC32MZ2048ECG144"},
+ {0x05127053,"PIC32MZ2048ECH144"},
+ {0x0514F053,"PIC32MZ2048ECM144"},
+ {0x06A10053,"PIC32MX150F256H"},
+ {0x06A11053,"PIC32MX150F256L"},
+ {0x06A30053,"PIC32MX170F512H"},
+ {0x06A31053,"PIC32MX170F512L"},
+ {0x06A12053,"PIC32MX250F256H"},
+ {0x06A13053,"PIC32MX250F256L"},
+ {0x06A32053,"PIC32MX270F512H"},
+ {0x06A33053,"PIC32MX270F512L"},
+ {0x06A14053,"PIC32MX550F256H"},
+ {0x06A15053,"PIC32MX550F256L"},
+ {0x06A34053,"PIC32MX570F512H"},
+ {0x06A35053,"PIC32MX570F512L"},
+ {0x06A50053,"PIC32MX120F064H"},
+ {0x06A00053,"PIC32MX130F128H"},
+ {0x06A01053,"PIC32MX130F128L"},
+ {0x06A02053,"PIC32MX230F128H"},
+ {0x06A03053,"PIC32MX230F128L"},
+ {0x06A04053,"PIC32MX530F128H"},
+ {0x06A05053,"PIC32MX530F128L"},
+ {0x07201053,"PIC32MZ0512EFE064"},
+ {0x07206053,"PIC32MZ0512EFF064"},
+ {0x0722E053,"PIC32MZ0512EFK064"},
+ {0x07202053,"PIC32MZ1024EFE064"},
+ {0x07207053,"PIC32MZ1024EFF064"},
+ {0x0722F053,"PIC32MZ1024EFK064"},
+ {0x07203053,"PIC32MZ1024EFG064"},
+ {0x07208053,"PIC32MZ1024EFH064"},
+ {0x07230053,"PIC32MZ1024EFM064"},
+ {0x07204053,"PIC32MZ2048EFG064"},
+ {0x07209053,"PIC32MZ2048EFH064"},
+ {0x07231053,"PIC32MZ2048EFM064"},
+ {0x0720B053,"PIC32MZ0512EFE100"},
+ {0x07210053,"PIC32MZ0512EFF100"},
+ {0x07238053,"PIC32MZ0512EFK100"},
+ {0x0720C053,"PIC32MZ1024EFE100"},
+ {0x07211053,"PIC32MZ1024EFF100"},
+ {0x07239053,"PIC32MZ1024EFK100"},
+ {0x0720D053,"PIC32MZ1024EFG100"},
+ {0x07212053,"PIC32MZ1024EFH100"},
+ {0x0723A053,"PIC32MZ1024EFM100"},
+ {0x0720E053,"PIC32MZ2048EFG100"},
+ {0x07213053,"PIC32MZ2048EFH100"},
+ {0x0723B053,"PIC32MZ2048EFM100"},
+ {0x07215053,"PIC32MZ0512EFE124"},
+ {0x0721A053,"PIC32MZ0512EFF124"},
+ {0x07242053,"PIC32MZ0512EFK124"},
+ {0x07216053,"PIC32MZ1024EFE124"},
+ {0x0721B053,"PIC32MZ1024EFF124"},
+ {0x07243053,"PIC32MZ1024EFK124"},
+ {0x07217053,"PIC32MZ1024EFG124"},
+ {0x0721C053,"PIC32MZ1024EFH124"},
+ {0x07244053,"PIC32MZ1024EFM124"},
+ {0x07218053,"PIC32MZ2048EFG124"},
+ {0x0721D053,"PIC32MZ2048EFH124"},
+ {0x07245053,"PIC32MZ2048EFM124"},
+ {0x0721F053,"PIC32MZ0512EFE144"},
+ {0x07224053,"PIC32MZ0512EFF144"},
+ {0x0724C053,"PIC32MZ0512EFK144"},
+ {0x07220053,"PIC32MZ1024EFE144"},
+ {0x07225053,"PIC32MZ1024EFF144"},
+ {0x0724D053,"PIC32MZ1024EFK144"},
+ {0x07221053,"PIC32MZ1024EFG144"},
+ {0x07226053,"PIC32MZ1024EFH144"},
+ {0x0724E053,"PIC32MZ1024EFM144"},
+ {0x07222053,"PIC32MZ2048EFG144"},
+ {0x07227053,"PIC32MZ2048EFH144"},
+ {0x0724F053,"PIC32MZ2048EFM144"},
+ {0x05F0C053,"PIC32MZ1025DAA169"},
+ {0x05F0D053,"PIC32MZ1025DAB169"},
+ {0x05F0F053,"PIC32MZ1064DAA169"},
+ {0x05F10053,"PIC32MZ1064DAB169"},
+ {0x05F15053,"PIC32MZ2025DAA169"},
+ {0x05F16053,"PIC32MZ2025DAB169"},
+ {0x05F18053,"PIC32MZ2064DAA169"},
+ {0x05F19053,"PIC32MZ2064DAB169"},
+ {0x05F42053,"PIC32MZ1025DAG169"},
+ {0x05F43053,"PIC32MZ1025DAH169"},
+ {0x05F45053,"PIC32MZ1064DAG169"},
+ {0x05F46053,"PIC32MZ1064DAH169"},
+ {0x05F4B053,"PIC32MZ2025DAG169"},
+ {0x05F4C053,"PIC32MZ2025DAH169"},
+ {0x05F4E053,"PIC32MZ2064DAG169"},
+ {0x05F4F053,"PIC32MZ2064DAH169"},
+ {0x05F78053,"PIC32MZ1025DAA176"},
+ {0x05F79053,"PIC32MZ1025DAB176"},
+ {0x05F7B053,"PIC32MZ1064DAA176"},
+ {0x05F7C053,"PIC32MZ1064DAB176"},
+ {0x05F81053,"PIC32MZ2025DAA176"},
+ {0x05F82053,"PIC32MZ2025DAB176"},
+ {0x05F84053,"PIC32MZ2064DAA176"},
+ {0x05F85053,"PIC32MZ2064DAB176"},
+ {0x05FAE053,"PIC32MZ1025DAG176"},
+ {0x05FAF053,"PIC32MZ1025DAH176"},
+ {0x05FB1053,"PIC32MZ1064DAG176"},
+ {0x05FB2053,"PIC32MZ1064DAH176"},
+ {0x05FB7053,"PIC32MZ2025DAG176"},
+ {0x05FB8053,"PIC32MZ2025DAH176"},
+ {0x05FBA053,"PIC32MZ2064DAG176"},
+ {0x05FBB053,"PIC32MZ2064DAH176"},
+ {0x05F5D053,"PIC32MZ1025DAA288"},
+ {0x05F5E053,"PIC32MZ1025DAB288"},
+ {0x05F60053,"PIC32MZ1064DAA288"},
+ {0x05F61053,"PIC32MZ1064DAB288"},
+ {0x05F66053,"PIC32MZ2025DAA288"},
+ {0x05F67053,"PIC32MZ2025DAB288"},
+ {0x05F69053,"PIC32MZ2064DAA288"},
+ {0x05F6A053,"PIC32MZ2064DAB288"},
+ {0x07800053,"PIC32MX154F128B"},
+ {0x07804053,"PIC32MX154F128D"},
+ {0x07808053,"PIC32MX155F128B"},
+ {0x0780C053,"PIC32MX155F128D"},
+ {0x07801053,"PIC32MX174F256B"},
+ {0x07805053,"PIC32MX174F256D"},
+ {0x07809053,"PIC32MX175F256B"},
+ {0x0780D053,"PIC32MX175F256D"},
+ {0x07802053,"PIC32MX254F128B"},
+ {0x07806053,"PIC32MX254F128D"},
+ {0x0780A053,"PIC32MX255F128B"},
+ {0x0780E053,"PIC32MX255F128D"},
+ {0x07803053,"PIC32MX274F256B"},
+ {0x07807053,"PIC32MX274F256D"},
+ {0x0780B053,"PIC32MX275F256B"},
+ {0x0780F053,"PIC32MX275F256D"},
+ {0x06211053,"PIC32MK0512GPD064"},
+ {0x0620E053,"PIC32MK1024GPD064"},
+ {0x06210053,"PIC32MK0512GPD100"},
+ {0x0620D053,"PIC32MK1024GPD100"},
+ {0x0620B053,"PIC32MK0512GPE064"},
+ {0x06208053,"PIC32MK1024GPE064"},
+ {0x0620A053,"PIC32MK0512GPE100"},
+ {0x06207053,"PIC32MK1024GPE100"},
+ {0x06205053,"PIC32MK0512MCF064"},
+ {0x06202053,"PIC32MK1024MCF064"},
+ {0x06201053,"PIC32MK0512MCF100"},
+ {0x06201053,"PIC32MK1024MCF100"},
+};
+
+void PIC32_ID(int id)
+{
+ char s[64];
+ int i;
+ for(i=0;i<sizeof(PIC32LIST)/sizeof(PIC32LIST[0]);i++){
+ if((id&0x0FFFFFFF)==PIC32LIST[i].id){
+ strcpy(s,PIC32LIST[i].device);
+ strcat(s,"\r\n");
+ PrintMessage(s);
+ return;
+ }
+ }
+ PrintMessage(strings[S_nodev]); //"Unknown device\r\n");
+}
+
+/*#ifdef _MSC_VER
+void COpenProgDlg::DisplayCODE24F(int dim){
+#else
+void DisplayCODE24F(int dim){
+#endif
+// display 16 bit PIC CODE memory
+ char s[256]="",t[256]="";
+ char* aux=(char*)malloc((dim/COL+1)*2*(16+COL*9));
+ aux[0]=0;
+ int valid=0,empty=1,i,j,d,lines=0;
+ for(i=0;i<dim&&i<size;i+=COL*2){
+ valid=0;
+ for(j=i;j<i+COL*2&&j<dim;j+=4){
+ d=(memCODE[j+3]<<24)+(memCODE[j+2]<<16)+(memCODE[j+1]<<8)+memCODE[j];
+ sprintf(t,"%08X ",d);
+ strcat(s,t);
+ if(d!=0xffffffff) valid=1;
+ }
+ if(valid){
+ sprintf(t,"%06X: %s\r\n",i/2,s);
+ empty=0;
+ strcat(aux,t);
+ lines++;
+ if(lines>500){ //limit number of lines printed
+ strcat(aux,"(...)\r\n");
+ i=(dim<size?dim:size)-COL*4;
+ lines=490;
+ }
+ }
+ s[0]=0;
+ }
+ if(empty) PrintMessage(strings[S_Empty]); //empty
+ else PrintMessage(aux);
+ free(aux);
+}
+
+*/
+/*
+TDI=RB7 ->
+TCK=RB6 ->
+TDO=RB5 <-
+TMS=RB4 ->
+MCLR=RB3 ->
+*/
+//MCHP TAP INSTRUCTIONS (sent via JTAGSendCommand)
+#define MTAP_COMMAND 0x07 //TDI and TDO connected to MCHP Command Shift register
+#define MTAP_SW_MTAP 0x04 //Switch TAP controller to MCHP TAP controller
+#define MTAP_SW_ETAP 0x05 //Switch TAP controller to EJTAG TAP controller
+#define MTAP_IDCODE 0x01 //Select Chip Identification Data register
+//MTAP_COMMAND DR COMMANDS (sent via xferData)
+#define MCHP_STATUS 0x00 //NOP and return Status.
+#define MCHP_ASSERT_RST 0xD1 //Requests the reset controller to assert device Reset.
+#define MCHP_DE_ASSERT_RST 0xD0 //Removes the request for device Reset, which causes the reset controller
+ //to deassert device Reset if there is no other source requesting Reset (i.e., MCLR).
+#define MCHP_ERASE 0xFC //Cause the Flash controller to perform a Chip Erase.
+#define MCHP_FLASH_ENABLE 0xFE //Enables fetches and loads to the Flash (from the processor).
+#define MCHP_FLASH_DISABLE 0xFD //Disables fetches and loads to the Flash (from the processor).
+//EJTAG TAP INSTRUCTIONS
+#define ETAP_ADDRESS 0x08 //Select Address register.
+#define ETAP_DATA 0x09 //Select Data register.
+#define ETAP_CONTROL 0x0A //Select EJTAG Control register.
+#define ETAP_EJTAGBOOT 0x0C //Set EjtagBrk, ProbEn and ProbTrap to ‘1’ as the reset value.
+#define ETAP_FASTDATA 0x0E //Selects the Data and Fastdata registers.
+
+void XferInstruction(int* j,int instruction){
+// fill buffer with XferInstruction (14 bytes)
+// if j<0 use separate counter and perform IO directly (also wait for CPU ready)
+ int i=0,z,w0=0;
+ int IO=0;
+ if((int)j==-1){
+ j=&i;
+ IO=1;
+ }
+ if(IO){
+// bufferU[(*j)++]=JTAG_SEND_CMD;
+// bufferU[(*j)++]=MTAP_SW_ETAP;
+// bufferU[(*j)++]=JTAG_SET_MODE;
+// bufferU[(*j)++]=0x3E;//0x1F;
+ bufferU[(*j)++]=JTAG_SEND_CMD;
+ bufferU[(*j)++]=ETAP_CONTROL;
+ bufferU[(*j)++]=FLUSH;
+ for(;(*j)<DIMBUF;(*j)++) bufferU[(*j)]=0x0;
+ PacketIO(5);
+ i=0;
+ bufferU[(*j)++]=JTAG_XFER_DATA;
+ bufferU[(*j)++]=0x00;
+ bufferU[(*j)++]=0x04;
+ bufferU[(*j)++]=0xC0;
+ bufferU[(*j)++]=0x00;
+ bufferU[(*j)++]=FLUSH;
+ for(;(*j)<DIMBUF;(*j)++) bufferU[(*j)]=0x0;
+ for(i=0;i<20;i++){ //Wait for CPU ready
+ PacketIO(5);
+ for(z=0;bufferI[z]!=JTAG_XFER_DATA&&z<DIMBUF;z++);
+ if(z<DIMBUF-4) w0=(bufferI[z+1]<<24)+(bufferI[z+2]<<16)+(bufferI[z+3]<<8)+bufferI[z+4];
+ if(w0&0x40000) break;
+ }
+ if(i==20) PrintMessage1("i=20 ECR=0x%08X\r\n",w0);
+ i=0;
+ }
+ bufferU[(*j)++]=JTAG_SEND_CMD;
+ bufferU[(*j)++]=ETAP_DATA;
+ bufferU[(*j)++]=JTAG_XFER_DATA;
+ bufferU[(*j)++]=(instruction>>24)&0xFF;
+ bufferU[(*j)++]=(instruction>>16)&0xFF;
+ bufferU[(*j)++]=(instruction>>8)&0xFF;
+ bufferU[(*j)++]=instruction&0xFF;
+ bufferU[(*j)++]=JTAG_SEND_CMD;
+ bufferU[(*j)++]=ETAP_CONTROL;
+ bufferU[(*j)++]=JTAG_XFER_DATA;
+ bufferU[(*j)++]=0x00;
+ bufferU[(*j)++]=0x00;
+ bufferU[(*j)++]=0xC0;
+ bufferU[(*j)++]=0x00;
+ if(IO){
+ bufferU[(*j)++]=FLUSH;
+ for(;(*j)<DIMBUF;(*j)++) bufferU[(*j)]=0x0;
+ PacketIO(5);
+ i=0;
+ }
+}
+
+
+
+void Read32x(int dim,int options){
+// read 32 bit PIC32x
+// deviceID @ 0xFF0000
+// dim=program size (bytes)
+// options:
+// bit [3:0]
+ int k=0,k2=0,z=0,i,j;
+ if(FWVersion<0xA00){
+ PrintMessage1(strings[S_FWver2old],"0.10.0"); //"This firmware is too old. Version %s is required\r\n"
+ return;
+ }
+ if(!CheckV33Regulator()){
+ PrintMessage(strings[S_noV33reg]); //Can't find 3.3V expansion board
+ return;
+ }
+ if(saveLog){
+ OpenLogFile();
+ fprintf(logfile,"Read32x(%d,%d) (0x%X,0x%X)\n",dim,options,dim,options);
+ }
+ //dim*=2; //from words to bytes
+ if(dim>0x80000||dim<0){
+ PrintMessage(strings[S_CodeLim]); //"Code size out of limits\r\n"
+ return;
+ }
+ //unsigned char *memExec=0;
+ //executiveArea*=2;
+ //if(executiveArea) memExec=(unsigned char *)malloc(executiveArea);
+ //for(i=0;i<executiveArea;i++) memExec[i]=0xFF;
+ size=dim;
+ if(memCODE) free(memCODE);
+ memCODE=(unsigned char*)malloc(size); //CODE
+ memset(memCODE,0xFF,dim);
+ StartHVReg(-1); //disable HV
+ unsigned int start=GetTickCount();
+ int w0=0;
+ j=0;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=10000>>8;
+ bufferU[j++]=10000&0xff;
+ bufferU[j++]=EN_VPP_VCC; //enter program mode
+ bufferU[j++]=0x0;
+ bufferU[j++]=WAIT_T2;
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=SET_PORT_DIR;
+ bufferU[j++]=0x27; //RB7-6-4-3 output
+ bufferU[j++]=0xFF;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0x08; //MCLR=1
+ bufferU[j++]=0;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0; //MCLR=0
+ bufferU[j++]=0;
+ bufferU[j++]=JTAG_SET_MODE;
+ bufferU[j++]=0x3E;//0x1F;
+ bufferU[j++]=JTAG_SEND_CMD;
+ bufferU[j++]=MTAP_SW_MTAP;
+ bufferU[j++]=JTAG_SET_MODE;
+ bufferU[j++]=0x3E;//0x1F;
+ bufferU[j++]=JTAG_SEND_CMD;
+ bufferU[j++]=MTAP_COMMAND;
+ bufferU[j++]=JTAG_XFER_DATA;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=MCHP_STATUS;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(25);
+ j=0;
+ for(z=0;bufferI[z]!=JTAG_XFER_DATA&&z<DIMBUF;z++);
+ if(z<DIMBUF-4) w0=(bufferI[z+1]<<24)+(bufferI[z+2]<<16)+(bufferI[z+3]<<8)+bufferI[z+4];
+// PrintMessage1("w0: (0x%08X)\r\n",w0);
+ bufferU[j++]=JTAG_XFER_DATA;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=MCHP_STATUS;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ j=0;
+ for(i=0;(w0&0xC)!=0x8&&i<20;i++){
+ PacketIO(5);
+ for(z=0;bufferI[z]!=JTAG_XFER_DATA&&z<DIMBUF;z++);
+ if(z<DIMBUF-4) w0=(bufferI[z+1]<<24)+(bufferI[z+2]<<16)+(bufferI[z+3]<<8)+bufferI[z+4];
+// PrintMessage1("w0: (0x%08X)\r\n",w0);
+ }
+ PrintMessage3("Device status: CFGRDY=%d FCBUSY=%d (0x%02X)\r\n",w0&0x8?1:0,w0&0x4?1:0,w0&0xFF);
+ bufferU[j++]=JTAG_SEND_CMD;
+ bufferU[j++]=MTAP_IDCODE;
+ bufferU[j++]=JTAG_XFER_DATA;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=FLUSH;
+ PacketIO(5);
+ j=0;
+ for(z=0;bufferI[z]!=JTAG_XFER_DATA&&z<DIMBUF;z++);
+ if(z<DIMBUF-4) w0=(bufferI[z+1]<<24)+(bufferI[z+2]<<16)+(bufferI[z+3]<<8)+bufferI[z+4];
+ PrintMessage1("IDCODE=0x%08X\r\n",w0);
+ PIC32_ID(w0);
+ //enable serial execution mode
+ bufferU[j++]=JTAG_SEND_CMD;
+ bufferU[j++]=MTAP_SW_MTAP;
+ bufferU[j++]=JTAG_SET_MODE;
+ bufferU[j++]=0x3E;//0x1F;
+ bufferU[j++]=JTAG_SEND_CMD;
+ bufferU[j++]=MTAP_COMMAND;
+ bufferU[j++]=JTAG_XFER_DATA;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=MCHP_STATUS;
+ bufferU[j++]=JTAG_SEND_CMD;
+ bufferU[j++]=MTAP_SW_ETAP;
+ bufferU[j++]=JTAG_SET_MODE;
+ bufferU[j++]=0x3E;//0x1F;
+ bufferU[j++]=JTAG_SEND_CMD;
+ bufferU[j++]=ETAP_EJTAGBOOT;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0x8; //MCLR=1
+ bufferU[j++]=0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ j=0;
+// msDelay(5);
+ /*
+ PrintMessage2("DevID: 0x%04X\r\nDevRev: 0x%04X\r\n",w0,w1);
+ PIC24_ID(w0);
+ //Read ApplicationID @ appIDaddr
+ j=1;
+ for(z=1;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2) w0=(bufferI[z+1]<<8)+bufferI[z+2];
+ PrintMessage2("ApplicationID @ 0x80%04X: 0x%04X\r\n",appIDaddr,w0);
+//****************** read code ********************
+ PrintMessage(strings[S_CodeReading1]); //code read ...
+ PrintStatusSetup();
+//Read 6 24 bit words packed in 9 16 bit words
+//memory address advances by 24 bytes because of alignment
+ int High=0;
+ for(i=0;i<dim;i+=24){
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ writeP();
+ msDelay(3);
+ readP();
+ for(z=1;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ memCODE[k+1]=bufferI[z+1]; //M0
+ memCODE[k]=bufferI[z+2]; //L0
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ memCODE[k+2]=bufferI[z+2]; //H0
+ memCODE[k+6]=bufferI[z+1]; //H1
+ }
+ PrintStatus(strings[S_CodeReading2],i*100/dim,i/2); //"Read: %d%%, addr. %05X"
+ j=1;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k,k); //"i=%d(0x%X), k=%d(0x%X)\n"
+ WriteLogIO();
+ }
+ }
+ PrintStatusEnd();
+ if(k!=dim){
+ PrintMessage("\r\n");
+ PrintMessage2(strings[S_ReadCodeErr2],dim,k); //"Error reading code area, requested %d bytes, read %d\r\n"
+ }
+ else PrintMessage(strings[S_Compl]);*/
+//****************** read config area ********************
+//0x1FC00BF0-0BFF
+ bufferU[j++]=JTAG_SEND_CMD;
+ bufferU[j++]=MTAP_SW_ETAP;
+ bufferU[j++]=JTAG_SET_MODE;
+ bufferU[j++]=0x3E;//0x1F;
+
+ bufferU[j++]=JTAG_SEND_CMD;
+ bufferU[j++]=ETAP_CONTROL;
+ bufferU[j++]=JTAG_XFER_DATA;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ j=0;
+ for(i=0;i<20;i++){ //Wait for CPU ready
+ PacketIO(5);
+ for(z=0;bufferI[z]!=JTAG_XFER_DATA&&z<DIMBUF;z++);
+ if(z<DIMBUF-4) w0=(bufferI[z+1]<<24)+(bufferI[z+2]<<16)+(bufferI[z+3]<<8)+bufferI[z+4];
+ if(w0&0x40000) break;
+ }
+ //PrintMessage1("i=%d\r\n",i);
+ PrintMessage1("ECR=0x%08X\r\n",w0);
+ for(i=0xbFC00BF0;i<0xbFC00C10;i+=4){
+/* XferInstruction(&j,0x3C13FF20); //lui $s3, 0xFF20
+ XferInstruction(&j,0x3C080000+(i>>16)); //lui $t0,<FLASH_WORD_ADDR(31:16)>
+ XferInstruction(&j,0x35080000+(i%0xFFFF)); //ori $t0,<FLASH_WORD_ADDR(15:0)>
+ XferInstruction(&j,0x8d090000); //lw $t1, 0($t0)
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ j=0;
+ XferInstruction(&j,0xae690000); //sw $t1, 0($s3)
+ XferInstruction(&j,0); //nop
+*/
+ XferInstruction(-1,0x3C13FF20); //lui $s3, 0xFF20
+ XferInstruction(-1,0x3C080000+(i>>16)); //lui $t0,<FLASH_WORD_ADDR(31:16)>
+ XferInstruction(-1,0x35080000+(i&0xFFFF)); //ori $t0,<FLASH_WORD_ADDR(15:0)>
+ XferInstruction(-1,0x8d090000); //lw $t1, 0($t0)
+ XferInstruction(-1,0xae690000); //sw $t1, 0($s3)
+ XferInstruction(-1,0); //nop
+ j=0;
+ bufferU[j++]=JTAG_SEND_CMD;
+ bufferU[j++]=ETAP_FASTDATA;
+ bufferU[j++]=JTAG_XFER_F_DATA;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ j=0;
+ w0=-10;
+ //for(z=0;bufferI[z]!=JTAG_XFER_DATA&&z<DIMBUF;z++);
+ //for(z+=4;bufferI[z]!=JTAG_XFER_DATA&&z<DIMBUF;z++);
+ for(z=0;bufferI[z]!=JTAG_XFER_F_DATA&&z<DIMBUF;z++);
+ if(z<DIMBUF-4) w0=(bufferI[z+1]<<24)+(bufferI[z+2]<<16)+(bufferI[z+3]<<8)+bufferI[z+4];
+ PrintMessage2("[0x%08X]=0x%08X\r\n",i,w0);
+ //msDelay(5);
+ }
+ i=0xBF80F230; //DEV ID
+ XferInstruction(-1,0x3C13FF20); //lui $s3, 0xFF20
+ XferInstruction(-1,0x3C080000+(i>>16)); //lui $t0,<FLASH_WORD_ADDR(31:16)>
+ XferInstruction(-1,0x35080000+(i&0xFFFF)); //ori $t0,<FLASH_WORD_ADDR(15:0)>
+ XferInstruction(-1,0x8d090000); //lw $t1, 0($t0)
+ XferInstruction(-1,0xae690000); //sw $t1, 0($s3)
+ XferInstruction(-1,0); //nop
+ j=0;
+
+/* XferInstruction(&j,0x3C13FF20); //lui $s3, 0xFF20
+ XferInstruction(&j,0x3C080000+(i>>16)); //lui $t0,<FLASH_WORD_ADDR(31:16)>
+ XferInstruction(&j,0x35080000+(i%0xFFFF)); //ori $t0,<FLASH_WORD_ADDR(15:0)>
+ XferInstruction(&j,0x8d090000); //lw $t1, 0($t0)
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ j=0;
+ XferInstruction(&j,0xae690000); //sw $t1, 0($s3)
+ */
+ bufferU[j++]=JTAG_SEND_CMD;
+ bufferU[j++]=ETAP_FASTDATA;
+ bufferU[j++]=JTAG_XFER_F_DATA;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ j=0;
+ w0=-10;
+// for(z=0;bufferI[z]!=JTAG_XFER_DATA&&z<DIMBUF;z++);
+// for(z+=4;bufferI[z]!=JTAG_XFER_DATA&&z<DIMBUF;z++);
+ for(z=0;bufferI[z]!=JTAG_XFER_F_DATA&&z<DIMBUF;z++);
+ if(z<DIMBUF-4) w0=(bufferI[z+1]<<24)+(bufferI[z+2]<<16)+(bufferI[z+3]<<8)+bufferI[z+4];
+ PrintMessage1("DEVID=0x%08X\r\n",w0);
+ PacketIO(5);
+ for(z=0;bufferI[z]!=JTAG_XFER_F_DATA&&z<DIMBUF;z++);
+ if(z<DIMBUF-4) w0=(bufferI[z+1]<<24)+(bufferI[z+2]<<16)+(bufferI[z+3]<<8)+bufferI[z+4];
+ PrintMessage1("DEVID=0x%08X\r\n",w0);
+ PacketIO(5);
+ for(z=0;bufferI[z]!=JTAG_XFER_F_DATA&&z<DIMBUF;z++);
+ if(z<DIMBUF-4) w0=(bufferI[z+1]<<24)+(bufferI[z+2]<<16)+(bufferI[z+3]<<8)+bufferI[z+4];
+ PrintMessage1("DEVID=0x%08X\r\n",w0);
+ PacketIO(5);
+ for(z=0;bufferI[z]!=JTAG_XFER_F_DATA&&z<DIMBUF;z++);
+ if(z<DIMBUF-4) w0=(bufferI[z+1]<<24)+(bufferI[z+2]<<16)+(bufferI[z+3]<<8)+bufferI[z+4];
+ PrintMessage1("DEVID=0x%08X\r\n",w0);
+ PacketIO(5);
+ for(z=0;bufferI[z]!=JTAG_XFER_F_DATA&&z<DIMBUF;z++);
+ if(z<DIMBUF-4) w0=(bufferI[z+1]<<24)+(bufferI[z+2]<<16)+(bufferI[z+3]<<8)+bufferI[z+4];
+ PrintMessage1("DEVID=0x%08X\r\n",w0);
+ XferInstruction(-1,0x3C13FF20); //lui $s3, 0xFF20
+ XferInstruction(-1,0x3C080000+(i>>16)); //lui $t0,<FLASH_WORD_ADDR(31:16)>
+ XferInstruction(-1,0x35080000+(i&0xFFFF)); //ori $t0,<FLASH_WORD_ADDR(15:0)>
+ XferInstruction(-1,0x8d090000); //lw $t1, 0($t0)
+ XferInstruction(-1,0xae690000); //sw $t1, 0($s3)
+ XferInstruction(-1,0); //nop
+ j=0;
+ bufferU[j++]=JTAG_SEND_CMD;
+ bufferU[j++]=ETAP_FASTDATA;
+ bufferU[j++]=JTAG_XFER_F_DATA;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ j=0;
+ w0=-10;
+// for(z=0;bufferI[z]!=JTAG_XFER_DATA&&z<DIMBUF;z++);
+// for(z+=4;bufferI[z]!=JTAG_XFER_DATA&&z<DIMBUF;z++);
+ for(z=0;bufferI[z]!=JTAG_XFER_F_DATA&&z<DIMBUF;z++);
+ if(z<DIMBUF-4) w0=(bufferI[z+1]<<24)+(bufferI[z+2]<<16)+(bufferI[z+3]<<8)+bufferI[z+4];
+ PrintMessage1("DEVID=0x%08X\r\n",w0);
+// Boot block
+// PrintMessage("BOOT BLOCK @0x1FC00000\r\n");
+ for(i=0x1FC00000;i<0x1FC00BF0&&0;i+=4){
+ XferInstruction(&j,0x3C13FF20); //lui $s3, 0xFF20
+ XferInstruction(&j,0x3C080000+(i>>16)); //lui $t0,<FLASH_WORD_ADDR(31:16)>
+ XferInstruction(&j,0x35080000+(i%0xFFFF)); //ori $t0,<FLASH_WORD_ADDR(15:0)>
+ XferInstruction(&j,0x8d090000); //lw $t1, 0($t0)
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ j=0;
+ XferInstruction(&j,0xae690000); //sw $t1, 0($s3)
+ bufferU[j++]=JTAG_SEND_CMD;
+ bufferU[j++]=ETAP_FASTDATA;
+ bufferU[j++]=JTAG_XFER_F_DATA;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(5);
+ j=0;
+ for(z=0;bufferI[z]!=JTAG_XFER_DATA&&z<DIMBUF;z++);
+ for(z+=4;bufferI[z]!=JTAG_XFER_DATA&&z<DIMBUF;z++);
+ for(z+=4;bufferI[z]!=JTAG_XFER_F_DATA&&z<DIMBUF;z++);
+ if(z<DIMBUF-4) w0=(bufferI[z+1]<<24)+(bufferI[z+2]<<16)+(bufferI[z+3]<<8)+bufferI[z+4];
+ PrintMessage2("[0x%08X]=0x%08X\r\n",i,w0);
+ }
+
+/* if(config>2){ //config area @ 0xF80000
+ if(saveLog) fprintf(logfile,"\nCONFIG:\n");
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=4;
+ bufferU[j++]=0x20; //MOV XXXX,W0
+ bufferU[j++]=0x0F;
+ bufferU[j++]=0x80;
+ bufferU[j++]=0x88; //MOV W0,TABLPAG
+ if(newTABLPAG){
+ bufferU[j++]=0x02;
+ bufferU[j++]=0xA0;
+ }
+ else{
+ bufferU[j++]=0x01;
+ bufferU[j++]=0x90;
+ }
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ writeP();
+ msDelay(3);
+ readP();
+ j=1;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],0xF80000,0xF80000,0,0); //"i=%d(0x%X), k=%d(0x%X)\n"
+ WriteLogIO();
+ }
+ //save 0xF800000 to 0xF80010
+ for(i=0,z=1;i<9;i++){
+ for(;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ memCONFIG[i*4]=bufferI[z+2]; //Low byte
+ memCONFIG[i*4+1]=bufferI[z+1]; //High byte
+ z+=3;
+ }
+ writeP();
+ msDelay(3);
+ readP();
+ j=1;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],0xF80000,0xF80000,0,0); //"i=%d(0x%X), k=%d(0x%X)\n"
+ WriteLogIO();
+ }
+ //save 0xF800012 to 0xF80016
+ for(i=9,z=1;i<12;i++){
+ for(;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ memCONFIG[i*4]=bufferI[z+2]; //Low byte
+ memCONFIG[i*4+1]=bufferI[z+1]; //High byte
+ z+=3;
+ }
+ PrintStatusClear();
+ }*/
+//****************** exit ********************
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2000>>8;
+ bufferU[j++]=2000&0xff;
+ bufferU[j++]=EXT_PORT;
+ bufferU[j++]=0; //MCLR=0
+ bufferU[j++]=0;
+ bufferU[j++]=EN_VPP_VCC; //0
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ writeP();
+ msDelay(2);
+ readP();
+ if(saveLog) WriteLogIO();
+ unsigned int stop=GetTickCount();
+ PrintStatusClear();
+//****************** visualize ********************
+/* if(config>2){ //only if separate config area
+ PrintMessage(strings[S_ConfigMem]); //"\r\nConfig Memory:\r\n"
+ if(config==3||config==4||config==6){
+ PrintMessage1("0xF80000: FBS = 0x%02X\r\n",memCONFIG[0]);
+ if(config==4){ //0xF80000-16
+ PrintMessage1("0xF80002: FSS = 0x%02X\r\n",memCONFIG[4]);
+ }
+ PrintMessage1("0xF80004: FGS = 0x%02X\r\n",memCONFIG[8]);
+ PrintMessage1("0xF80006: FOSCSEL = 0x%02X\r\n",memCONFIG[12]);
+ PrintMessage1("0xF80008: FOSC = 0x%02X\r\n",memCONFIG[16]);
+ PrintMessage1("0xF8000A: FWDT = 0x%02X\r\n",memCONFIG[20]);
+ PrintMessage1("0xF8000C: FPOR = 0x%02X\r\n",memCONFIG[24]);
+ PrintMessage1("0xF8000E: FICD = 0x%02X\r\n",memCONFIG[28]);
+ if(config==3){ //0xF80000-10 except 02
+ PrintMessage1("0xF80010: FDS = 0x%02X\r\n",memCONFIG[32]);
+ }
+ else if(config==4){ //0xF80000-16
+ PrintMessage1("0xF80010: UID0 = 0x%02X\r\n",memCONFIG[32]);
+ PrintMessage1("0xF80012: UID1 = 0x%02X\r\n",memCONFIG[36]);
+ PrintMessage1("0xF80014: UID2 = 0x%02X\r\n",memCONFIG[40]);
+ PrintMessage1("0xF80016: UID3 = 0x%02X\r\n",memCONFIG[44]);
+ }
+ }
+ else if(config==5){ //0xF80000-0C (16 bit)
+ PrintMessage2("0xF80000: FOSC = 0x%02X%02X\r\n",memCONFIG[1],memCONFIG[0]);
+ PrintMessage2("0xF80002: FWDT = 0x%02X%02X\r\n",memCONFIG[5],memCONFIG[4]);
+ PrintMessage2("0xF80004: FBORPOR = 0x%02X%02X\r\n",memCONFIG[9],memCONFIG[8]);
+ PrintMessage2("0xF80006: FBS = 0x%02X%02X\r\n",memCONFIG[13],memCONFIG[12]);
+ PrintMessage2("0xF80008: FSS = 0x%02X%02X\r\n",memCONFIG[17],memCONFIG[16]);
+ PrintMessage2("0xF8000A: FGS = 0x%02X%02X\r\n",memCONFIG[21],memCONFIG[20]);
+ PrintMessage2("0xF8000C: FICD = 0x%02X%02X\r\n",memCONFIG[25],memCONFIG[24]);
+ }
+ }
+ else{
+ //last 2 program words
+ PrintMessage2("CONFIG1: 0x%04X\r\nCONFIG2: 0x%04X\r\n",(memCODE[dim-3]<<8)+memCODE[dim-4]\
+ ,(memCODE[dim-7]<<8)+memCODE[dim-8]);
+ if(config==1){ //last 3 program words
+ PrintMessage1("CONFIG3: 0x%04X\r\n",(memCODE[dim-11]<<8)+memCODE[dim-12]);
+ }
+ if(config==2){ //last 4 program words
+ PrintMessage1("CONFIG4: 0x%04X\r\n",(memCODE[dim-15]<<8)+memCODE[dim-16]);
+ }
+ }
+ PrintMessage(strings[S_CodeMem]); //"\r\nCode memory:\r\n"
+ DisplayCODE24F(dim);
+ if(dim2){
+ PrintMessage(strings[S_EEMem]); //"\r\nEEPROM memory:\r\n"
+ DisplayEE24F();
+ }
+ if(executiveArea){
+ char s[256],t[256];
+ int d,valid,empty=1;
+ char* aux=(char*)malloc((dim/COL+1)*2*(16+COL*9));
+ aux[0]=0;
+ s[0]=0;
+ empty=1;
+ PrintMessage(strings[S_ExeMem]); //"\r\nExecutive memory:\r\n"
+ for(i=0;i<executiveArea;i+=COL*2){
+ valid=0;
+ for(j=i;j<i+COL*2&&j<executiveArea;j+=4){
+ d=(memExec[j+3]<<24)+(memExec[j+2]<<16)+(memExec[j+1]<<8)+memExec[j];
+ sprintf(t,"%08X ",d);
+ strcat(s,t);
+ if(d!=0xffffffff) valid=1;
+ }
+ if(valid){
+ sprintf(t,"%06X: %s\r\n",i/2,s);
+ empty=0;
+ strcat(aux,t);
+ }
+ s[0]=0;
+ }
+ if(empty) PrintMessage(strings[S_Empty]); //empty
+ else PrintMessage(aux);
+ free(aux);
+ }*/
+ PrintMessage1(strings[S_End],(stop-start)/1000.0); //"\r\nEnd (%.2f s)\r\n"
+ if(saveLog) CloseLogFile();
+}
+
+/*
+#ifdef _MSC_VER
+void COpenProgDlg::Write24Fx(int dim,int dim2,int options,int appIDaddr,int rowSize, double wait){
+#else
+void Write24Fx(int dim,int dim2,int options,int appIDaddr,int rowSize, double wait){
+#endif
+// write 16 bit PIC 24Fxxxx
+// deviceID @ 0xFF0000
+// dim=program size (16 bit words)
+// dim2=eeprom size (in bytes, area starts at 0x800000-size)
+// options:
+// bit [3:0]
+// 0 = low voltage ICSP entry
+// 1 = High voltage ICSP entry (6V)
+// 2 = High voltage ICSP entry (12V) + PIC30F sequence (additional NOPs)
+// 3 = low voltage ICSP entry (5V power supply)
+// bit [7:4]
+// 0 = config area in the last 2 program words
+// 1 = config area in the last 3 program words
+// 2 = config area in the last 4 program words
+// 3 = 0xF80000 to 0xF80010 except 02 (24F)
+// 4 = 0xF80000 to 0xF80016 (24H-33F)
+// 5 = 0xF80000 to 0xF8000C (x16 bit, 30F)
+// 6 = 0xF80000 to 0xF8000E (30FSMPS)
+// bit [11:8]
+// 0 = code erase word is 0x4064, row write is 0x4004
+// 1 = code erase word is 0x404F, row write is 0x4001
+// 2 = code erase word is 0x407F, row write is 0x4001, 55AA unlock and external timing (2 ms)
+// 3 = code erase word is 0x407F, row write is 0x4001, 55AA unlock and external timing (200 ms)
+// bit [15:12]
+// 0 = eeprom erase word is 0x4050, write word is 0x4004
+// 1 = eeprom erased with bulk erase, write word is 0x4004
+// 2 = eeprom erased with special sequence, write word is 0x4004
+// bit [19:16]
+// 0 = config write is 0x4000
+// 1 = config write is 0x4003
+// 2 = config write is 0x4004
+// 3 = config write is 0x4008
+// bit [20]
+// 0 = standard TABLPAG address
+// 1 = new TABLPAG address
+// appIDaddr = application ID word lower address (high is 0x80)
+// rowSize = row size in instruction words (a row is written altogether)
+// wait = write delay in ms
+ int k=0,k2=0,z=0,i,j;
+ int entry=options&0xF;
+ int config=(options>>4)&0xF;
+ int EEbaseAddr=0x1000-dim2;
+ int newTABLPAG=options&0x100000?1:0;
+ int err=0;
+ if(FWVersion<0x700){
+ PrintMessage1(strings[S_FWver2old],"0.7.0"); //"This firmware is too old. Version %s is required\r\n"
+ return;
+ }
+ if(entry<2&&!CheckV33Regulator()){ //except 30Fxx which is on 5V
+ PrintMessage(strings[S_noV33reg]); //Can't find 3.3V expansion board
+ return;
+ }
+ if(saveLog){
+ OpenLogFile();
+ fprintf(logfile,"Write24Fx(%d,%d,%d,%d,%d,%.1f) (0x%X,0x%X,0x%X,0x%X,0x%X,%.3f)\n"
+ ,dim,dim2,options,appIDaddr,rowSize,wait,dim,dim2,options,appIDaddr,rowSize,wait);
+ }
+ dim*=2; //from words to bytes
+ if(dim>0x80000||dim<0){
+ PrintMessage(strings[S_CodeLim]); //"Code size out of limits\r\n"
+ return;
+ }
+ if(dim2>0x1000||dim2<0){
+ PrintMessage(strings[S_EELim]); //"EEPROM size out of limits\r\n"
+ return;
+ }
+ j=size;
+ if(j%(rowSize*4)){ //grow to an integer number of rows
+ size=(j/(rowSize*4)+1)*rowSize*4;
+ memCODE=(unsigned char*)realloc(memCODE,size);
+ for(;j<size;j++) memCODE[j]=0xFF;
+ }
+ if(dim>size) dim=size;
+ if(sizeEE<0x1000) dim2=0;
+ if(dim<1){
+ PrintMessage(strings[S_NoCode]); //"Empty code area\r\n"
+ return;
+ }
+ if((entry==1)||(entry==2)){ //High voltage programming: 3.3V + 1.5V + R drop + margin
+ if(!StartHVReg(entry==2?12:6)){ //12V only for 30Fxx !!!
+ PrintMessage(strings[S_HVregErr]); //"HV regulator error\r\n"
+ return;
+ }
+ }
+ else StartHVReg(-1); //LVP: current limited to (5-0.7-3.6)/10k = 50uA
+ if(config>2){ //only if separate config area
+ PrintMessage(strings[S_ConfigMem]); //"\r\nConfig Memory:\r\n"
+ if(config==3||config==4||config==6){
+ PrintMessage1("0xF80000: FBS = 0x%02X\r\n",memCONFIG[0]);
+ if(config==4){ //0xF80000-16
+ PrintMessage1("0xF80002: FSS = 0x%02X\r\n",memCONFIG[4]);
+ }
+ PrintMessage1("0xF80004: FGS = 0x%02X\r\n",memCONFIG[8]);
+ PrintMessage1("0xF80006: FOSCSEL = 0x%02X\r\n",memCONFIG[12]);
+ PrintMessage1("0xF80008: FOSC = 0x%02X\r\n",memCONFIG[16]);
+ PrintMessage1("0xF8000A: FWDT = 0x%02X\r\n",memCONFIG[20]);
+ PrintMessage1("0xF8000C: FPOR = 0x%02X\r\n",memCONFIG[24]);
+ PrintMessage1("0xF8000E: FICD = 0x%02X\r\n",memCONFIG[28]);
+ if(config==3){ //0xF80000-10 except 02
+ PrintMessage1("0xF80010: FDS = 0x%02X\r\n",memCONFIG[32]);
+ }
+ else if(config==4){ //0xF80000-16
+ PrintMessage1("0xF80010: UID0 = 0x%02X\r\n",memCONFIG[32]);
+ PrintMessage1("0xF80012: UID1 = 0x%02X\r\n",memCONFIG[36]);
+ PrintMessage1("0xF80014: UID2 = 0x%02X\r\n",memCONFIG[40]);
+ PrintMessage1("0xF80016: UID3 = 0x%02X\r\n",memCONFIG[44]);
+ }
+ }
+ else if(config==5){ //0xF80000-0C (16 bit)
+ PrintMessage2("0xF80000: FOSC = 0x%02X%02X\r\n",memCONFIG[1],memCONFIG[0]);
+ PrintMessage2("0xF80002: FWDT = 0x%02X%02X\r\n",memCONFIG[5],memCONFIG[4]);
+ PrintMessage2("0xF80004: FBORPOR = 0x%02X%02X\r\n",memCONFIG[9],memCONFIG[8]);
+ PrintMessage2("0xF80006: FBS = 0x%02X%02X\r\n",memCONFIG[13],memCONFIG[12]);
+ PrintMessage2("0xF80008: FSS = 0x%02X%02X\r\n",memCONFIG[17],memCONFIG[16]);
+ PrintMessage2("0xF8000A: FGS = 0x%02X%02X\r\n",memCONFIG[21],memCONFIG[20]);
+ PrintMessage2("0xF8000C: FICD = 0x%02X%02X\r\n",memCONFIG[25],memCONFIG[24]);
+ }
+ }
+ else{
+ //last 2 program words
+ PrintMessage2("CONFIG1: 0x%04X\r\nCONFIG2: 0x%04X\r\n",(memCODE[dim-3]<<8)+memCODE[dim-4]\
+ ,(memCODE[dim-7]<<8)+memCODE[dim-8]);
+ if(config==1){ //last 3 program words
+ PrintMessage1("CONFIG3: 0x%04X\r\n",(memCODE[dim-11]<<8)+memCODE[dim-12]);
+ }
+ if(config==2){ //last 4 program words
+ PrintMessage1("CONFIG4: 0x%04X\r\n",(memCODE[dim-15]<<8)+memCODE[dim-16]);
+ }
+ }
+ unsigned int start=GetTickCount();
+ bufferU[0]=0;
+ j=1;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2000>>8;
+ bufferU[j++]=2000&0xff;
+ bufferU[j++]=EN_VPP_VCC; //enter program mode
+ bufferU[j++]=0x0;
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=WAIT_T2;
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC; //VDD + VPP
+ bufferU[j++]=0x5;
+ if((entry==0)||(entry==3)){ //LVP: pulse on MCLR
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ }
+ else PrintMessage(strings[S_HVICSP]); //"High Voltage ICSP\r\n"
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=TX16;
+ bufferU[j++]=2;
+ bufferU[j++]=0x4D;
+ bufferU[j++]=0x43;
+ bufferU[j++]=0x48;
+ bufferU[j++]=0x51;
+ bufferU[j++]=WAIT_T3; //min 1ms
+ bufferU[j++]=EN_VPP_VCC; //VDD + VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=30000>>8;
+ bufferU[j++]=30000&0xff;
+ bufferU[j++]=WAIT_T3; //min 25ms
+ if(entry==2){ //30Fx entry
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ bufferU[j++]=EN_VPP_VCC; //VDD + VPP
+ bufferU[j++]=0x5;
+ bufferU[j++]=ICSP_NOP;
+ }
+ else{
+ //Additional 5 clock cycles upon entering program mode
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0; //CK=0
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x4; //CK=1
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0; //CK=0
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x4; //CK=1
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0; //CK=0
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x4; //CK=1
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0; //CK=0
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x4; //CK=1
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0; //CK=0
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x4; //CK=1
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0; //CK=0
+ }
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX; //GOTO 0x200
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ writeP();
+ msDelay(37);
+ readP();
+ if(saveLog)WriteLogIO();
+ j=1;
+ //Read DeviceID @0xFF0000, DevRev @0xFF0002
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=4;
+ bufferU[j++]=0x20; //MOV XXXX,W0
+ bufferU[j++]=0x0F;
+ bufferU[j++]=0xF0; //0xFF
+ bufferU[j++]=0x88; //MOV W0,TABLPAG
+ if(newTABLPAG){
+ bufferU[j++]=0x02;
+ bufferU[j++]=0xA0;
+ }
+ else{
+ bufferU[j++]=0x01;
+ bufferU[j++]=0x90;
+ }
+ bufferU[j++]=0x20; //MOV XXXX,W6
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x06; //0x0000
+ bufferU[j++]=0x20; //MOV #VISI,W7
+ bufferU[j++]=0x78;
+ bufferU[j++]=0x47;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX; //GOTO 0x200
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ writeP();
+ msDelay(2);
+ readP();
+ if(saveLog)WriteLogIO();
+ j=1;
+ int w0=0,w1=0;
+ for(z=1;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2) w0=(bufferI[z+1]<<8)+bufferI[z+2];
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2) w1=(bufferI[z+1]<<8)+bufferI[z+2];
+ PrintMessage2("DevID: 0x%04X\r\nDevRev: 0x%04X\r\n",w0,w1);
+ PIC24_ID(w0);
+ //Read ApplicationID @ appIDaddr
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=0x44; //append 1 NOP
+ bufferU[j++]=0x20; //MOV XXXX,W0
+ bufferU[j++]=0x08;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x88; //MOV W0,TABLPAG
+ if(newTABLPAG){
+ bufferU[j++]=0x02;
+ bufferU[j++]=0xA0;
+ }
+ else{
+ bufferU[j++]=0x01;
+ bufferU[j++]=0x90;
+ }
+ bufferU[j++]=0x20+((appIDaddr>>12)&0xF); //MOV XXXX,W6
+ bufferU[j++]=(appIDaddr>>4)&0xFF;
+ bufferU[j++]=((appIDaddr<<4)&0xF0)+6;
+ bufferU[j++]=0x20; //MOV #VISI,W7
+ bufferU[j++]=0x78;
+ bufferU[j++]=0x47;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0x96;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //GOTO 0x200
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=2000>>8;
+ bufferU[j++]=2000&0xff;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ writeP();
+ msDelay(2);
+ readP();
+ j=1;
+ if(saveLog)WriteLogIO();
+ for(z=1;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2) w0=(bufferI[z+1]<<8)+bufferI[z+2];
+ PrintMessage2("ApplicationID @ 0x80%04X: 0x%04X\r\n",appIDaddr,w0);
+//****************** erase memory ********************
+ PrintMessage(strings[S_StartErase]); //"Erase ... "
+ if(saveLog) fprintf(logfile,"\nERASE:\n");
+ int erase=(options&0xF00)>>8;
+ //bulk erase command
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=4;
+ bufferU[j++]=0x24; //MOV XXXX,W10
+ if(erase==0){ //0x4064
+ bufferU[j++]=0x06;
+ bufferU[j++]=0x4A;
+ }
+ else if(erase==1){ //0x404F
+ bufferU[j++]=0x04;
+ bufferU[j++]=0xFA;
+ }
+ else if(erase>=2){ //0x407F
+ bufferU[j++]=0x07;
+ bufferU[j++]=0xFA;
+ }
+ bufferU[j++]=0x88; //MOV W10,NVMCON
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x0A;
+ bufferU[j++]=0x20; //MOV XXXX,W0
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x88; //MOV W0,TABLPAG
+ if(newTABLPAG){
+ bufferU[j++]=0x02;
+ bufferU[j++]=0xA0;
+ }
+ else{
+ bufferU[j++]=0x01;
+ bufferU[j++]=0x90;
+ }
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX_LONG; //TBLWTL W0,[W0] (dummy write)
+ bufferU[j++]=0xBB;
+ bufferU[j++]=0x08;
+ bufferU[j++]=0x00;
+ if(erase>=2){ //30Fx, unlock and external timing
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=4;
+ bufferU[j++]=0x20; //MOV 0x55,W8
+ bufferU[j++]=0x05;
+ bufferU[j++]=0x58;
+ bufferU[j++]=0x88; //MOV W8,NVMKEY
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x38;
+ bufferU[j++]=0x20; //MOV 0xAA,W8
+ bufferU[j++]=0x0A;
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0x88; //MOV W8,NVMKEY
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x38;
+ bufferU[j++]=SIX_LONG; //BSET NVMCON,#WR
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0xE7;
+ bufferU[j++]=0x61;
+ bufferU[j++]=WAIT_T3;
+ if(erase==3){ //200 ms timing
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ writeP();
+ msDelay(200);
+ readP();
+ j=1;
+ if(saveLog)WriteLogIO();
+ }
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX_LONG; //BCLR NVMCON,#WR
+ bufferU[j++]=0xA9;
+ bufferU[j++]=0xE7;
+ bufferU[j++]=0x61;
+ }
+ else{ //internal timing
+ bufferU[j++]=SIX_LONG; //BSET NVMCON,#WR
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0xE7;
+ bufferU[j++]=0x61;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=SIX; //MOV NVMCON,W2
+ bufferU[j++]=0x80;
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x02;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX; //MOV W2,VISI
+ bufferU[j++]=0x88;
+ bufferU[j++]=0x3C;
+ bufferU[j++]=0x22;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=REGOUT;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ writeP();
+ msDelay(7);
+ readP();
+ j=1;
+ if(saveLog)WriteLogIO();
+ for(z=1;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ w0=bufferI[z+1]&0x80;
+ //Wait for erase completion (max 1s)
+ for(i=0;erase<2&&i<100&&w0;i++){
+ bufferU[j++]=SIX; //MOV NVMCON,W2
+ bufferU[j++]=0x80;
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x02;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX; //MOV W2,VISI
+ bufferU[j++]=0x88;
+ bufferU[j++]=0x3C;
+ bufferU[j++]=0x22;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ writeP();
+ msDelay(10);
+ readP();
+ j=1;
+ if(saveLog)WriteLogIO();
+ for(z=1;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ w0=bufferI[z+1]&0x80;
+ }
+//****************** prepare write ********************
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=5;
+ bufferU[j++]=0x24; //MOV XXXX,W10
+ bufferU[j++]=0x00;
+ bufferU[j++]=erase>0?0x1A:0x4A; //0x4001/0x4004
+ bufferU[j++]=0x88; //MOV W10,NVMCON
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x0A;
+ bufferU[j++]=0x20; //MOV XXXX,W0
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x88; //MOV W0,TABLPAG
+ if(newTABLPAG){
+ bufferU[j++]=0x02;
+ bufferU[j++]=0xA0;
+ }
+ else{
+ bufferU[j++]=0x01;
+ bufferU[j++]=0x90;
+ }
+ bufferU[j++]=0x04; //GOTO 0x200
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ writeP();
+ msDelay(2);
+ readP();
+ j=1;
+ if(saveLog)WriteLogIO();
+ PrintMessage(strings[S_Compl]); //"completed\r\n"
+//****************** write code ********************
+ PrintMessage(strings[S_StartCodeProg]); //"Write code ... "
+ if(saveLog) fprintf(logfile,"\nWRITE CODE:\n");
+ PrintStatusSetup();
+// instruction words are stored in code memory array as follows:
+// L0 M0 H0 FF L1 M1 H1 FF
+ int valid,High=0;
+ for(i=0,k=0;i<dim;i+=4*4){ //write 4 instruction words
+ if(k==0){ //skip row if empty
+ for(valid=0;!valid&&i<dim;i+=valid?0:rowSize*4){
+ for(k2=0;k2<rowSize*4&&!valid;k2++) if(memCODE[i+k2]<0xFF) valid=1;
+ }
+ if(i>=dim) break;
+ }
+ if((i>>17)!=High){ //advance page
+ bufferU[j++]=SIX; //MOV XXXX,W0
+ bufferU[j++]=0x20;
+ bufferU[j++]=(i>>21)&0xFF;
+ bufferU[j++]=(i>>13)&0xF0;
+ bufferU[j++]=SIX; //MOV W0,TABLPAG
+ bufferU[j++]=0x88;
+ if(newTABLPAG){
+ bufferU[j++]=0x02;
+ bufferU[j++]=0xA0;
+ }
+ else{
+ bufferU[j++]=0x01;
+ bufferU[j++]=0x90;
+ }
+ bufferU[j++]=SIX; //GOTO 0x200
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ writeP();
+ msDelay(2);
+ readP();
+ j=1;
+ if(saveLog)WriteLogIO();
+ High=i>>17;
+ }
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=8;
+ bufferU[j++]=0x20+((i>>13)&0xF); //MOV i/2,W7
+ bufferU[j++]=(i>>5)&0xFF;
+ bufferU[j++]=((i<<3)&0xF0)+7;
+ bufferU[j++]=0x20+((memCODE[i+1]>>4)&0xF); //MOV LSW0,W0
+ bufferU[j++]=((memCODE[i+1]<<4)&0xF0)+((memCODE[i]>>4)&0xF);
+ bufferU[j++]=(memCODE[i]<<4)&0xF0;
+ bufferU[j++]=0x20+((memCODE[i+6]>>4)&0xF); //MOV MSB1:MSB0,W1
+ bufferU[j++]=((memCODE[i+6]<<4)&0xF0)+((memCODE[i+2]>>4)&0xF);
+ bufferU[j++]=((memCODE[i+2]<<4)&0xF0)+1;
+ bufferU[j++]=0x20+((memCODE[i+5]>>4)&0xF); //MOV LSW1,W2
+ bufferU[j++]=((memCODE[i+5]<<4)&0xF0)+((memCODE[i+4]>>4)&0xF);
+ bufferU[j++]=((memCODE[i+4]<<4)&0xF0)+2;
+ bufferU[j++]=0x20+((memCODE[i+9]>>4)&0xF); //MOV LSW2,W3
+ bufferU[j++]=((memCODE[i+9]<<4)&0xF0)+((memCODE[i+8]>>4)&0xF);
+ bufferU[j++]=((memCODE[i+8]<<4)&0xF0)+3;
+ bufferU[j++]=0x20+((memCODE[i+14]>>4)&0xF); //MOV MSB3:MSB2,W4
+ bufferU[j++]=((memCODE[i+14]<<4)&0xF0)+((memCODE[i+10]>>4)&0xF);
+ bufferU[j++]=((memCODE[i+10]<<4)&0xF0)+4;
+ bufferU[j++]=0x20+((memCODE[i+13]>>4)&0xF); //MOV LSW3,W5
+ bufferU[j++]=((memCODE[i+13]<<4)&0xF0)+((memCODE[i+12]>>4)&0xF);
+ bufferU[j++]=((memCODE[i+12]<<4)&0xF0)+5;
+ bufferU[j++]=0xEB; //CLR W6
+ bufferU[j++]=0x03;
+ bufferU[j++]=0x00;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=0x88; //Append 2 NOP
+ bufferU[j++]=0xBB; //TBLWTL [W6++],[W7]
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=0xBB; //TBLWTH.B [W6++],[W7++]
+ bufferU[j++]=0xDB;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=0xBB; //TBLWTH.B [W6++],[++W7]
+ bufferU[j++]=0xEB;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=0xBB; //TBLWTL [W6++],[W7++]
+ bufferU[j++]=0x1B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=0xBB; //TBLWTL [W6++],[W7]
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=0xBB; //TBLWTH.B [W6++],[W7++]
+ bufferU[j++]=0xDB;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=0xBB; //TBLWTH.B [W6++],[++W7]
+ bufferU[j++]=0xEB;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=0xBB; //TBLWTL [W6++],[W7++]
+ bufferU[j++]=0x1B;
+ bufferU[j++]=0xB6;
+ k++;
+ if(k==rowSize/4){ //Write row
+ if(erase>1){ //30Fx, unlock and external timing
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ writeP();
+ msDelay(3);
+ readP();
+ j=1;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k,k); //"i=%d, k=%d 0=%d\n"
+ WriteLogIO();
+ }
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=6;
+ bufferU[j++]=0x24; //MOV XXXX,W10
+ bufferU[j++]=0x00;
+ bufferU[j++]=erase>0?0x1A:0x4A; //0x4001/0x4004
+ bufferU[j++]=0x88; //MOV W10,NVMCON
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x0A;
+ bufferU[j++]=0x20; //MOV 0x55,W8
+ bufferU[j++]=0x05;
+ bufferU[j++]=0x58;
+ bufferU[j++]=0x88; //MOV W8,NVMKEY
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x38;
+ bufferU[j++]=0x20; //MOV 0xAA,W8
+ bufferU[j++]=0x0A;
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0x88; //MOV W8,NVMKEY
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x38;
+ bufferU[j++]=SIX_LONG; //BSET NVMCON,#WR
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0xE7;
+ bufferU[j++]=0x61;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX_LONG; //BCLR NVMCON,#WR
+ bufferU[j++]=0xA9;
+ bufferU[j++]=0xE7;
+ bufferU[j++]=0x61;
+ bufferU[j++]=SIX_LONG; //GOTO 0x200
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ }
+ else{ //internal timing
+ bufferU[j++]=SIX_LONG; //GOTO 0x200
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=SIX_LONG; //BSET NVMCON,#WR
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0xE7;
+ bufferU[j++]=0x61;
+ }
+ k=0;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ writeP();
+ msDelay(3);
+ readP();
+ j=1;
+ PrintStatus(strings[S_CodeWriting2],i*100/(dim+dim2),i/2); //"Write: %d%%,addr. %04X"
+ if(RWstop) i=dim;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i/2,i/2,k,k); //"i=%d, k=%d 0=%d\n"
+ WriteLogIO();
+ }
+ }
+ PrintStatusEnd();
+ PrintMessage(strings[S_Compl]); //"completed\r\n"
+//****************** verify code ********************
+ PrintMessage(strings[S_CodeV]); //"Verify code ... "
+ if(saveLog) fprintf(logfile,"\nVERIFY CODE:\n");
+ PrintStatusSetup();
+//Read 4 24 bit words packed in 6 16 bit words
+//memory address advances by 16 bytes because of alignment
+ High=0xE0000000;
+ int r0=0,r1=0,r2=0,r3=0,w3,w2;
+ for(i=0;i<dim;i+=16){
+ //skip row if empty
+ for(valid=0;!valid&&i<dim;i+=valid?0:16){
+ for(k2=0;k2<16&&!valid;k2++) if(memCODE[i+k2]<0xFF) valid=1;
+ }
+ if(i>=dim) break;
+ if((i>>17)!=High){ //advance page
+ bufferU[j++]=SIX; //MOV XXXX,W0
+ bufferU[j++]=0x20;
+ bufferU[j++]=(i>>21)&0xFF;
+ bufferU[j++]=(i>>13)&0xF0;
+ bufferU[j++]=SIX; //MOV W0,TABLPAG
+ bufferU[j++]=0x88;
+ if(newTABLPAG){
+ bufferU[j++]=0x02;
+ bufferU[j++]=0xA0;
+ }
+ else{
+ bufferU[j++]=0x01;
+ bufferU[j++]=0x90;
+ }
+ bufferU[j++]=SIX; //GOTO 0x200
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ writeP();
+ msDelay(2);
+ readP();
+ j=1;
+ if(saveLog)WriteLogIO();
+ High=i>>17;
+ }
+ bufferU[j++]=SIX; //MOV i/2,W6
+ bufferU[j++]=0x20+((i>>13)&0xF);
+ bufferU[j++]=(i>>5)&0xFF;
+ bufferU[j++]=((i<<3)&0xF0)+6;
+ bufferU[j++]=SIX; //MOV #VISI,W7
+ bufferU[j++]=0x20;
+ bufferU[j++]=0x78;
+ bufferU[j++]=0x47;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0x96;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDH.B [W6++],[W7++]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0xDB;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=SIX_LONG; //TBLRDH.B [++W6],[W7--]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0xD3;
+ bufferU[j++]=0xD6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0x96;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDH.B [W6++],[W7++]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0xDB;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=SIX_LONG; //TBLRDH.B [++W6],[W7--]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0xD3;
+ bufferU[j++]=0xD6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //GOTO 0x200
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ writeP();
+ msDelay(3);
+ readP();
+ PrintStatus(strings[S_CodeV2],i*100/(dim+dim2),i/2); //"Verify: %d%%, addr. %04X"
+ if(RWstop) i=dim;
+ for(z=1;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ r0=(bufferI[z+1]<<8)+bufferI[z+2];
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ r0+=bufferI[z+2]<<16;
+ r1=bufferI[z+1]<<16;
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ r1+=(bufferI[z+1]<<8)+bufferI[z+2];
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ r2=(bufferI[z+1]<<8)+bufferI[z+2];
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ r2+=bufferI[z+2]<<16;
+ r3=bufferI[z+1]<<16;
+ }
+ for(z+=3;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ if(z<DIMBUF-2){
+ r3+=(bufferI[z+1]<<8)+bufferI[z+2];
+ }
+ w0=(memCODE[i+2]<<16)+(memCODE[i+1]<<8)+memCODE[i];
+ w1=(memCODE[i+6]<<16)+(memCODE[i+5]<<8)+memCODE[i+4];
+ w2=(memCODE[i+10]<<16)+(memCODE[i+9]<<8)+memCODE[i+8];
+ w3=(memCODE[i+14]<<16)+(memCODE[i+13]<<8)+memCODE[i+12];
+ CheckData(w0,r0,i/2,&err);
+ CheckData(w1,r1,i/2+2,&err);
+ CheckData(w2,r2,i/2+4,&err);
+ CheckData(w3,r3,i/2+6,&err);
+ PrintStatus(strings[S_CodeV2],i*100/dim,i/2); //"Verify: %d%%, addr. %05X"
+ j=1;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log8],i/2,i/2,k,k,err); //"i=%d, k=%d, errori=%d\n"
+ WriteLogIO();
+ }
+ if(err>=max_err) break;
+ }
+ PrintStatusEnd();
+ PrintMessage1(strings[S_ComplErr],err); //"completed: %d errors\r\n"
+ if(err>=max_err){
+ PrintMessage1(strings[S_MaxErr],err); //"Exceeded maximum number of errors (%d), write interrupted\r\n"
+ }
+//****************** erase, write and verify EEPROM ********************
+ if(dim2&&err<max_err){
+ //EEPROM @ 0x7F(EEbaseAddr)
+ PrintMessage(strings[S_EEAreaW]); //"Write EEPROM ... "
+ PrintStatusSetup();
+ if(saveLog) fprintf(logfile,"\nWRITE EEPROM:\n");
+ int eewrite=(options&0xf000)>>12;
+ if(eewrite==0){ //24FxxKAxx
+ bufferU[j++]=SIX; //MOV 0x4050,W10
+ bufferU[j++]=0x24;
+ bufferU[j++]=0x05;
+ bufferU[j++]=0x0A;
+ bufferU[j++]=SIX; //MOV W10,NVMCON
+ bufferU[j++]=0x88;
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x0A;
+ bufferU[j++]=SIX; //MOV 0x7F,W0
+ bufferU[j++]=0x20;
+ bufferU[j++]=0x07;
+ bufferU[j++]=0xF0;
+ bufferU[j++]=SIX; //MOV W0,TABLPAG
+ bufferU[j++]=0x88;
+ if(newTABLPAG){
+ bufferU[j++]=0x02;
+ bufferU[j++]=0xA0;
+ }
+ else{
+ bufferU[j++]=0x01;
+ bufferU[j++]=0x90;
+ }
+ bufferU[j++]=SIX; //MOV EEbaseAddr,W0
+ bufferU[j++]=0x2F;
+ bufferU[j++]=EEbaseAddr>>4;
+ bufferU[j++]=0x00;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX; //TBLWTL W0,[W0]
+ bufferU[j++]=0xBB;
+ bufferU[j++]=0x08;
+ bufferU[j++]=0x00;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;/**/
+ /* //Erase EEPROM
+ bufferU[j++]=SIX; //BSET NVMCON,#WR
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0xE7;
+ bufferU[j++]=0x61;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=SIX; //MOV 0x4004,W10
+ bufferU[j++]=0x24;
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x4A;
+ bufferU[j++]=SIX; //MOV W10,NVMCON
+ bufferU[j++]=0x88;
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x0A;
+ bufferU[j++]=SIX; //GOTO 0x200
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ writeP();
+ msDelay(9);
+ readP();
+ j=1;
+ if(saveLog)WriteLogIO();
+ }
+ else if(eewrite==2){ //separate erase
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=6;
+ bufferU[j++]=0x24; //MOV 4046,W10
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x6A;
+ bufferU[j++]=0x88; //MOV W10,NVMCON
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x0A;
+ bufferU[j++]=0x20; //MOV 0x55,W8
+ bufferU[j++]=0x05;
+ bufferU[j++]=0x58;
+ bufferU[j++]=0x88; //MOV W8,NVMKEY
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x38;
+ bufferU[j++]=0x20; //MOV 0xAA,W8
+ bufferU[j++]=0x0A;
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0x88; //MOV W8,NVMKEY
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x38;
+ bufferU[j++]=SIX_LONG; //BSET NVMCON,#WR
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0xE7;
+ bufferU[j++]=0x61;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX_LONG; //BCLR NVMCON,#WR
+ bufferU[j++]=0xA9;
+ bufferU[j++]=0xE7;
+ bufferU[j++]=0x61;
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=6;
+ bufferU[j++]=0x24; //MOV 4056,W10
+ bufferU[j++]=0x05;
+ bufferU[j++]=0x6A;
+ bufferU[j++]=0x88; //MOV W10,NVMCON
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x0A;
+ bufferU[j++]=0x20; //MOV 0x55,W8
+ bufferU[j++]=0x05;
+ bufferU[j++]=0x58;
+ bufferU[j++]=0x88; //MOV W8,NVMKEY
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x38;
+ bufferU[j++]=0x20; //MOV 0xAA,W8
+ bufferU[j++]=0x0A;
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0x88; //MOV W8,NVMKEY
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x38;
+ bufferU[j++]=SIX_LONG; //BSET NVMCON,#WR
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0xE7;
+ bufferU[j++]=0x61;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX_LONG; //BCLR NVMCON,#WR
+ bufferU[j++]=0xA9;
+ bufferU[j++]=0xE7;
+ bufferU[j++]=0x61;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ writeP();
+ msDelay(6);
+ readP();
+ j=1;
+ if(saveLog)WriteLogIO();
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=6;
+ bufferU[j++]=0x24; //MOV 4066,W10
+ bufferU[j++]=0x06;
+ bufferU[j++]=0x6A;
+ bufferU[j++]=0x88; //MOV W10,NVMCON
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x0A;
+ bufferU[j++]=0x20; //MOV 0x55,W8
+ bufferU[j++]=0x05;
+ bufferU[j++]=0x58;
+ bufferU[j++]=0x88; //MOV W8,NVMKEY
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x38;
+ bufferU[j++]=0x20; //MOV 0xAA,W8
+ bufferU[j++]=0x0A;
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0x88; //MOV W8,NVMKEY
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x38;
+ bufferU[j++]=SIX_LONG; //BSET NVMCON,#WR
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0xE7;
+ bufferU[j++]=0x61;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX_LONG; //BCLR NVMCON,#WR
+ bufferU[j++]=0xA9;
+ bufferU[j++]=0xE7;
+ bufferU[j++]=0x61;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ writeP();
+ msDelay(4);
+ readP();
+ j=1;
+ if(saveLog)WriteLogIO();
+ }
+ else if(eewrite==1){ //30Fxx
+ bufferU[j++]=SIX; //MOV 0x7F,W0
+ bufferU[j++]=0x20;
+ bufferU[j++]=0x07;
+ bufferU[j++]=0xF0;
+ bufferU[j++]=SIX; //MOV W0,TABLPAG
+ bufferU[j++]=0x88;
+ if(newTABLPAG){
+ bufferU[j++]=0x02;
+ bufferU[j++]=0xA0;
+ }
+ else{
+ bufferU[j++]=0x01;
+ bufferU[j++]=0x90;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ writeP();
+ msDelay(1);
+ readP();
+ j=1;
+ if(saveLog)WriteLogIO();
+ }
+ //Write EEPROM
+ for(k2=0,i=0x1000-dim2;i<0x1000;i+=2){ //write 1 word (2 bytes)
+ if(memEE[i]<0xFF||memEE[i+1]<0xFF){
+ bufferU[j++]=SIX; //MOV i,W7
+ bufferU[j++]=0x2F;
+ bufferU[j++]=i>>4;
+ bufferU[j++]=((i<<4)&0xF0)+7;
+ bufferU[j++]=SIX; //MOV XXXX,W0
+ bufferU[j++]=0x20+((memEE[i+1]>>4)&0xF);
+ bufferU[j++]=((memEE[i+1]<<4)&0xF0)+((memEE[i]>>4)&0xF);
+ bufferU[j++]=(memEE[i]<<4)&0xF0;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX_LONG; //TBLWTL W0,[W7++]
+ bufferU[j++]=0xBB;
+ bufferU[j++]=0x1B;
+ bufferU[j++]=0x80;
+ if(eewrite==0){ //24FxxKAxx
+ bufferU[j++]=SIX_LONG; //BSET NVMCON,#WR
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0xE7;
+ bufferU[j++]=0x61;
+ }
+ else if(eewrite==1){ //30Fxxxx
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=6;
+ bufferU[j++]=0x24; //MOV 0x4004,W10
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x4A;
+ bufferU[j++]=0x88; //MOV W10,NVMCON
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x0A;
+ bufferU[j++]=0x20; //MOV 0x55,W8
+ bufferU[j++]=0x05;
+ bufferU[j++]=0x58;
+ bufferU[j++]=0x88; //MOV W8,NVMKEY
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x38;
+ bufferU[j++]=0x20; //MOV 0xAA,W8
+ bufferU[j++]=0x0A;
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0x88; //MOV W8,NVMKEY
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x38;
+ bufferU[j++]=SIX_LONG; //BSET NVMCON,#WR
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0xE7;
+ bufferU[j++]=0x61;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX_LONG; //BCLR NVMCON,#WR
+ bufferU[j++]=0xA9;
+ bufferU[j++]=0xE7;
+ bufferU[j++]=0x61;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ writeP();
+ msDelay(wait+2); //write delay
+ readP();
+ j=1;
+ PrintStatus(strings[S_CodeWriting],(i-0x1000+dim2)*100/(dim2),i); //"Scrittura: %d%%, ind. %03X"
+ if(RWstop) i=dim;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k,k); //"i=%d, k=%d 0=%d\n"
+ WriteLogIO();
+ }
+ }
+ }
+ //Verify EEPROM
+ if(saveLog) fprintf(logfile,"\nVERIFY EEPROM:\n");
+ bufferU[j++]=SIX; //MOV 0xFE00,W6
+ bufferU[j++]=0x2F;
+ bufferU[j++]=EEbaseAddr>>4;
+ bufferU[j++]=0x06;
+ bufferU[j++]=SIX; //MOV #VISI,W7
+ bufferU[j++]=0x20;
+ bufferU[j++]=0x78;
+ bufferU[j++]=0x47;
+ bufferU[j++]=SIX; //GOTO 0x200
+ bufferU[j++]=0x04;
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=ICSP_NOP;
+ int errE=0;
+ for(i=k2=EEbaseAddr;i<EEbaseAddr+dim2;i+=2){
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ if(j>DIMBUF-7||i==dim2-4){
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ writeP();
+ msDelay(3);
+ readP();
+ for(z=1;z<DIMBUF-2;z++){
+ if(bufferI[z]==REGOUT){
+ CheckData(memEE[k2],bufferI[z+2],i,&errE);
+ CheckData(memEE[k2+1],bufferI[z+1],i+1,&errE);
+ z+=3;
+ k2+=2;
+ }
+ }
+ PrintStatus(strings[S_CodeReading],(i-EEbaseAddr)*100/(dim2),i); //"Read: %d%%, addr. %03X"
+ if(RWstop) i=EEbaseAddr+dim2;
+ j=1;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,k2,k2); //"i=%d(0x%X), k=%d(0x%X)\n"
+ WriteLogIO();
+ }
+ }
+ }
+ PrintStatusEnd();
+ PrintMessage1(strings[S_ComplErr],errE); //"completed: %d errors \r\n"
+ err+=errE;
+ PrintStatusClear();
+ }
+//****************** write CONFIG ********************
+ int written, read;
+ j=1;
+ if(config>2&&config<5&&err<max_err){ //config area @ 0xF80000
+ PrintMessage(strings[S_ConfigW]); //"Write CONFIG ..."
+ if(saveLog) fprintf(logfile,"\nWRITE CONFIG:\n");
+ int confword=(options&0xF0000)>>16;
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=6;
+ bufferU[j++]=0x20; //MOV 0xF8,W0
+ bufferU[j++]=0x0F;
+ bufferU[j++]=0x80;
+ bufferU[j++]=0x88; //MOV W0,TABLPAG
+ if(newTABLPAG){
+ bufferU[j++]=0x02;
+ bufferU[j++]=0xA0;
+ }
+ else{
+ bufferU[j++]=0x01;
+ bufferU[j++]=0x90;
+ }
+ bufferU[j++]=0x24; //MOV 0x400x,W10
+ bufferU[j++]=0x00;
+ if(confword==0)bufferU[j++]=0x0A; //0x4000
+ else if(confword==1)bufferU[j++]=0x3A; //0x4003
+ else if(confword==2)bufferU[j++]=0x4A; //0x4004
+ else if(confword==3)bufferU[j++]=0x8A; //0x4008
+ bufferU[j++]=0x88; //MOV W10,NVMCON
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x0A;
+ bufferU[j++]=0x20; //MOV 0,W7
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x07;
+ bufferU[j++]=0x04; //GOTO 0x200
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=ICSP_NOP;
+ for(i=0;i<12;i++){
+ //Write CONFIG
+ bufferU[j++]=SIX; //MOV XXXX,W0
+ bufferU[j++]=0x20;
+ bufferU[j++]=(memCONFIG[i*4]>>4)&0xF;
+ bufferU[j++]=(memCONFIG[i*4]<<4)&0xF0;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX_LONG; //TBLWTL W0,[W7++]
+ bufferU[j++]=0xBB;
+ bufferU[j++]=0x1B;
+ bufferU[j++]=0x80;
+ //if(memCONFIG[i*4]<0xFF){ //write if not empty
+ bufferU[j++]=SIX_LONG; //BSET NVMCON,#WR
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0xE7;
+ bufferU[j++]=0x61;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ //}
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ writeP();
+ msDelay(27);
+ readP();
+ j=1;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,0,0); //"i=%d(0x%X), k=%d(0x%X)\n"
+ WriteLogIO();
+ }
+ }
+ //Verify write
+ int errC=0;
+ bufferU[j++]=SIX;
+ bufferU[j++]=0x20; //MOV XXXX,W6
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x06;
+ bufferU[j++]=SIX;
+ bufferU[j++]=0x20; //MOV #VISI,W7
+ bufferU[j++]=0x78;
+ bufferU[j++]=0x47;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ writeP();
+ msDelay(3);
+ readP();
+ j=1;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],0xF80000,0xF80000,0,0); //"i=%d(0x%X), k=%d(0x%X)\n"
+ WriteLogIO();
+ }
+ for(i=0,z=1;i<9;i++){
+ for(;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ written=memCONFIG[i*4];
+ read=bufferI[z+2]; //Low byte
+ if(~written&read)CheckData(written,read,0xF80000+i*2,&errC);
+ z+=3;
+ }
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ writeP();
+ msDelay(3);
+ readP();
+ j=1;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],0xF80000,0xF80000,0,0); //"i=%d(0x%X), k=%d(0x%X)\n"
+ WriteLogIO();
+ }
+ for(z=1;i<12;i++){
+ for(;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ written=memCONFIG[i*4];
+ read=bufferI[z+2]; //Low byte
+ if(~written&read)CheckData(written,read,0xF80000+i*2,&errC);
+ z+=3;
+ }
+ PrintMessage1(strings[S_ComplErr],errC); //"completed: %d errors \r\n"
+ PrintStatusClear();
+ err+=errC;
+ }
+ else if(config>=5&&err<max_err){ //16 bit config area (30Fxxxx)
+ PrintMessage(strings[S_ConfigW]); //"Write CONFIG ..."
+ if(saveLog) fprintf(logfile,"\nWRITE CONFIG:\n");
+ int Nconf=config==5?7:8;
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=4;
+ bufferU[j++]=0x20; //MOV 0xF8,W0
+ bufferU[j++]=0x0F;
+ bufferU[j++]=0x80;
+ bufferU[j++]=0x88; //MOV W0,TABLPAG
+ if(newTABLPAG){
+ bufferU[j++]=0x02;
+ bufferU[j++]=0xA0;
+ }
+ else{
+ bufferU[j++]=0x01;
+ bufferU[j++]=0x90;
+ }
+ bufferU[j++]=0x20; //MOV 0,W7
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x07;
+ bufferU[j++]=0x04; //GOTO 0x200
+ bufferU[j++]=0x02;
+ bufferU[j++]=0x00;
+ bufferU[j++]=ICSP_NOP;
+ for(i=0;i<Nconf;i++){
+ //Erase CONFIG
+ bufferU[j++]=SIX; //MOV 0xFFFF,W0
+ bufferU[j++]=0x2F;
+ bufferU[j++]=0xFF;
+ bufferU[j++]=0xF0;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX_LONG; //TBLWTL W0,[W7++]
+ bufferU[j++]=0xBB;
+ bufferU[j++]=0x1B;
+ bufferU[j++]=0x80;
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=6;
+ bufferU[j++]=0x24; //MOV 0x400x,W10
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x8A; //0x4008
+ bufferU[j++]=0x88; //MOV W10,NVMCON
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x0A;
+ bufferU[j++]=0x20; //MOV 0x55,W8
+ bufferU[j++]=0x05;
+ bufferU[j++]=0x58;
+ bufferU[j++]=0x88; //MOV W8,NVMKEY
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x38;
+ bufferU[j++]=0x20; //MOV 0xAA,W8
+ bufferU[j++]=0x0A;
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0x88; //MOV W8,NVMKEY
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x38;
+ bufferU[j++]=SIX_LONG; //BSET NVMCON,#WR
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0xE7;
+ bufferU[j++]=0x61;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX_LONG; //BCLR NVMCON,#WR
+ bufferU[j++]=0xA9;
+ bufferU[j++]=0xE7;
+ bufferU[j++]=0x61;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ writeP();
+ msDelay(3);
+ readP();
+ j=1;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,0,0); //"i=%d(0x%X), k=%d(0x%X)\n"
+ WriteLogIO();
+ }
+ }
+ bufferU[j++]=SIX;
+ bufferU[j++]=0x20; //MOV 0,W7
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x07;
+ for(i=0;i<Nconf;i++){
+ int value=memCONFIG[i*4]+(memCONFIG[i*4+1]<<8);
+ //Write CONFIG
+ bufferU[j++]=SIX; //MOV XXXX,W0
+ bufferU[j++]=0x20+(value>>12);
+ bufferU[j++]=(value>>4);
+ bufferU[j++]=(value<<4);
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX_LONG; //TBLWTL W0,[W7++]
+ bufferU[j++]=0xBB;
+ bufferU[j++]=0x1B;
+ bufferU[j++]=0x80;
+ if(value<0xFFFF){ //write if not empty
+ bufferU[j++]=SIX_N;
+ bufferU[j++]=6;
+ bufferU[j++]=0x24; //MOV 0x400x,W10
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x8A; //0x4008
+ bufferU[j++]=0x88; //MOV W10,NVMCON
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x0A;
+ bufferU[j++]=0x20; //MOV 0x55,W8
+ bufferU[j++]=0x05;
+ bufferU[j++]=0x58;
+ bufferU[j++]=0x88; //MOV W8,NVMKEY
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x38;
+ bufferU[j++]=0x20; //MOV 0xAA,W8
+ bufferU[j++]=0x0A;
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0x88; //MOV W8,NVMKEY
+ bufferU[j++]=0x3B;
+ bufferU[j++]=0x38;
+ bufferU[j++]=SIX_LONG; //BSET NVMCON,#WR
+ bufferU[j++]=0xA8;
+ bufferU[j++]=0xE7;
+ bufferU[j++]=0x61;
+ bufferU[j++]=WAIT_T3;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX_LONG; //BCLR NVMCON,#WR
+ bufferU[j++]=0xA9;
+ bufferU[j++]=0xE7;
+ bufferU[j++]=0x61;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ writeP();
+ msDelay(3);
+ readP();
+ j=1;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],i,i,0,0); //"i=%d(0x%X), k=%d(0x%X)\n"
+ WriteLogIO();
+ }
+ }
+ //Verify write
+ int errC=0;
+ bufferU[j++]=SIX;
+ bufferU[j++]=0x20; //MOV XXXX,W6
+ bufferU[j++]=0x00;
+ bufferU[j++]=0x06;
+ bufferU[j++]=SIX;
+ bufferU[j++]=0x20; //MOV #VISI,W7
+ bufferU[j++]=0x78;
+ bufferU[j++]=0x47;
+ bufferU[j++]=ICSP_NOP;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=SIX_LONG; //TBLRDL [W6++],[W7]
+ bufferU[j++]=0xBA;
+ bufferU[j++]=0x0B;
+ bufferU[j++]=0xB6;
+ bufferU[j++]=REGOUT;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ writeP();
+ msDelay(3);
+ readP();
+ j=1;
+ if(saveLog){
+ fprintf(logfile,strings[S_Log7],0xF80000,0xF80000,0,0); //"i=%d(0x%X), k=%d(0x%X)\n"
+ WriteLogIO();
+ }
+ for(i=0,z=1;i<7;i++){
+ for(;bufferI[z]!=REGOUT&&z<DIMBUF;z++);
+ written=memCONFIG[i*4+1]+(memCONFIG[i*4]<<8);
+ read=bufferI[z+1]+(bufferI[z+2]<<8);
+ if(~written&read)CheckData(written,read,0xF80000+i*2,&errC); //16 bit
+ z+=3;
+ }
+ PrintMessage1(strings[S_ComplErr],errC); //"completed: %d errors \r\n"
+ PrintStatusClear();
+ err+=errC;
+ }
+//****************** exit ********************
+ bufferU[j++]=SET_CK_D;
+ bufferU[j++]=0x0;
+ bufferU[j++]=EN_VPP_VCC; //0
+ bufferU[j++]=0x0;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ writeP();
+ msDelay(2);
+ readP();
+ if(saveLog)WriteLogIO();
+ j=1;
+ unsigned int stop=GetTickCount();
+ PrintStatusClear();
+ PrintMessage3(strings[S_EndErr],(stop-start)/1000.0,err,err!=1?strings[S_ErrPlur]:strings[S_ErrSing]); //"\r\nEnd (%.2f s) %d %s\r\n\r\n"
+ if(saveLog) CloseLogFile();
+}
+*/
diff --git a/progP32.h b/progP32.h
new file mode 100644
index 0000000..4f8f327
--- /dev/null
+++ b/progP32.h
@@ -0,0 +1,4 @@
+void Read32x(int dim,int options);
+//void Write24Fx(int dim,int dim2,int options,int appIDaddr,int rowSize, double wait);
+//void DisplayCODE24F(int dim);
+
diff --git a/read.png b/read.png
new file mode 100644
index 0000000..c00de0e
--- /dev/null
+++ b/read.png
Binary files differ
diff --git a/read_eeprom.sh b/read_eeprom.sh
new file mode 100644
index 0000000..3814155
--- /dev/null
+++ b/read_eeprom.sh
@@ -0,0 +1 @@
+./op -ee -d 2402 -s 24c02.hex
diff --git a/readme b/readme
new file mode 100644
index 0000000..9bc8887
--- /dev/null
+++ b/readme
@@ -0,0 +1,98 @@
+opgui: control program for open programmer,
+an USB programmer for PIC and ATMEL micros, I2C/SPI/MicroWire memories,
+and other I2C/SPI devices.
+Website: http://openprog.altervista.org
+These sources are given free of charge under the GNU General Public License version 2
+
+Changelog (to use new features the corresponding firmware is required):
+V 0.12.1 february 2023: fixed crash when filtering with "*" while some devices were selected
+
+V 0.12.0 october 2022: port to GTK3; device selected via tree; added possibility to send manual commands;
+ added 16F15213-14-23-24-25-43-44-45-54-55-56-74-75-76,
+ 16F18013-14-15-23-24-25-26-44-45-46-54-55-56-74-75-76,
+ 16F18114-15-24-25-26-44-45-46-54-55-56-74-75-76,
+ 16F17114-15-24-25-26-44-45-46-54-55-56-74-75-76,
+ 18F04-05-06-14-15-16Q40-41,
+ 18F24-25-26-44-45-46-54-55-56Q71,
+ 18F26-27-46-47-56-57Q83-84;
+ fixed write on 254005
+
+V 0.11.5 december 2021: fixed config word write on some 33FJXX devices
+
+V 0.11.4 july 2021: fixed missing parentheses in progP18.c and progP16.c
+
+V 0.11.3 april 2021: fixed EEPROM write on 16F184xx/188xx/191xx
+
+V 0.11.2 october 2020: fixed 16F18xxx write with empty space at address 0;
+ added 18F25-26-27-45-46-47-55-56-57Q43,
+ 18F25-26-27-45-46-47-55-56-57K42, 18F25-26K83;
+ [linux] changed HW access path to /dev/hidraw
+
+V 0.11.1 february 2020: fixes: save file for 12F1XXX;
+ timeout writing config for 16F18XXX;
+ avoid reading DIA-DCI on 16F188XX;
+ EE verification of 0x22 on 18FXXX
+
+V 0.11.0 january 2019: added 16F15313-23-24-25-44-45-54-55-56-75-76-85-86,
+ 16F18424-25-26-44-45-46-54-55-56,
+ 16F18854-55-56-57-75-76-77,
+ 16F19155-56-75-76-85-86-95-96-97
+
+V 0.10.1 december 2018: added 16F1764-65-68-69-73-76-77-78-79;
+ removed MSVC6 function definitions
+
+V 0.10.0 june 2016: added 16F18313-23-24-25-26-44-45-46;
+ improved USB communication
+
+V 0.9.1 november 2014: Fixed verification of ATTiny11-12;
+ fixed 24FJ128GA3xx-GB2xx-GCxx-DAxx;
+ added config force for PIC18, IO lines hardware test,
+ AVR auto speed communication, AVR write fuse at low frequency;
+ faster write verification for SPI FLASH memories;
+ added 10F320-22,12F529T39A,12F752,12F1612-13-14-15-18-19,
+ 16F1512-13,16F1574-75-78-79,16F1703-04-05-07-08-09-13-16-17-18-19,
+ 16F1788-89,16F570,16LF1554-59,
+ 18F24K50-25K50-26K50-45K50-46K50,
+ 18F25K80-26K80-45K80-46K80-65K80-66K80,
+ 18F63J11-90,18F64J11-90,18F65J10-11-15-50-90,
+ 18F66J10-11-15-16-50-55-90-93,18F67J10-11-50-90-93,
+ 18F83J11-90,18F84J11-90,18F85J10-11-15-50-90,
+ 18F86J10-11-15-16-50-55-90-93,18F87J10-11-50-72-90-93,
+ 25X128,25Q40
+
+V 0.9.0 march 2014: Write16F72x requires only config-word 1;
+ added HV serial programming for ATtiny11-12-13-24-25-44-45-84-85;
+ added 24FJ64GA3xx-GCxx,24FJ128GA3xx-GB2xx-GCxx-DAxx,24FJ256DAxx,24EPx,33EPx;
+ added 95xx SPI EEPROM,25X05 FLASH;
+ added 12F1571-72,16F527,16F753,16F1454-55-59;
+ some code rework & minor improvements
+
+V 0.8.1 june 2013: added IO and Utility tabs;
+ start programming with S1; SPI/I2C speed selection; -command option;
+ multiple language support; force config word; skip LV check;
+ fixed EEPROM write when code protection is active (16F83-84,12F629,
+ 12F675,16F627-28,16F630,16F676,16F870-1-2,16F873-74,16F876-77);
+ fixed read of files > 1MB;
+ modified prog mode entry for AVR;
+ fixed write of 93Sx6 with protection
+
+V 0.8.0 june 2012: added one-wire memories DS2430,DS2431,DS2433,DS28EC20, thermometer DS1820;
+ added UNIO memories 11010-20-40-80-160;
+ fixed algorithms for 24x1024/5 and 251024,
+ added SPI FLASH 251005,252005,254005,258005,251605,25X10,25X20,25X40,25X80,
+ 25X16,25X32,25X64;
+ added 16F1782-83-84-86-87,12C508-509
+
+V 0.7.10 january 2012: added 12F617,12F1501,16F1503-07-08-09,16F720-21,16F72,16F707,
+ 18F13K22,18F14K22,18F23K22,18F43K22,18F24K22,18F44K22,18F25K22,
+ 18F45K22,18F26K22,18F46K22,18F8520,18F66J60,18F66J65,18F67J60,
+ 18F86J60,18F86J65,18F87J60,18F96J60,18F96J65,18F97J60,
+ fixed read/write binary files, various corrections,
+ added support for in-circuit debugging
+
+V 0.7.9 april 2011: first public version, using the same version number as op
+
+To compile: make
+To install: make install
+Can be compiled under windows with MinGW/MSYS and GTK bundle
+
diff --git a/resources.xml b/resources.xml
new file mode 100644
index 0000000..3a37c27
--- /dev/null
+++ b/resources.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gresources>
+ <gresource prefix="res">
+ <file preprocess="xml-stripblanks">opgui.glade</file>
+ <file>read.png</file>
+ <file>sys.png</file>
+ <file>write.png</file>
+ <file>style.css</file>
+ </gresource>
+</gresources>
diff --git a/strings.c b/strings.c
new file mode 100644
index 0000000..5899abe
--- /dev/null
+++ b/strings.c
@@ -0,0 +1,1070 @@
+// Strings.c v0.12.0
+
+#include "common.h"
+#define NL "\n"
+
+char *STR_ID[DIM];
+char *strings_it[DIM];
+char *strings_en[DIM];
+
+
+int strfind(const char* langid,const char* langfile){
+ FILE* f=fopen(langfile,"r");
+ char line[4096],*id,*string,*p;
+ char temp[32];
+ int i=0;
+// printf("file %s f=%d\n",langfile, f); fflush(stdout);
+ if(f){
+ temp[0]=0;
+ for(;fgets(line,sizeof(line),f);){
+ if(sscanf(line,"[%[^]]",temp)&&!strncmp(langid,temp,sizeof(temp))){
+ strings=malloc(DIM*sizeof(char*));
+ for(i=0;i<DIM;i++) strings[i]=0;
+ for(;fgets(line,sizeof(line),f);){
+ if(strlen(line)>0&&line[0]=='[') break; //start of new table
+ id=strtok(line," \t");
+ string=strtok(0,"\n");
+ for(i=0;string&&i<DIM;i++){
+ if(!strcmp(id,STR_ID[i])){
+ for(;string&&string[0]&&string[0]=='\t';string++);
+ for(;(p=strstr(string,"\\n"));){
+ for(p[0]='\n';p[1];p++) p[1]=p[2];
+ }
+ for(;(p=strstr(string,"\\r"));){
+ for(p[0]='\r';p[1];p++) p[1]=p[2];
+ }
+ strings[i]=malloc(strlen(string)+1);
+ strcpy(strings[i],string);
+ i=DIM;
+ }
+ }
+ }
+ for(i=0;i<DIM;i++){
+ if(strings[i]==0){
+ strings[i]=malloc(strlen(strings_en[i])+1);
+ strcpy(strings[i],strings_en[i]);
+ }
+ }
+ }
+ }
+ fclose(f);
+ }
+ return i; //i=0 if language table was not found
+}
+
+void GenerateLangFile(const char* langid,const char* langfile){
+ FILE* f=fopen(langfile,"a");
+ int i,j;
+ if(f){
+ fprintf(f,"\n\n[%s]\n",langid?langid:"x");
+ for(i=1;i<DIM;i++){
+ fprintf(f,"%s\t\t",STR_ID[i]);
+ for(j=0;strings_en[i][j];j++){
+ if(strings_en[i][j]=='\n') fprintf(f,"%s","\\n");
+ else if(strings_en[i][j]=='\r') fprintf(f,"%s","\\r");
+ else fprintf(f,"%c",strings_en[i][j]);
+ }
+ fprintf(f,"\n");
+ }
+ fclose(f);
+ }
+}
+
+void strinit()
+{
+ STR_ID[S_NL]=(char*) "S_NL";
+ STR_ID[S_noprog]=(char*) "S_noprog";
+ STR_ID[S_prog]="S_prog";
+ STR_ID[S_progDev]="S_progDev";
+ STR_ID[S_DevPermission]="S_DevPermission";
+ STR_ID[S_nodev_r]="S_nodev_r";
+ STR_ID[S_nodev_w]="S_nodev_w";
+ STR_ID[S_nodev]="S_nodev";
+ STR_ID[S_DevMismatch]="S_DevMismatch";
+ STR_ID[S_noV33reg]="S_noV33reg";
+ STR_ID[S_progver]="S_progver";
+ STR_ID[S_progid]="S_progid";
+ STR_ID[S_FWver2old]="S_FWver2old";
+ STR_ID[S_lowUsbV]="S_lowUsbV";
+ STR_ID[S_HiVPP]="S_HiVPP";
+ STR_ID[S_LowVPP]="S_LowVPP";
+ STR_ID[S_reg]="S_reg";
+ STR_ID[S_dev_det]="S_dev_det";
+ STR_ID[S_file]="S_file";
+ STR_ID[S_file2]="S_file2";
+ STR_ID[S_fileEEP]="S_fileEEP";
+ STR_ID[S_noDLL]="S_noDLL";
+ STR_ID[S_openEEfile]="S_openEEfile";
+ STR_ID[S_saveEEfile]="S_saveEEfile";
+ STR_ID[S_IhexShort]="S_IhexShort";
+ STR_ID[S_IhexChecksum]="S_IhexChecksum";
+ STR_ID[S_InvHandle]="S_InvHandle";
+ STR_ID[S_LogFile]="S_LogFile";
+ STR_ID[S_FileSaved]="S_FileSaved";
+ STR_ID[S_HVICSP]="S_HVICSP";
+ STR_ID[S_StartRead]="S_StartRead";
+ STR_ID[S_Read]="S_Read";
+ STR_ID[S_CodeReading]="S_CodeReading";
+ STR_ID[S_CodeReading1]="S_CodeReading1";
+ STR_ID[S_CodeReading2]="S_CodeReading2";
+ STR_ID[S_ReadEnd]="S_ReadEnd";
+ STR_ID[S_ReadID_CONFIG]="S_ReadID_CONFIG";
+ STR_ID[S_Read_CONFIG_A]="S_Read_CONFIG_A";
+ STR_ID[S_Read_EXE_A]="S_Read_EXE_A";
+ STR_ID[S_ReadEE]="S_ReadEE";
+ STR_ID[S_StartErase]="S_StartErase";
+ STR_ID[S_Writing]="S_Writing";
+ STR_ID[S_StartCodeProg]="S_StartCodeProg";
+ STR_ID[S_CodeWriting]="S_CodeWriting";
+ STR_ID[S_CodeWriting2]="S_CodeWriting2";
+ STR_ID[S_IDW]="S_IDW";
+ STR_ID[S_ConfigW]="S_ConfigW";
+ STR_ID[S_ConfigAreaW]="S_ConfigAreaW";
+ STR_ID[S_EEAreaW]="S_EEAreaW";
+ STR_ID[S_FuseAreaW]="S_FuseAreaW";
+ STR_ID[S_CodeV]="S_CodeV";
+ STR_ID[S_CodeV2]="S_CodeV2";
+ STR_ID[S_IDV]="S_IDV";
+ STR_ID[S_ConfigV]="S_ConfigV";
+ STR_ID[S_EEV]="S_EEV";
+ STR_ID[S_IntW]="S_IntW";
+ STR_ID[S_TotErr]="S_TotErr";
+ STR_ID[S_ComplErr]="S_ComplErr";
+ STR_ID[S_Compl]="S_Compl";
+ STR_ID[S_Ready]="S_Ready";
+ STR_ID[S_End]="S_End";
+ STR_ID[S_EndErr]="S_EndErr";
+ STR_ID[S_ProtErase]="S_ProtErase";
+ STR_ID[S_Inohex]="S_Inohex";
+ STR_ID[S_ReadErr]="S_ReadErr";
+ STR_ID[S_ReadCodeErr]="S_ReadCodeErr";
+ STR_ID[S_ReadCodeErr2]="S_ReadCodeErr2";
+ STR_ID[S_ReadEEErr]="S_ReadEEErr";
+ STR_ID[S_ConfigErr]="S_ConfigErr";
+ STR_ID[S_ReadConfigErr]="S_ReadConfigErr";
+ STR_ID[S_ErrOsccal]="S_ErrOsccal";
+ STR_ID[S_CodeWError]="S_CodeWError";
+ STR_ID[S_CodeWError2]="S_CodeWError2";
+ STR_ID[S_CodeWError3]="S_CodeWError3";
+ STR_ID[S_CodeWError4]="S_CodeWError4";
+ STR_ID[S_ConfigWErr]="S_ConfigWErr";
+ STR_ID[S_ConfigWErr2]="S_ConfigWErr2";
+ STR_ID[S_ConfigWErr3]="S_ConfigWErr3";
+ STR_ID[S_WErr1]="S_WErr1";
+ STR_ID[S_WErr2]="S_WErr2";
+ STR_ID[S_IDErr]="S_IDErr";
+ STR_ID[S_ICDErr]="S_ICDErr";
+ STR_ID[S_Calib1Err]="S_Calib1Err";
+ STR_ID[S_Calib2Err]="S_Calib2Err";
+ STR_ID[S_CodeVError]="S_CodeVError";
+ STR_ID[S_CodeVError2]="S_CodeVError2";
+ STR_ID[S_CodeVError3]="S_CodeVError3";
+ STR_ID[S_ErrSing]="S_ErrSing";
+ STR_ID[S_ErrPlur]="S_ErrPlur";
+ STR_ID[S_MaxErr]="S_MaxErr";
+ STR_ID[S_I2CInitErr]="S_I2CInitErr";
+ STR_ID[S_I2CAckErr]="S_I2CAckErr";
+ STR_ID[S_ComErr]="S_ComErr";
+ STR_ID[S_InsErr]="S_InsErr";
+ STR_ID[S_SyncErr]="S_SyncErr";
+ STR_ID[S_HVregErr]="S_HVregErr";
+ STR_ID[S_Log1]="S_Log1";
+ STR_ID[S_Log2]="S_Log2";
+ STR_ID[S_Log3]="S_Log3";
+ STR_ID[S_Log4]="S_Log4";
+ STR_ID[S_Log5]="S_Log5";
+ STR_ID[S_Log6]="S_Log6";
+ STR_ID[S_Log7]="S_Log7";
+ STR_ID[S_Log8]="S_Log8";
+ STR_ID[S_Log9]="S_Log9";
+ STR_ID[S_comTimeout]="S_comTimeout";
+ STR_ID[S_EraseTimeout]="S_EraseTimeout";
+ STR_ID[S_ConfigTimeout]="S_ConfigTimeout";
+ STR_ID[S_ConfigTimeout2]="S_ConfigTimeout2";
+ STR_ID[S_CodeTimeout]="S_CodeTimeout";
+ STR_ID[S_CodeTimeout2]="S_CodeTimeout2";
+ STR_ID[S_OsccalTimeout]="S_OsccalTimeout";
+ STR_ID[S_EETimeout]="S_EETimeout";
+ STR_ID[S_ConfigWTimeout]="S_ConfigWTimeout";
+ STR_ID[S_CodeWTimeout]="S_CodeWTimeout";
+ STR_ID[S_ConfigWTimeout2]="S_ConfigWTimeout2";
+ STR_ID[S_EEWTimeout]="S_EEWTimeout";
+ STR_ID[S_IDWTimeout]="S_IDWTimeout";
+ STR_ID[S_ConfigNWTimeout]="S_ConfigNWTimeout";
+ STR_ID[S_CodeVTimeout]="S_CodeVTimeout";
+ STR_ID[S_ConfigVTimeout]="S_ConfigVTimeout";
+ STR_ID[S_ProgModeTimeout]="S_ProgModeTimeout";
+ STR_ID[S_ProgModeXTimeout]="S_ProgModeXTimeout";
+ STR_ID[S_LogTimeout]="S_LogTimeout";
+ STR_ID[S_CodeMem]="S_CodeMem";
+ STR_ID[S_EEMem]="S_EEMem";
+ STR_ID[S_IDMem]="S_IDMem";
+ STR_ID[S_ConfigMem]="S_ConfigMem";
+ STR_ID[S_ConfigResMem]="S_ConfigResMem";
+ STR_ID[S_CodeMem2]="S_CodeMem2";
+ STR_ID[S_ExeMem]="S_ExeMem";
+ STR_ID[S_LPOsc]="S_LPOsc";
+ STR_ID[S_XTOsc]="S_XTOsc";
+ STR_ID[S_IntOsc]="S_IntOsc";
+ STR_ID[S_RCOsc]="S_RCOsc";
+ STR_ID[S_WDTON]="S_WDTON";
+ STR_ID[S_WDTOFF]="S_WDTOFF";
+ STR_ID[S_CPOFF]="S_CPOFF";
+ STR_ID[S_CPON]="S_CPON";
+ STR_ID[S_MCLRON]="S_MCLRON";
+ STR_ID[S_MCLROFF]="S_MCLROFF";
+ STR_ID[S_ChipID]="S_ChipID";
+ STR_ID[S_ChipID2]="S_ChipID2";
+ STR_ID[S_BKOsccal]="S_BKOsccal";
+ STR_ID[S_Osccal]="S_Osccal";
+ STR_ID[S_DevID]="S_DevID";
+ STR_ID[S_DevID2]="S_DevID2";
+ STR_ID[S_DevREV]="S_DevREV";
+ STR_ID[S_ConfigWord]="S_ConfigWord";
+ STR_ID[S_ConfigWord2]="S_ConfigWord2";
+ STR_ID[S_ConfigWordX]="S_ConfigWordX";
+ STR_ID[S_ConfigWordH]="S_ConfigWordH";
+ STR_ID[S_ConfigWordL]="S_ConfigWordL";
+ STR_ID[S_Config2Cal1]="S_Config2Cal1";
+ STR_ID[S_CalibWord1]="S_CalibWord1";
+ STR_ID[S_Calib1_2]="S_Calib1_2";
+ STR_ID[S_CalibWord2]="S_CalibWord2";
+ STR_ID[S_CalibWordX]="S_CalibWordX";
+ STR_ID[S_Protected]="S_Protected";
+ STR_ID[S_CodeLim]="S_CodeLim";
+ STR_ID[S_EELim]="S_EELim";
+ STR_ID[S_ConfigLim]="S_ConfigLim";
+ STR_ID[S_WbufLim]="S_WbufLim";
+ STR_ID[S_MaxRetry]="S_MaxRetry";
+ STR_ID[S_NoCode]="S_NoCode";
+ STR_ID[S_NoCode2]="S_NoCode2";
+ STR_ID[S_NoCalibW]="S_NoCalibW";
+ STR_ID[S_NoEEMem]="S_NoEEMem";
+ STR_ID[S_NoConfigW]="S_NoConfigW";
+ STR_ID[S_NoConfigW2]="S_NoConfigW2";
+ STR_ID[S_NoConfigW3]="S_NoConfigW3";
+ STR_ID[S_NoConfigW4]="S_NoConfigW4";
+ STR_ID[S_NoConfigW5]="S_NoConfigW5";
+ STR_ID[S_NoConfigW6]="S_NoConfigW6";
+ STR_ID[S_Empty]="S_Empty";
+ STR_ID[S_NextIns]="S_NextIns";
+ STR_ID[S_ForceConfigW]="S_ForceConfigW";
+ STR_ID[S_ForceConfigWx]="S_ForceConfigWx";
+ STR_ID[S_WarnFlashSize]="S_WarnFlashSize";
+ STR_ID[I_Fopen]="I_Fopen";
+ STR_ID[I_Fsave]="I_Fsave";
+ STR_ID[I_DevR]="I_DevR";
+ STR_ID[I_DevW]="I_DevW";
+ STR_ID[I_Info]="I_Info";
+ STR_ID[I_Data]="I_Data";
+ STR_ID[I_Opt]="I_Opt";
+ STR_ID[I_Dev]="I_Dev";
+ STR_ID[I_Type]="I_Type";
+ STR_ID[I_Speed]="I_Speed";
+ STR_ID[I_ReadRes]="I_ReadRes";
+ STR_ID[I_ID_BKo_W]="I_ID_BKo_W";
+ STR_ID[I_EE]="I_EE";
+ STR_ID[I_CalW]="I_CalW";
+ STR_ID[I_OSCW]="I_OSCW";
+ STR_ID[I_OSC]="I_OSC";
+ STR_ID[I_BKOSC]="I_BKOSC";
+ STR_ID[I_OSCF]="I_OSCF";
+ STR_ID[I_CONN]="I_CONN";
+ STR_ID[I_QUIT]="I_QUIT";
+ STR_ID[I_LOG]="I_LOG";
+ STR_ID[I_CK_V33]="I_CK_V33";
+ STR_ID[I_LANG]="I_LANG";
+ STR_ID[I_MAXERR]="I_MAXERR";
+ STR_ID[I_ADDR]="I_ADDR";
+ STR_ID[I_USBD]="I_USBD";
+ STR_ID[I_I2CDATAOUT]="I_I2CDATAOUT";
+ STR_ID[I_I2CDATATR]="I_I2CDATATR";
+ STR_ID[I_I2C_NB]="I_I2C_NB";
+ STR_ID[I_I2CMode]="I_I2CMode";
+ STR_ID[I_I2CSend]="I_I2CSend";
+ STR_ID[I_I2CReceive]="I_I2CReceive";
+ STR_ID[I_TestHW]="I_TestHW";
+ STR_ID[I_TestHWB]="I_TestHWB";
+ STR_ID[I_TestMSG]="I_TestMSG";
+ STR_ID[I_IO_Enable]="I_IO_Enable";
+ STR_ID[I_IO_Commands]="I_IO_Commands";
+ STR_ID[I_SPIMEM]="I_SPIMEM";
+ STR_ID[I_I2CMEM]="I_I2CMEM";
+ STR_ID[I_UWMEM]="I_UWMEM";
+ STR_ID[I_OWMEM]="I_OWMEM";
+ STR_ID[I_OWDEV]="I_OWDEV";
+ STR_ID[I_UNIOMEM]="I_UNIOMEM";
+ STR_ID[I_3V3REQUIRED]="I_3V3REQUIRED";
+ STR_ID[I_PIC_FORCECW]="I_PIC_FORCECW";
+ STR_ID[I_AT_FUSE]="I_AT_FUSE";
+ STR_ID[I_AT_FUSEH]="I_AT_FUSEH";
+ STR_ID[I_AT_FUSEX]="I_AT_FUSEX";
+ STR_ID[I_AT_LOCK]="I_AT_LOCK";
+ STR_ID[I_W_LANGFILE]="I_W_LANGFILE";
+ STR_ID[I_AT_FUSELF]="I_AT_FUSELF";
+ STR_ID[I_AT_COMM]="I_AT_COMM";
+ STR_ID[I_WAITS1]="I_WAITS1";
+ STR_ID[I_PRESSS1]="I_PRESSS1";
+ STR_ID[S_WaitS1W]="S_WaitS1W";
+ STR_ID[S_WaitS1R]="S_WaitS1R";
+ STR_ID[I_ICD_ENABLE]="I_ICD_ENABLE";
+ STR_ID[I_ICD_ADDRESS]="I_ICD_ADDRESS";
+ STR_ID[I_LOAD_COFF]="I_LOAD_COFF";
+ STR_ID[I_SHOW_PC]="I_SHOW_PC";
+ STR_ID[I_SHOW_STATUS]="I_SHOW_STATUS";
+ STR_ID[I_SHOW_BANK0]="I_SHOW_BANK0";
+ STR_ID[I_SHOW_BANK1]="I_SHOW_BANK1";
+ STR_ID[I_SHOW_BANK2]="I_SHOW_BANK2";
+ STR_ID[I_SHOW_BANK3]="I_SHOW_BANK3";
+ STR_ID[I_SHOW_EE]="I_SHOW_EE";
+ STR_ID[I_STOP]="I_STOP";
+ STR_ID[I_ICD_RUN]="I_ICD_RUN";
+ STR_ID[I_ICD_HALT]="I_ICD_HALT";
+ STR_ID[I_ICD_STEP]="I_ICD_STEP";
+ STR_ID[I_ICD_STEPOVER]="I_ICD_STEPOVER";
+ STR_ID[I_ICD_STOP]="I_ICD_STOP";
+ STR_ID[I_ICD_REFRESH]="I_ICD_REFRESH";
+ STR_ID[I_ICD_CMD]="I_ICD_CMD";
+ STR_ID[I_ICD_HELP]="I_ICD_HELP";
+ STR_ID[I_ICD_SOURCE]="I_ICD_SOURCE";
+ STR_ID[I_ICD_STATUS]="I_ICD_STATUS";
+ STR_ID[I_ICD_HELP_TXT]="I_ICD_HELP_TXT";
+ STR_ID[I_GUI_CMD_HELP]="I_GUI_CMD_HELP";
+ STR_ID[L_HELP]="L_HELP";
+ STR_ID[L_OPTERR]="L_OPTERR";
+ STR_ID[L_INFO1]="L_INFO1";
+ STR_ID[L_INFO2]="L_INFO2";
+ STR_ID[L_UNKNOWN]="L_UNKNOWN";
+ STR_ID[L_NAME]="L_NAME";
+ STR_ID[L_DEV_RO]="L_DEV_RO";
+ STR_ID[L_DEV_RW]="L_DEV_RW";
+
+ strings_it[S_NL]=NL;
+ strings_it[S_noprog]="Programmatore non rilevato" NL;
+ strings_it[S_prog]="Programmatore rilevato" NL;
+ strings_it[S_progDev]="Programmatore rilevato su %s" NL;
+ strings_it[S_DevPermission]="Impossibile aprire %s, assicurati di avere i diritti di lettura" NL;
+ strings_it[S_nodev_r]="Dispositivo non supportato in lettura" NL;
+ strings_it[S_nodev_w]="Dispositivo non supportato in scrittura" NL;
+ strings_it[S_nodev]="Dispositivo sconosciuto" NL;
+ strings_it[S_DevMismatch]="Attenzione: il dispositivo è diverso da quello specificato nei dati" NL;
+ strings_it[S_noV33reg]="Regolatore a 3,3V non rilevato" NL;
+ strings_it[S_progver]="Versione firmware %d.%d.%d" NL;
+ strings_it[S_progid]="ID Hardware: %d.%d.%d";
+ strings_it[S_FWver2old]="Questo firmware è troppo vecchio. E' richiesta la versione %s" NL;
+ strings_it[S_lowUsbV]="Tensione USB troppo bassa (VUSB<4.5V)" NL;
+ strings_it[S_HiVPP]="Attenzione: tensione regolatore troppo alta" NL NL;
+ strings_it[S_LowVPP]="Attenzione: tensione regolatore troppo bassa" NL NL;
+ strings_it[S_reg]="Regolatore avviato e funzionante dopo %dms VPP=%.1fV" NL NL;
+ strings_it[S_dev_det]="Dispositivo rilevato: vid=0x%04X pid=0x%04X" NL "Percorso: %s" NL;
+ strings_it[S_file]="File Hex8 (*.hex)|*.hex|Tutti i file (*.*)|*.*||";
+ strings_it[S_file2]="File Hex8 (*.hex)|*.hex|File binari (*.bin)|*.bin|Tutti i file (*.*)|*.*||";
+ strings_it[S_fileEEP]="File Hex8 (*.hex *.eep)|*.hex;*.eep|Tutti i file (*.*)|*.*||";
+ strings_it[S_noDLL]="Impossibile aprire hid.dll";
+ strings_it[S_openEEfile]="Apri file EEPROM";
+ strings_it[S_saveEEfile]="Salva file EEPROM";
+ strings_it[S_IhexShort]="Linea Ihex8 troppo corta:" NL "%s" NL;
+ strings_it[S_IhexChecksum]="Errore di checksum nella linea Ihex8:" NL "%s" NL;
+ strings_it[S_InvHandle]="Handle invalido" NL;
+ strings_it[S_LogFile]="Registro.txt";
+ strings_it[S_FileSaved]="Salvato %s" NL;
+ //
+ strings_it[S_HVICSP]="ICSP ad alta tensione" NL;
+ strings_it[S_StartRead]="Inizio lettura..." NL;
+ strings_it[S_Read]="Lettura ... ";
+ strings_it[S_CodeReading1]="Lettura codice ... ";
+ strings_it[S_CodeReading]="Lettura: %3d%%, ind. %03X";
+ strings_it[S_CodeReading2]="Lettura: %3d%%, ind. %05X";
+ strings_it[S_ReadEnd]="Lettura completata: %d word" NL;
+ strings_it[S_ReadID_CONFIG]="Lettura ID e CONFIG";
+ strings_it[S_Read_CONFIG_A]="Lettura area CONFIG ... ";
+ strings_it[S_Read_EXE_A]="Lettura area Executive ... ";
+ strings_it[S_ReadEE]="Lettura area EEPROM ... ";
+ strings_it[S_StartErase]="Cancellazione ... ";
+ strings_it[S_Writing]="Inizio scrittura..." NL;
+ strings_it[S_StartCodeProg]="Scrittura codice ... ";
+ strings_it[S_CodeWriting]="Scrittura: %3d%%, ind. %03X";
+ strings_it[S_CodeWriting2]="Scrittura: %3d%%, ind. %04X";
+ strings_it[S_IDW]="Scrittura ID ... ";
+ strings_it[S_ConfigW]="Scrittura CONFIG ... ";
+ strings_it[S_ConfigAreaW]="Scrittura area CONFIG ... ";
+ strings_it[S_EEAreaW]="Scrittura area EEPROM ... ";
+ strings_it[S_FuseAreaW]="Scrittura area FUSE ... ";
+ strings_it[S_CodeV]="Verifica codice ... ";
+ strings_it[S_CodeV2]="Verifica: %d%%, ind. %04X";
+ strings_it[S_IDV]="Verifica ID ... ";
+ strings_it[S_ConfigV]="Verifica CONFIG ... ";
+ strings_it[S_EEV]="Verifica EEPROM ... ";
+ strings_it[S_IntW]="Scrittura interrotta" NL;
+ strings_it[S_TotErr]="completata, %d errori totali" NL;
+ strings_it[S_ComplErr]="completata, %d errori" NL;
+ strings_it[S_Compl]="completata" NL;
+ strings_it[S_Ready]="pronto";
+ strings_it[S_End]= NL "Fine (%.2f s)" NL NL;
+ strings_it[S_EndErr]= NL "Fine (%.2f s) %d %s" NL NL;
+ strings_it[S_ProtErase]="Il dispositivo è protetto, sovrascrivo la protezione." NL;
+ strings_it[S_Inohex]="Errore: '%.4s' non sembra molto esadecimale, vero?" NL;
+ strings_it[S_ReadErr]="Errore in lettura: word richieste=%d, lette=%d" NL;
+ strings_it[S_ReadCodeErr]="Errore in lettura area programma, richieste %d word, lette %d" NL;
+ strings_it[S_ReadCodeErr2]="Errore in lettura area programma, richiesti %d byte, letti %d" NL;
+ strings_it[S_ReadEEErr]="Errore in lettura area EEPROM, richiesti %d byte, letti %d" NL;
+ strings_it[S_ConfigErr]="Errore in lettura area configurazione, richieste %d word, lette %d" NL;
+ strings_it[S_ReadConfigErr]="Errore in lettura area configurazione, richiesti %d byte, letti %d" NL;
+ strings_it[S_ErrOsccal]="Errore in lettura OSCCAL e BKOSCCAL";
+ strings_it[S_CodeWError]="Errore in scrittura all'indirizzo %3X: scritto %03X, letto %03X" NL;
+ strings_it[S_CodeWError2]="Errore in scrittura all'indirizzo %3X: scritto %04X, letto %04X" NL;
+ strings_it[S_CodeWError3]="Errore in scrittura all'indirizzo %4X: scritto %02X, letto %02X" NL;
+ strings_it[S_CodeWError4]="Errore in scrittura area programma, richiesti %d byte, scritti %d" NL;
+ strings_it[S_ConfigWErr]="Errore in scrittura config: scritto %03X, letto %03X" NL;
+ strings_it[S_ConfigWErr2]="Errore in scrittura CONFIG";
+ strings_it[S_ConfigWErr3]="Errore in scrittura config: scritto %04X, letto %04X" NL;
+ strings_it[S_WErr1]="Errore in scrittura %s: scritto %02X, letto %02X" NL;
+ strings_it[S_WErr2]="Errore in scrittura %s: scritto %04X, letto %04X" NL;
+ strings_it[S_IDErr]="Errore in scrittura ID%d: scritto %04X, letto %04X" NL;
+ strings_it[S_ICDErr]="Errore in scrittura ICD (0x%X): scritto %04X, letto %04X" NL;
+ strings_it[S_Calib1Err]="Errore in scrittura Calib1: scritto %04X, letto %04X" NL;
+ strings_it[S_Calib2Err]="Errore in scrittura Calib2: scritto %04X, letto %04X" NL;
+ strings_it[S_CodeVError]="Errore in verifica, indirizzo %04X (%d), scritto %02X, letto %02X" NL;
+ strings_it[S_CodeVError2]="Errore in verifica area programma, richiesti %d byte, letti %d" NL;
+ strings_it[S_CodeVError3]="Errore in verifica area programma, richieste %d word, lette %d" NL;
+ strings_it[S_ErrSing]="errore";
+ strings_it[S_ErrPlur]="errori";
+ strings_it[S_MaxErr]="Superato il massimo numero di errori (%d), scrittura interrotta" NL;
+ strings_it[S_I2CInitErr]="Errore di inizializzazione bus I2C" NL;
+ strings_it[S_I2CAckErr]="Errore di acknowledge I2C" NL;
+ strings_it[S_ComErr]="Errore di comunicazione" NL;
+ strings_it[S_InsErr]="Istruzione sconosciuta" NL;
+ strings_it[S_SyncErr]="Errore di sincronizzazione" NL;
+ strings_it[S_HVregErr]="Errore sul regolatore HV" NL;
+ strings_it[S_WarnFlashSize]="Attenzione, la dimensione della flash non corrisponde a quella del dispositivo scelto" NL;
+ //
+ strings_it[S_Log1]="i=%d(0x%X), k=%d(0x%X) NumberOfBytesRead=%d" NL;
+ strings_it[S_Log2]="i=%d, k=%d, errori=%d, NumberOfBytesRead=%d" NL NL;
+ strings_it[S_Log3]="i=%d, k2=%d NumberOfBytesRead=%d" NL;
+ strings_it[S_Log4]="Area config. errori=%d NumberOfBytesRead=%d" NL;
+ strings_it[S_Log5]="dim=%d(0x%X), dimx=%d(0x%X), dimx/wbuf=%d " NL NL;
+ strings_it[S_Log6]="i=%d(0x%X), NumberOfBytesRead=%d" NL NL;
+ strings_it[S_Log7]="i=%d(0x%X), k=%d(0x%X)" NL;
+ strings_it[S_Log8]="i=%d(0x%X), k=%d(0x%X), errori=%d" NL;
+ strings_it[S_Log9]="Area config. errori=%d" NL;
+ //
+ strings_it[S_comTimeout]="Timeout comunicazione" NL;
+ strings_it[S_EraseTimeout]="Timeout in cancellazione" NL;
+ strings_it[S_ConfigTimeout]="Timeout in lettura config" NL;
+ strings_it[S_ConfigTimeout2]="Timeout in lettura area config" NL;
+ strings_it[S_CodeTimeout]="Timeout in lettura, indirizzo %02X (%d)" NL;
+ strings_it[S_CodeTimeout2]="Timeout in lettura, indirizzo %04X (%d)" NL;
+ strings_it[S_OsccalTimeout]="Timeout in lettura osccal" NL;
+ strings_it[S_EETimeout]="Timeout in lettura EEPROM, indirizzo %02X (%d)" NL;
+ strings_it[S_ConfigWTimeout]="Timeout in verifica config" NL;
+ strings_it[S_CodeWTimeout]="Timeout in scrittura, indirizzo %02X (%d)" NL;
+ strings_it[S_ConfigWTimeout2]="Timeout in scrittura area config" NL;
+ strings_it[S_EEWTimeout]="Timeout in scrittura EEPROM, indirizzo %03X (%d)" NL;
+ strings_it[S_IDWTimeout]="Timeout in scrittura ID" NL;
+ strings_it[S_ConfigNWTimeout]="Timeout in scrittura CONFIG%d" NL;
+ strings_it[S_CodeVTimeout]="Timeout in verifica, indirizzo %04X (%d)" NL;
+ strings_it[S_ConfigVTimeout]="Timeout in verifica area config" NL;
+ strings_it[S_ProgModeTimeout]="Timeout in entrata program mode" NL;
+ strings_it[S_ProgModeXTimeout]="Timeout in uscita programmazione" NL;
+ strings_it[S_LogTimeout]="Timeout" NL;
+ //
+ strings_it[S_CodeMem]= NL "memoria CODICE:" NL;
+ strings_it[S_EEMem]= NL "memoria EEPROM:" NL;
+ strings_it[S_IDMem]= NL "memoria ID:" NL;
+ strings_it[S_ConfigMem]= NL "memoria CONFIG:" NL;
+ strings_it[S_ConfigResMem]= NL "Memoria configurazione e riservata:" NL;
+ strings_it[S_CodeMem2]= NL "Memoria programma:" NL;
+ strings_it[S_ExeMem]= NL "memoria Executive:" NL;
+ //
+ strings_it[S_LPOsc]="LP oscillator" NL;
+ strings_it[S_XTOsc]="XT oscillator" NL;
+ strings_it[S_IntOsc]="Internal osc." NL;
+ strings_it[S_RCOsc]="RC oscillator" NL;
+ strings_it[S_WDTON]="WDT ON" NL;
+ strings_it[S_WDTOFF]="WDT OFF" NL;
+ strings_it[S_CPOFF]="Code protection OFF" NL;
+ strings_it[S_CPON]="Code protection ON" NL;
+ strings_it[S_MCLRON]="Master clear ON" NL;
+ strings_it[S_MCLROFF]="Master clear OFF" NL;
+ strings_it[S_ChipID]="ID%d: 0x%03X ID%d: 0x%03X" NL;
+ strings_it[S_ChipID2]="ID%d: 0x%02X ID%d: 0x%02X" NL;
+ strings_it[S_BKOsccal]="Backup OSCCAL: 0x%03X" NL;
+ strings_it[S_Osccal]="OSCCAL: 0x%03X" NL;
+ strings_it[S_DevID]="DevID: 0x%04X" NL;
+ strings_it[S_DevID2]="DevID: 0x%02X%02X" NL;
+ strings_it[S_DevREV]="DevREV: 0x%04X" NL;
+ strings_it[S_ConfigWord]="Configuration word: 0x%03X" NL;
+ strings_it[S_Config2Cal1]="Configuration word2 o calibration word 1: 0x%03X" NL;
+ strings_it[S_ConfigWord2]="Configuration word2: 0x%04X" NL;
+ strings_it[S_ConfigWordX]="Configuration word %d: 0x%04X" NL;
+ strings_it[S_ConfigWordH]="CONFIG%dH: 0x%02X\t";
+ strings_it[S_ConfigWordL]="CONFIG%dL: 0x%02X" NL;
+ strings_it[S_CalibWord1]="Calibration word1: 0x%04X" NL;
+ strings_it[S_Calib1_2]="Calibration word 1 or 2: 0x%04X" NL;
+ strings_it[S_CalibWord2]="Calibration word2: 0x%04X" NL;
+ strings_it[S_CalibWordX]="Calibration word %d: 0x%04X" NL;
+ strings_it[S_Protected]="Dispositivo protetto";
+ //
+ strings_it[S_CodeLim]="Dimensione programma oltre i limiti" NL;
+ strings_it[S_EELim]="Dimensione eeprom oltre i limiti" NL;
+ strings_it[S_ConfigLim]="Dimensione area config oltre i limiti" NL;
+ strings_it[S_WbufLim]="Dimensione buffer scrittura oltre i limiti" NL;
+ strings_it[S_MaxRetry]="Max tentativi di scrittura: %d" NL;
+ //
+ strings_it[S_NoCode]="Area dati vuota" NL;
+ strings_it[S_NoCode2]="Niente da scrivere" NL;
+ strings_it[S_NoCalibW]="Impossibile trovare i dati di calibrazione" NL;
+ strings_it[S_NoEEMem]="Impossibile trovare i dati EEPROM" NL;
+ strings_it[S_NoConfigW]="Impossibile leggere la config word" NL;
+ strings_it[S_NoConfigW2]="Impossibile trovare la locazione CONFIG (0xFFF)" NL;
+ strings_it[S_NoConfigW3]="Impossibile trovare la locazione CONFIG (0x2007)" NL "Fine" NL;
+ strings_it[S_NoConfigW4]="Impossibile trovare la locazione CONFIG (0x2008)" NL "Fine" NL;
+ strings_it[S_NoConfigW5]="Impossibile trovare la locazione CONFIG (0x8007-0x8008)" NL "Fine" NL;
+ strings_it[S_NoConfigW6]="Impossibile trovare la locazione CONFIG (0x8007-0x800B)" NL "Fine" NL;
+ strings_it[S_Empty]="(vuoto)" NL;
+ strings_it[S_NextIns]="Prossima istruzione";
+ strings_it[S_ForceConfigW]="Forzo config word" NL;
+ strings_it[S_ForceConfigWx]="Forzo config word%d [0x%04X]=0x%04X" NL;
+ //
+ strings_it[I_CANCEL]="A_nnulla";
+ strings_it[I_OPEN]="_Apri";
+ strings_it[I_SAVE]="_Salva";
+ strings_it[I_Fopen]="Apri file";
+ strings_it[I_Fsave]="Salva file";
+ strings_it[I_DevR]="Leggi dispositivo";
+ strings_it[I_DevW]="Scrivi dispositivo";
+ strings_it[I_Info]="Informazioni";
+ strings_it[I_Data]="Dati";
+ strings_it[I_Opt]="Opzioni";
+ strings_it[I_Dev]="Dispositivo";
+ strings_it[I_Type]="Filtra per tipo";
+ strings_it[I_Speed]="Velocità";
+ strings_it[I_ReadRes]="Leggi area riservata";
+ strings_it[I_ID_BKo_W]="Programma ID e BKosccal";
+ strings_it[I_EE]="Leggi e programma EEPROM";
+ strings_it[I_CalW]="Programma Calib1 e 2";
+ strings_it[I_OSCW]="Scrivi OSCCal";
+ strings_it[I_OSC]="OSCCal";
+ strings_it[I_BKOSC]="Backup OSCCal";
+ strings_it[I_OSCF]="Da File";
+ strings_it[I_CONN]="Riconnetti";
+ strings_it[I_QUIT]="Quit";
+ strings_it[I_LOG]="Registra eventi su file";
+ strings_it[I_CK_V33]="Salta controllo regolatore a 3,3V";
+ strings_it[I_LANG]="Lingua";
+ strings_it[I_MAXERR]="Max errori in scrittura";
+ strings_it[I_ADDR]="Indirizzo";
+ strings_it[I_USBD]="Ritardo minimo USB (ms)";
+ strings_it[I_I2CDATAOUT]="Dati da scrivere";
+ strings_it[I_I2CDATATR]="Dati trasferiti";
+ strings_it[I_I2C_NB]="Byte da scrivere/leggere";
+ strings_it[I_I2CMode]="Modalità";
+ strings_it[I_I2CSend]="Invia";
+ strings_it[I_I2CReceive]="Ricevi";
+ strings_it[I_TestHW]="Test hardware: rimuovere eventuali dispositivi dal programmatore";
+ strings_it[I_TestHWB]="Test hardware";
+ strings_it[I_TestMSG]="Verifica sul programmatore il valore delle seguenti tensioni:";
+ strings_it[I_IO_Enable]="Abilita IO";
+ strings_it[I_IO_Commands]="Comandi manuali";
+ strings_it[I_SPIMEM]="Memoria SPI";
+ strings_it[I_I2CMEM]="Memoria I2C";
+ strings_it[I_UWMEM]="Memoria Microwire";
+ strings_it[I_OWMEM]="Memoria OneWire";
+ strings_it[I_OWDEV]="Dispositivo OneWire";
+ strings_it[I_UNIOMEM]="Memoria UNI/O";
+ strings_it[I_3V3REQUIRED]="adattatore 3,3V";
+ strings_it[I_PIC_FORCECW]="Forza config word";
+ strings_it[I_AT_FUSE]="Scrivi Fuse Low";
+ strings_it[I_AT_FUSEH]="Scrivi Fuse High";
+ strings_it[I_AT_FUSEX]="Scrivi Extended Fuse";
+ strings_it[I_AT_LOCK]="Scrivi Lock";
+ strings_it[I_AT_FUSELF]="Scrivi Fuse Low @3kHz";
+ strings_it[I_AT_COMM]="Comunicazione @ %.0f kbps" NL;
+ strings_it[I_W_LANGFILE]="Scrivi file linguaggio";
+ strings_it[I_WAITS1]="Inizia a scrivere/leggere con S1";
+ strings_it[I_PRESSS1]="Premi S1 per iniziare" NL;
+ strings_it[S_WaitS1W]="Premi S1 per programmare, un tasto per uscire" NL;
+ strings_it[S_WaitS1R]="Premi S1 per leggere, un tasto per uscire" NL;
+ strings_it[I_ICD_ENABLE]="Abilita ICD";
+ strings_it[I_ICD_ADDRESS]="Indirizzo routine ICD";
+ strings_it[I_LOAD_COFF]="Carica file COFF ...";
+ strings_it[I_SHOW_PC]="Mostra Program Counter";
+ strings_it[I_SHOW_STATUS]="Mostra Status";
+ strings_it[I_SHOW_BANK0]="Mostra banco memoria 0";
+ strings_it[I_SHOW_BANK1]="Mostra banco memoria 1";
+ strings_it[I_SHOW_BANK2]="Mostra banco memoria 2";
+ strings_it[I_SHOW_BANK3]="Mostra banco memoria 3";
+ strings_it[I_SHOW_EE]="Mostra EEPROM";
+ strings_it[I_STOP]="Fermato" NL;
+ strings_it[I_ICD_RUN]="Vai/continua";
+ strings_it[I_ICD_HALT]="Ferma";
+ strings_it[I_ICD_STEP]="Passo";
+ strings_it[I_ICD_STEPOVER]="Passo sopra";
+ strings_it[I_ICD_STOP]="Arresta";
+ strings_it[I_ICD_REFRESH]="Rinfresca";
+ strings_it[I_ICD_CMD]="linea di comando";
+ strings_it[I_ICD_HELP]="Aiuto";
+ strings_it[I_ICD_SOURCE]="Sorgente";
+ strings_it[I_ICD_STATUS]="Status";
+ strings_it[I_ICD_HELP_TXT]=
+ "Guida ICD" NL NL
+ "Doppio click sul nome di una variabile per" NL
+ "aggiungerla alla lista di osservazione;" NL
+ "doppio click nuovamente per rimuoverla." NL
+ "Scorciatoie:" NL
+ " F1 guida" NL
+ " F5 ferma" NL
+ " F7 passo" NL
+ " F8 passo sopra" NL
+ " F9 vai" NL
+ "Guida comandi:" NL
+ " variabile=x imposta variabile a x" NL
+ " [var ind.]=x imposta a x la variabile all'indirizzo ind." NL
+ " help guida comandi" NL
+ " break <ind> imposta breakpoint all'indirizzo <ind>" NL
+ " freeze [on,off] freeze periferiche" NL
+ " h[alt] ferma esecuzione" NL
+ " list <ind> mostra codice a partire da <ind>" NL
+ " p[rint] 0x<ind> osserva variabile all'indirizzo <ind>" NL
+ " p[rint] <var> osserva variabile <var>" NL
+ " p[rint] bank <b> osserva i registri nel banco <b>" NL
+ " p[rint] p <ind> osserva la memoria programma all'indirizzo <ind>" NL
+ " p[rint] ee <ind> osserva la memoria eeprom all'indirizzo <ind>" NL
+ " p[rint] ee osserva tutta la memoria eeprom" NL
+ " r[un] vai" NL
+ " s[tep] [n] passo singolo [n volte]" NL
+ " step over / ss [n] passo sopra le chiamate [n volte]" NL
+ " version leggi versione debugger" NL
+ " w[atch] variabile aggiungi/rimuovi variabile alla lista di osservazione" NL
+ " w[atch] 0x<ind> aggiungi/rimuovi variabile all'indirizzo <ind> alla lista di osservazione" NL;
+ strings_it[I_GUI_CMD_HELP]=
+ "Opzioni da linea di comando:" NL
+ " ?,h,help guida comandi" NL
+ " command <messaggio> invia <messaggio> al programmatore ed esci." NL
+ " Il messaggio è composto da byte esadecimali separati da uno spazio," NL
+ " fino a un massimo di 64; quelli non specificati vengono posti a 0" NL
+ " lang <lingua> carica <lingua>" NL
+ " langfile scrivi tutte le stringhe su file" NL;
+ strings_it[L_HELP]=
+ "op [opzioni]" NL NL
+ "-BKosccal carica BKosccal da file" NL
+ "-calib carica calibration da file" NL
+ "-command <messaggio> invia <messaggio> al programmatore ed esci." NL
+ " Il messaggio è composto da byte esadecimali separati da uno spazio," NL
+ " fino a un massimo di 64; quelli non specificati vengono posti a 0" NL
+ "-cwX <cw> forza config word X [1-7]" NL
+ "-d, device <disp.> dispositivo" NL
+ "-ee usa eeprom" NL
+ "-err <max> imposta massimo errori in scrittura" NL
+ "-fuse <val> scrive il byte fuse low (solo Atmel)" NL
+ "-fuseh <val> scrive il byte fuse high (solo Atmel)" NL
+ "-fusex <val> scrive il byte extended fuse (solo Atmel)" NL
+ "-fuse3k <val> scrive il byte fuse low a 3kHz (solo Atmel)" NL
+ "-h, help guida" NL
+ "-HWtest test hardware" NL
+ "-i, info informazioni programmatore" NL
+ "-icd <val> abilita ICD (goto indirizzo)" NL
+ "-i2c_r <N Ctr Ind> leggi N byte dal bus I2C" NL
+ "-i2c_r2 <N Ctr Ind(2)> leggi N byte dal bus I2C (indirizzi 16b)" NL
+ "-i2c_w <N Ctr Ind Dati> scrivi N byte sul bus I2C" NL
+ "-i2c_w2 <N Ctr Ind(2) Dati> scrivi N byte sul bus I2C (indirizzi 16b)" NL
+ "-i2cspeed <s> cambia velocità I2C: 0=100k,1=200k,2=500k,3=800k" NL
+ "-id usa ID" NL
+ "-l, log [=file] salva registro" NL
+ "-lang <lingua> carica <lingua>" NL
+ "-langfile scrivi tutte le stringhe su file" NL
+ "-lock <val> scrive il byte lock (solo Atmel)" NL
+ "-mode <mode> SPI mode: 00,01,10,11" NL
+ "-nolvcheck salta controllo regolatore a 3,3V" NL
+ "-osccal carica osccal da file invece che dal valore salvato prima della cancellazione" NL
+ "-p, path <percorso> percorso programmatore [/dev/usb/hiddev0]" NL
+ "-pid <pid> pid programmatore [0x100]" NL
+ "-r, reserved leggi area riservata" NL
+ "-rep <n> dimensione report [64]" NL
+ "-s1, S1 Programmazione multipla comandata da S1" NL
+ "-s, save <file> salva su file Ihex" NL
+ "-se, saveEE <file> salva EEPROM su file Ihex (solo ATxxxx)" NL
+ "-spi_r <N> leggi N byte dal bus SPI" NL
+ "-spi_w <N Dati> scrivi N byte sul bus SPI" NL
+ "-spispeed <s> cambia velocità SPI: 0=100k,1=200k,2=300k,3=500k" NL
+ "-support dispositivi supportati" NL
+ "-use_BKosccal copia BKosccal su osccal" NL
+ "-v, version versione" NL
+ "-vid <vid> vid programmatore [0x4D8]" NL
+ "-w, write <file> scrivi file Ihex" NL
+ "-we, writeEE <file> scrivi EEPROM file Ihex (solo ATxxxx)" NL
+ "" NL
+ "es. op -d 12F683 -s prova.hex" NL;
+ strings_it[L_OPTERR]="Errore nelle opzioni" NL;
+ strings_it[L_INFO1]="vid 0x%04hx pid 0x%04hx versione 0x%04hx ";
+ strings_it[L_INFO2]= NL "bus: %d devnum: %d ifnum: %d" NL;
+ strings_it[L_UNKNOWN]="sconosciuto";
+ strings_it[L_NAME]="Il dispositivo su %s si chiama %s" NL;
+ strings_it[L_DEV_RO]="Dispositivi supportati in sola lettura:";
+ strings_it[L_DEV_RW]="Dispositivi supportati in lettura e scrittura:";
+
+// ENGLISH strings
+ strings_en[S_NL]=NL;
+ strings_en[S_noprog]="Programmer not detected" NL;
+ strings_en[S_prog]="Programmer detected" NL;
+ strings_en[S_progDev]="Programmer detected on %s" NL;
+ strings_en[S_DevPermission]="Cannot open %s, make sure you have read permission on it" NL;
+ strings_en[S_nodev_r]="Device not supported for reading" NL;
+ strings_en[S_nodev_w]="Device not supported for writing" NL;
+ strings_en[S_nodev]="Unknown device" NL;
+ strings_en[S_DevMismatch]="Warning: the device is different from what specified in source data" NL;
+ strings_en[S_noV33reg]="3.3V Regulator not detected" NL;
+ strings_en[S_progver]="Firmware version %d.%d.%d" NL;
+ strings_en[S_progid]="Hardware ID: %d.%d.%d";
+ strings_en[S_FWver2old]="This firmware is too old. Version %s is required" NL;
+ strings_en[S_lowUsbV]="USB voltage too low (VUSB<4.5V)" NL;
+ strings_en[S_HiVPP]="Warning: regulator voltage too high" NL NL;
+ strings_en[S_LowVPP]="Warning: regulator voltage too low" NL NL;
+ strings_en[S_reg]="Regulator up and running after %dms VPP=%.1fV" NL NL;
+ strings_en[S_dev_det]="Device detected: vid=0x%04X pid=0x%04X" NL "Path: %s" NL;
+ strings_en[S_file]="Hex8 files (*.hex)|*.hex|All files (*.*)|*.*||";
+ strings_en[S_file2]="Hex8 files (*.hex)|*.hex|Binary files (*.bin)|*.bin|All files (*.*)|*.*||";
+ strings_en[S_fileEEP]="Hex8 files (*.hex *.eep)|*.hex;*.eep|All files (*.*)|*.*||";
+ strings_en[S_noDLL]="Error opening hid.dll";
+ strings_en[S_openEEfile]="Open EEPROM file";
+ strings_en[S_saveEEfile]="Save EEPROM file";
+ //
+ strings_en[S_IhexShort]="Intel hex8 line too short:" NL "%s" NL;
+ strings_en[S_IhexChecksum]="Intel hex8 checksum error in line:" NL "%s" NL;
+ strings_en[S_InvHandle]="Invalid handle" NL;
+ strings_en[S_LogFile]="Log.txt";
+ strings_en[S_FileSaved]="Saved file %s" NL;
+ //
+ strings_en[S_HVICSP]="High Voltage ICSP" NL;
+ strings_en[S_StartRead]="Reading ..." NL;
+ strings_en[S_Read]="Reading ... ";
+ strings_en[S_CodeReading1]="Reading code ... ";
+ strings_en[S_CodeReading]="Reading: %3d%%, add. %03X";
+ strings_en[S_CodeReading2]="Reading: %3d%%, add. %05X";
+ strings_en[S_ReadEnd]="Reading completed: %d words" NL;
+ strings_en[S_ReadID_CONFIG]="Reading ID and CONFIG";
+ strings_en[S_Read_CONFIG_A]="Reading CONFIG area ... ";
+ strings_en[S_Read_EXE_A]="Reading Executive area ... ";
+ strings_en[S_ReadEE]="Reading EEPROM ... ";
+ strings_en[S_StartErase]="Erasing ... ";
+ strings_en[S_Writing]="Writing ..." NL;
+ strings_en[S_StartCodeProg]="Writing code ... ";
+ strings_en[S_CodeWriting]="Writing: %3d%%, add. %03X";
+ strings_en[S_CodeWriting2]="Writing: %3d%%, add. %04X";
+ strings_en[S_IDW]="Writing ID ... ";
+ strings_en[S_ConfigW]="Writing CONFIG ... ";
+ strings_en[S_ConfigAreaW]="Writing CONFIG area ... ";
+ strings_en[S_EEAreaW]="Writing EEPROM ... ";
+ strings_en[S_FuseAreaW]="Writing FUSE area ... ";
+ strings_en[S_CodeV]="Verifying code ... ";
+ strings_en[S_CodeV2]="Verifying: %d%%, add. %04X";
+ strings_en[S_IDV]="Verifying ID ... ";
+ strings_en[S_ConfigV]="Verifying CONFIG ... ";
+ strings_en[S_EEV]="Verifying EEPROM ... ";
+ strings_en[S_IntW]="Write interrupted" NL;
+ strings_en[S_TotErr]="completed, %d total errors" NL;
+ strings_en[S_ComplErr]="completed, %d errors" NL;
+ strings_en[S_Compl]="completed" NL;
+ strings_en[S_Ready]="ready";
+ strings_en[S_End]= NL "End (%.2f s)" NL NL;
+ strings_en[S_EndErr]= NL "End (%.2f s) %d %s" NL NL;
+ strings_en[S_ProtErase]="Device protected, overriding protection." NL;
+ //
+ strings_en[S_Inohex]="Error: '%.4s' doesn't look very hexadecimal, right?" NL;
+ strings_en[S_ReadErr]="Read error: requested words=%d, read=%d" NL;
+ strings_en[S_ReadCodeErr]="Error reading code area, requested %d words, read %d" NL;
+ strings_en[S_ReadCodeErr2]="Error reading code area, requested %d bytes, read %d" NL;
+ strings_en[S_ReadEEErr]="Error reading EEPROM area, requested %d bytes, read %d" NL;
+ strings_en[S_ConfigErr]="Error reading configuration area, requested %d words, read %d" NL;
+ strings_en[S_ReadConfigErr]="Error reading configuration area, requested %d bytes, read %d" NL;
+ strings_en[S_ErrOsccal]="Error reading OSCCAL and BKOSCCAL";
+ strings_en[S_CodeWError]="Error writing address %3X: written %03X, read %03X" NL;
+ strings_en[S_CodeWError2]="Error writing address %3X: written %04X, read %04X" NL;
+ strings_en[S_CodeWError3]="Error writing address %4X: written %02X, read %02X" NL;
+ strings_en[S_CodeWError4]="Error writing code area, requested %d bytes, written %d" NL;
+ strings_en[S_ConfigWErr]="Error writing config area: written %03X, read %03X" NL;
+ strings_en[S_ConfigWErr2]="Error writing CONFIG";
+ strings_en[S_ConfigWErr3]="Error writing config area: written %04X, read %04X" NL;
+ strings_en[S_WErr1]="Error writing %s: written %02X, read %02X" NL;
+ strings_en[S_WErr2]="Error writing %s: written %04X, read %04X" NL;
+ strings_en[S_IDErr]="Error writing ID%d: written %04X, read %04X" NL;
+ strings_en[S_ICDErr]="Error writing ICD (0x%X): written %04X, read %04X" NL;
+ strings_en[S_Calib1Err]="Error writing Calib1: written %04X, read %04X" NL;
+ strings_en[S_Calib2Err]="Error writing Calib2: written %04X, read %04X" NL;
+ strings_en[S_CodeVError]="Error verifying address %04X (%d), written %02X, read %02X" NL;
+ strings_en[S_CodeVError2]="Error verifying code area, requested %d bytes, read %d" NL;
+ strings_en[S_CodeVError3]="Error verifying code area, requested %d words, read %d" NL;
+ strings_en[S_ErrSing]="error";
+ strings_en[S_ErrPlur]="errors";
+ strings_en[S_MaxErr]="Exceeded maximum number of errors (%d), write interrupted" NL;
+ strings_en[S_I2CInitErr]="Error initializing I2C bus" NL;
+ strings_en[S_I2CAckErr]="I2C acknowledge error" NL;
+ strings_en[S_ComErr]="Communication error" NL;
+ strings_en[S_InsErr]="Unknown instruction" NL;
+ strings_en[S_SyncErr]="Synchronization error" NL;
+ strings_en[S_HVregErr]="HV regulator error" NL;
+ //
+ strings_en[S_Log1]="i=%d(0x%X), k=%d(0x%X) NumberOfBytesRead=%d" NL;
+ strings_en[S_Log2]="i=%d, k=%d, errors=%d, NumberOfBytesRead=%d" NL NL;
+ strings_en[S_Log3]="i=%d, k2=%d NumberOfBytesRead=%d" NL;
+ strings_en[S_Log4]="Config area. errors=%d NumberOfBytesRead=%d" NL;
+ strings_en[S_Log5]="dim=%d(0x%X), dimx=%d(0x%X), dimx/wbuf=%d " NL NL;
+ strings_en[S_Log6]="i=%d(0x%X), NumberOfBytesRead=%d" NL NL;
+ strings_en[S_Log7]="i=%d(0x%X), k=%d(0x%X)" NL;
+ strings_en[S_Log8]="i=%d(0x%X), k=%d(0x%X), errors=%d" NL;
+ strings_en[S_Log9]="Config area. errors=%d" NL;
+ //
+ strings_en[S_comTimeout]="Communication timeout" NL;
+ strings_en[S_EraseTimeout]="Timeout during erase" NL;
+ strings_en[S_ConfigTimeout]="Timeout reading CONFIG" NL;
+ strings_en[S_ConfigTimeout2]="Timeout reading config area" NL;
+ strings_en[S_CodeTimeout]="Timeout reading address %02X (%d)" NL;
+ strings_en[S_CodeTimeout2]="Timeout reading address %04X (%d)" NL;
+ strings_en[S_OsccalTimeout]="Timeout reading osccal" NL;
+ strings_en[S_EETimeout]="Timeout reading EEPROM, address %02X (%d)" NL;
+ strings_en[S_ConfigWTimeout]="Timeout verifying config" NL;
+ strings_en[S_CodeWTimeout]="Timeout writing address %02X (%d)" NL;
+ strings_en[S_ConfigWTimeout2]="Timeout writing config area" NL;
+ strings_en[S_EEWTimeout]="Timeout writing EEPROM, address %03X (%d)" NL;
+ strings_en[S_IDWTimeout]="Timeout writing ID" NL;
+ strings_en[S_ConfigNWTimeout]="Timeout writing CONFIG%d" NL;
+ strings_en[S_CodeVTimeout]="Timeout verifying address %04X (%d)" NL;
+ strings_en[S_ConfigVTimeout]="Timeout verifying config area" NL;
+ strings_en[S_ProgModeTimeout]="Timeout entering program mode" NL;
+ strings_en[S_ProgModeXTimeout]="Timeout exiting program mode" NL;
+ strings_en[S_LogTimeout]="Timeout" NL;
+ //
+ strings_en[S_CodeMem]= NL "Code memory:" NL;
+ strings_en[S_EEMem]= NL "EEPROM memory:" NL;
+ strings_en[S_IDMem]= NL "ID:" NL;
+ strings_en[S_ConfigMem]= NL "CONFIG:" NL;
+ strings_en[S_ConfigResMem]= NL "Configuration and reserved memory:" NL;
+ strings_en[S_CodeMem2]= NL "Code memory:" NL;
+ strings_en[S_ExeMem]= NL "Executive memory:" NL;
+ //
+ strings_en[S_LPOsc]="LP oscillator" NL;
+ strings_en[S_XTOsc]="XT oscillator" NL;
+ strings_en[S_IntOsc]="Internal osc." NL;
+ strings_en[S_RCOsc]="RC oscillator" NL;
+ strings_en[S_WDTON]="WDT ON" NL;
+ strings_en[S_WDTOFF]="WDT OFF" NL;
+ strings_en[S_CPOFF]="Code protection OFF" NL;
+ strings_en[S_CPON]="Code protection ON" NL;
+ strings_en[S_MCLRON]="Master clear ON" NL;
+ strings_en[S_MCLROFF]="Master clear OFF" NL;
+ strings_en[S_ChipID]="ID%d: 0x%03X ID%d: 0x%03X" NL;
+ strings_en[S_ChipID2]="ID%d: 0x%02X ID%d: 0x%02X" NL;
+ strings_en[S_BKOsccal]="Backup OSCCAL: 0x%03X" NL;
+ strings_en[S_Osccal]="OSCCAL: 0x%03X" NL;
+ strings_en[S_DevID]="DevID: 0x%04X" NL;
+ strings_en[S_DevID2]="DevID: 0x%02X%02X" NL;
+ strings_en[S_DevREV]="DevREV: 0x%04X" NL;
+ strings_en[S_ConfigWord]="Configuration word: 0x%03X" NL;
+ strings_en[S_Config2Cal1]="Configuration word2 or calibration word 1: 0x%03X" NL;
+ strings_en[S_ConfigWord2]="Configuration word2: 0x%04X" NL;
+ strings_en[S_ConfigWordX]="Configuration word %d: 0x%04X" NL;
+ strings_en[S_ConfigWordH]="CONFIG%dH: 0x%02X\t";
+ strings_en[S_ConfigWordL]="CONFIG%dL: 0x%02X" NL;
+ strings_en[S_CalibWord1]="Calibration word1: 0x%04X" NL;
+ strings_en[S_Calib1_2]="Calibration word 1 or 2: 0x%04X" NL;
+ strings_en[S_CalibWord2]="Calibration word2: 0x%04X" NL;
+ strings_en[S_CalibWordX]="Calibration word %d: 0x%04X" NL;
+ strings_en[S_Protected]="protected device";
+ //
+ strings_en[S_CodeLim]="Code size exceeds limits" NL;
+ strings_en[S_EELim]="Eeprom size exceeds limits" NL;
+ strings_en[S_ConfigLim]="Config area size exceeds limits" NL;
+ strings_en[S_WbufLim]="Write buffer size exceeds limits" NL;
+ strings_en[S_MaxRetry]="Max retries in writing: %d" NL;
+ //
+ strings_en[S_NoCode]="Data area is empty" NL;
+ strings_en[S_NoCode2]="Nothing to write" NL;
+ strings_en[S_NoCalibW]="Can't find calibration data" NL;
+ strings_en[S_NoEEMem]="Can't find EEPROM data" NL;
+ strings_en[S_NoConfigW]="Impossibile leggere la config word" NL;
+ strings_en[S_NoConfigW2]="Can't find CONFIG location (0xFFF)" NL;
+ strings_en[S_NoConfigW3]="Can't find CONFIG location (0x2007)" NL "End" NL;
+ strings_en[S_NoConfigW4]="Can't find CONFIG location (0x2008)" NL "End" NL;
+ strings_en[S_NoConfigW5]="Can't find CONFIG location (0x8007-0x8008)" NL "End" NL;
+ strings_en[S_NoConfigW6]="Can't find CONFIG location (0x8007-0x800B)" NL "End" NL;
+ strings_en[S_Empty]="(empty)" NL;
+ strings_en[S_NextIns]="Next instruction";
+ strings_en[S_ForceConfigW]="Forcing config words" NL;
+ strings_en[S_ForceConfigWx]="Forcing config word%d [0x%04X]=0x%04X" NL;
+ strings_en[S_WarnFlashSize]="Warning, flash size is different from the expected value" NL;
+ //
+ strings_en[I_CANCEL]="_Cancel";
+ strings_en[I_OPEN]="_Open";
+ strings_en[I_SAVE]="_Save";
+ strings_en[I_Fopen]="Open file";
+ strings_en[I_Fsave]="Save file";
+ strings_en[I_DevR]="Read device";
+ strings_en[I_DevW]="Write device";
+ strings_en[I_Info]="Info";
+ strings_en[I_Data]="Data";
+ strings_en[I_Opt]="Options";
+ strings_en[I_Dev]="Device";
+ strings_en[I_Type]="Filter by type";
+ strings_en[I_Speed]="Speed";
+ strings_en[I_ReadRes]="Read reserved area";
+ strings_en[I_ID_BKo_W]="Write ID and BKosccal";
+ strings_en[I_EE]="Read and write EEPROM";
+ strings_en[I_CalW]="Write Calib1 e 2";
+ strings_en[I_OSCW]="Write OSCCal";
+ strings_en[I_OSC]="OSCCal";
+ strings_en[I_BKOSC]="Backup OSCCal";
+ strings_en[I_OSCF]="From File";
+ strings_en[I_CONN]="Reconnect";
+ strings_en[I_QUIT]="Quit";
+ strings_en[I_LOG]="Log activity";
+ strings_en[I_CK_V33]="Skip 3.3V regulator check";
+ strings_en[I_LANG]="Language";
+ strings_en[I_MAXERR]="Max errors during write";
+ strings_en[I_ADDR]="Address";
+ strings_en[I_USBD]="Min USB delay (ms)";
+ strings_en[I_I2CDATAOUT]="Data to send";
+ strings_en[I_I2CDATATR]="Data transferred";
+ strings_en[I_I2C_NB]="Bytes to read/write";
+ strings_en[I_I2CMode]="Mode";
+ strings_en[I_I2CSend]="Send";
+ strings_en[I_I2CReceive]="Receive";
+ strings_en[I_TestHW]="Hardware test: remove any device from programmer";
+ strings_en[I_TestHWB]="Hardware test";
+ strings_en[I_TestMSG]="Verify on the programmer the value of the following voltages:";
+ strings_en[I_IO_Enable]="Enable IO";
+ strings_en[I_IO_Commands]="Manual commands";
+ strings_en[I_SPIMEM]="SPI Memory";
+ strings_en[I_I2CMEM]="I2C Memory";
+ strings_en[I_UWMEM]="Microwire Memory";
+ strings_en[I_OWMEM]="OneWire Memory";
+ strings_en[I_OWDEV]="OneWire Device";
+ strings_en[I_UNIOMEM]="UNI/O Memory";
+ strings_en[I_3V3REQUIRED]="3.3V adapter";
+ strings_en[I_PIC_FORCECW]="Force config word";
+ strings_en[I_AT_FUSE]="Write Fuse Low";
+ strings_en[I_AT_FUSEH]="Write Fuse High";
+ strings_en[I_AT_FUSEX]="Write Extended Fuse";
+ strings_en[I_AT_LOCK]="Write Lock";
+ strings_en[I_AT_FUSELF]="Write Fuse Low @3kHz";
+ strings_en[I_AT_COMM]="Communicating @ %.0f kbps" NL;
+ strings_en[I_W_LANGFILE]="Write language file";
+ strings_en[I_WAITS1]="Wait for S1 before read/write";
+ strings_en[I_PRESSS1]="Press S1 to start" NL;
+ strings_en[S_WaitS1W]="Press S1 to program, any key to exit";
+ strings_en[S_WaitS1R]="Press S1 to read, any key to exit";
+ strings_en[I_ICD_ENABLE]="Enable ICD";
+ strings_en[I_ICD_ADDRESS]="ICD routine address";
+ strings_en[I_LOAD_COFF]="Load COFF file ...";
+ strings_en[I_SHOW_PC]="Show Program Counter";
+ strings_en[I_SHOW_STATUS]="Show status registers";
+ strings_en[I_SHOW_BANK0]="Show memory bank 0";
+ strings_en[I_SHOW_BANK1]="Show memory bank 1";
+ strings_en[I_SHOW_BANK2]="Show memory bank 2";
+ strings_en[I_SHOW_BANK3]="Show memory bank 3";
+ strings_en[I_SHOW_EE]="show EEPROM";
+ strings_en[I_STOP]="Stopped" NL;
+ strings_en[I_ICD_RUN]="Run/Continue";
+ strings_en[I_ICD_HALT]="Halt";
+ strings_en[I_ICD_STEP]="Step";
+ strings_en[I_ICD_STEPOVER]="Step over";
+ strings_en[I_ICD_STOP]="Stop";
+ strings_en[I_ICD_REFRESH]="Refresh";
+ strings_en[I_ICD_CMD]="Command line";
+ strings_en[I_ICD_HELP]="Help";
+ strings_en[I_ICD_SOURCE]="Source";
+ strings_en[I_ICD_STATUS]="Status";
+ strings_en[I_ICD_HELP_TXT]=
+ "ICD help" NL NL
+ "Double click variable name to add to watch list;" NL
+ "double click again to remove it." NL
+ "Key shortcuts:" NL
+ " F1 help" NL
+ " F5 halt" NL
+ " F7 step" NL
+ " F8 step over" NL
+ " F9 run" NL
+ "Command-line help:" NL
+ " variable=x set variable to x" NL
+ " [var addr]=x set variable at addr to x" NL
+ " help command help" NL
+ " break <addr> set breakpoint at address <addr>" NL
+ " freeze [on,off] freeze peripherals" NL
+ " h[alt] halt execution" NL
+ " list <addr> show code starting from <addr>" NL
+ " p[rint] 0x<addr> print variable at address <addr>" NL
+ " p[rint] <var> print variable <var>" NL
+ " p[rint] bank <b> print registers in bank <b>" NL
+ " p[rint] p <addr> print program memory at address <addr>" NL
+ " p[rint] ee <addr> print eeprom memory at address <addr>" NL
+ " p[rint] ee print all eeprom memory" NL
+ " r[un] run" NL
+ " s[tep] [n] single step [n times]" NL
+ " step over / ss [n] step over calls [n times]" NL
+ " version read debugger version" NL
+ " w[atch] variable add/remove watch for variable" NL
+ " w[atch] 0x<addr> add/remove watch at address <addr>" NL;
+ strings_en[I_GUI_CMD_HELP]=
+ "Command line options:" NL
+ " ?,h,help this help" NL
+ " command <message> send <message> to the programmer and exit." NL
+ " The message is composed of up to 64 hexadecimal bytes separated by a space;" NL
+ " those not specified are 0" NL
+ " lang <language> load <language> strings" NL
+ " langfile write all strings to file" NL;
+ strings_en[L_HELP]="op [options]" NL
+ "-BKosccal load BKosccal from file" NL
+ "-calib load calibration from file" NL
+ "-command <message> send <message> to the programmer and exit." NL
+ " The message is composed of up to 64 hexadecimal bytes separated by a space;" NL
+ " those not specified are 0" NL
+ "-cwX <cw> force config word X [1-7]" NL
+ "-d, device <dev.> device" NL
+ "-ee use eeprom" NL
+ "-err <max> max errors during writing" NL
+ "-fuse <val> write fuse low byte (Atmel only)" NL
+ "-fuseh <val> write fuse high byte (Atmel only)" NL
+ "-fusex <val> write extended fuse byte (Atmel only)" NL
+ "-fuse3k <val> write fuse low byte at 3 kHz (Atmel only)" NL
+ "-h, help help" NL
+ "-HWtest hardware test" NL
+ "-i, info informations about programmer" NL
+ "-i2c_r <N Ctr Addr> read N bytes from I2C bus" NL
+ "-i2c_r2 <N Ctr Addr(2)> read N bytes from I2C bus (16b address)" NL
+ "-i2c_w <N Ctr Addr Data> write N bytes to I2C bus" NL
+ "-i2c_w2 <N Ctr Addr(2) D.> write N bytes to I2C bus (16b address)" NL
+ "-i2cspeed <s> set I2C speed: 0=100k,1=200k,2=500k,3=800k" NL
+ "-id use ID" NL
+ "-icd <val> enable ICD (goto address)" NL
+ "-l, log [=file] save log" NL
+ "-lang <language> load <language> strings" NL
+ "-langfile write all strings to file" NL
+ "-lock <val> write lock byte (Atmel only)" NL
+ "-mode <mode> SPI mode: 00,01,10,11" NL
+ "-nolvcheck skip 3.3V regulator check" NL
+ "-osccal loads osccal from file instead of using the value saved before erase" NL
+ "-p, path <path> programmer path [/dev/usb/hiddev0]" NL
+ "-pid <pid> programmer pid [0x100]" NL
+ "-r, reserved read reserved area" NL
+ "-rep <n> report size [64]" NL
+ "-s1, S1 Multiple programming triggered by S1" NL
+ "-s, save <file> save Ihex file" NL
+ "-se, saveEE <file> save EEPROM on Ihex file (ATxxxx only)" NL
+ "-spi_r <N> read N bytes from SPI bus" NL
+ "-spi_w <N Data> write N bytes to SPI bus" NL
+ "-spispeed <s> set SPI speed: 0=100k,1=200k,2=500k,3=800k" NL
+ "-support supported devices" NL
+ "-use_BKosccal copy BKosccal to osccal" NL
+ "-v, version version" NL
+ "-vid <vid> programmer vid [0x4D8]" NL
+ "-w, write <file> write Ihex file" NL
+ "-we, writeEE <file> write EEPROM on Ihex file (ATxxxx only)" NL
+ "" NL
+ "ex. op -d 12F683 -s test.hex" NL;
+ strings_en[L_OPTERR]="Error in command-line options" NL;
+ strings_en[L_INFO1]="vid 0x%04hx pid 0x%04hx version 0x%04hx ";
+ strings_en[L_INFO2]= NL "bus: %d devnum: %d ifnum: %d" NL;
+ strings_en[L_UNKNOWN]="Unknown";
+ strings_en[L_NAME]="The device on %s says its name is %s" NL;
+ strings_en[L_DEV_RO]="Devices supported for reading only:";
+ strings_en[L_DEV_RW]="Devices supported for reading and writing:";
+}
diff --git a/strings.h b/strings.h
new file mode 100644
index 0000000..7c3c58a
--- /dev/null
+++ b/strings.h
@@ -0,0 +1,282 @@
+// Strings.h v0.12.0
+
+enum S {
+ S_NL,
+ S_noprog,
+ S_prog,
+ S_progDev,
+ S_DevPermission,
+ S_nodev_r,
+ S_nodev_w,
+ S_nodev,
+ S_DevMismatch,
+ S_noV33reg,
+ S_progver,
+ S_progid,
+ S_FWver2old,
+ S_lowUsbV,
+ S_HiVPP,
+ S_LowVPP,
+ S_reg,
+ S_dev_det,
+ S_file,
+ S_file2,
+ S_fileEEP,
+ S_noDLL,
+ S_openEEfile,
+ S_saveEEfile,
+ S_IhexShort,
+ S_IhexChecksum,
+ S_InvHandle,
+ S_LogFile,
+ S_FileSaved,
+ S_HVICSP,
+ S_StartRead,
+ S_Read,
+ S_CodeReading1,
+ S_CodeReading,
+ S_CodeReading2,
+ S_ReadEnd,
+ S_ReadID_CONFIG,
+ S_Read_CONFIG_A,
+ S_Read_EXE_A,
+ S_ReadEE,
+ S_StartErase,
+ S_Writing,
+ S_StartCodeProg,
+ S_CodeWriting,
+ S_CodeWriting2,
+ S_IDW,
+ S_ConfigW,
+ S_ConfigAreaW,
+ S_EEAreaW,
+ S_FuseAreaW,
+ S_CodeV,
+ S_CodeV2,
+ S_IDV,
+ S_ConfigV,
+ S_EEV,
+ S_IntW,
+ S_TotErr,
+ S_ComplErr,
+ S_Compl,
+ S_Ready,
+ S_End,
+ S_EndErr,
+ S_ProtErase,
+ S_Inohex,
+ S_ReadErr,
+ S_ReadCodeErr,
+ S_ReadCodeErr2,
+ S_ReadEEErr,
+ S_ConfigErr,
+ S_ReadConfigErr,
+ S_ErrOsccal,
+ S_CodeWError,
+ S_CodeWError2,
+ S_CodeWError3,
+ S_CodeWError4,
+ S_ConfigWErr,
+ S_ConfigWErr2,
+ S_ConfigWErr3,
+ S_WErr1,
+ S_WErr2,
+ S_IDErr,
+ S_ICDErr,
+ S_Calib1Err,
+ S_Calib2Err,
+ S_CodeVError,
+ S_CodeVError2,
+ S_CodeVError3,
+ S_ErrSing,
+ S_ErrPlur,
+ S_MaxErr,
+ S_I2CInitErr,
+ S_I2CAckErr,
+ S_ComErr,
+ S_InsErr,
+ S_SyncErr,
+ S_HVregErr,
+ S_Log1,
+ S_Log2,
+ S_Log3,
+ S_Log4,
+ S_Log5,
+ S_Log6,
+ S_Log7,
+ S_Log8,
+ S_Log9,
+ S_comTimeout,
+ S_EraseTimeout,
+ S_ConfigTimeout,
+ S_ConfigTimeout2,
+ S_CodeTimeout,
+ S_CodeTimeout2,
+ S_OsccalTimeout,
+ S_EETimeout,
+ S_ConfigWTimeout,
+ S_CodeWTimeout,
+ S_ConfigWTimeout2,
+ S_EEWTimeout,
+ S_IDWTimeout,
+ S_ConfigNWTimeout,
+ S_CodeVTimeout,
+ S_ConfigVTimeout,
+ S_ProgModeTimeout,
+ S_ProgModeXTimeout,
+ S_LogTimeout,
+ S_CodeMem,
+ S_EEMem,
+ S_IDMem,
+ S_ConfigMem,
+ S_ConfigResMem,
+ S_CodeMem2,
+ S_ExeMem,
+ S_LPOsc,
+ S_XTOsc,
+ S_IntOsc,
+ S_RCOsc,
+ S_WDTON,
+ S_WDTOFF,
+ S_CPOFF,
+ S_CPON,
+ S_MCLRON,
+ S_MCLROFF,
+ S_ChipID,
+ S_ChipID2,
+ S_BKOsccal,
+ S_Osccal,
+ S_DevID,
+ S_DevID2,
+ S_DevREV,
+ S_ConfigWord,
+ S_ConfigWord2,
+ S_ConfigWordX,
+ S_Config2Cal1,
+ S_ConfigWordH,
+ S_ConfigWordL,
+ S_CalibWord1,
+ S_Calib1_2,
+ S_CalibWord2,
+ S_CalibWordX,
+ S_Protected,
+ S_CodeLim,
+ S_EELim,
+ S_ConfigLim,
+ S_WbufLim,
+ S_MaxRetry,
+ S_NoCode,
+ S_NoCode2,
+ S_NoCalibW,
+ S_NoEEMem,
+ S_NoConfigW,
+ S_NoConfigW2,
+ S_NoConfigW3,
+ S_NoConfigW4,
+ S_NoConfigW5,
+ S_NoConfigW6,
+ S_Empty,
+ S_NextIns,
+ S_ForceConfigW,
+ S_ForceConfigWx,
+ S_WaitS1W,
+ S_WaitS1R,
+ S_WarnFlashSize,
+// GUI strings
+ I_CANCEL,
+ I_OPEN,
+ I_SAVE,
+ I_Fopen,
+ I_Fsave,
+ I_DevR,
+ I_DevW,
+ I_Info,
+ I_Data,
+ I_Opt,
+ I_Dev,
+ I_Type,
+ I_Speed,
+ I_ReadRes,
+ I_ID_BKo_W,
+ I_EE,
+ I_CalW,
+ I_OSCW,
+ I_OSC,
+ I_BKOSC,
+ I_OSCF,
+ I_CONN,
+ I_QUIT,
+ I_LOG,
+ I_CK_V33,
+ I_LANG,
+ I_MAXERR,
+ I_ADDR,
+ I_USBD,
+ I_I2CDATAOUT,
+ I_I2CDATATR,
+ I_I2C_NB,
+ I_I2CMode,
+ I_I2CSend,
+ I_I2CReceive,
+ I_TestHW,
+ I_TestHWB,
+ I_TestMSG,
+ I_IO_Enable,
+ I_IO_Commands,
+ I_SPIMEM,
+ I_I2CMEM,
+ I_UWMEM,
+ I_OWMEM,
+ I_OWDEV,
+ I_UNIOMEM,
+ I_3V3REQUIRED,
+ I_PIC_FORCECW,
+ I_AT_FUSE,
+ I_AT_FUSEH,
+ I_AT_FUSEX,
+ I_AT_LOCK,
+ I_AT_FUSELF,
+ I_AT_COMM,
+ I_W_LANGFILE,
+ I_WAITS1,
+ I_PRESSS1,
+ I_ICD_ENABLE,
+ I_ICD_ADDRESS,
+ I_LOAD_COFF,
+ I_SHOW_PC,
+ I_SHOW_STATUS,
+ I_SHOW_BANK0,
+ I_SHOW_BANK1,
+ I_SHOW_BANK2,
+ I_SHOW_BANK3,
+ I_SHOW_EE,
+ I_STOP,
+ I_ICD_RUN,
+ I_ICD_HALT,
+ I_ICD_STEP,
+ I_ICD_STEPOVER,
+ I_ICD_STOP,
+ I_ICD_REFRESH,
+ I_ICD_CMD,
+ I_ICD_HELP,
+ I_ICD_SOURCE,
+ I_ICD_STATUS,
+ I_ICD_HELP_TXT,
+ I_GUI_CMD_HELP,
+// command-line strings
+ L_HELP,
+ L_OPTERR,
+ L_INFO1,
+ L_INFO2,
+ L_UNKNOWN,
+ L_NAME,
+ L_DEV_RO,
+ L_DEV_RW,
+ DIM};
+
+extern char *strings_it[DIM];
+extern char *strings_en[DIM];
+extern char *STR_ID[DIM];
+void strinit();
+int strfind(const char* langid,const char* langfile);
+void GenerateLangFile(const char* langid,const char* langfile);
diff --git a/style.css b/style.css
new file mode 100644
index 0000000..1e3edad
--- /dev/null
+++ b/style.css
@@ -0,0 +1,3 @@
+.mono {
+ font: 14px monospace;
+} \ No newline at end of file
diff --git a/sys.png b/sys.png
new file mode 100644
index 0000000..b518787
--- /dev/null
+++ b/sys.png
Binary files differ
diff --git a/write.png b/write.png
new file mode 100644
index 0000000..6ed5776
--- /dev/null
+++ b/write.png
Binary files differ