diff options
-rw-r--r-- | .gitignore | 3 | ||||
-rw-r--r-- | 24c02.hex | 18 | ||||
-rw-r--r-- | I2CSPI.c | 243 | ||||
-rw-r--r-- | I2CSPI.h | 2 | ||||
-rw-r--r-- | Makefile_op | 52 | ||||
-rw-r--r-- | Makefile_opgui | 67 | ||||
-rw-r--r-- | coff.c | 207 | ||||
-rw-r--r-- | coff.h | 208 | ||||
-rw-r--r-- | common.h | 5 | ||||
-rw-r--r-- | common_op.h | 114 | ||||
-rw-r--r-- | common_opgui.h | 117 | ||||
-rw-r--r-- | deviceRW.c | 1248 | ||||
-rw-r--r-- | deviceRW.h | 52 | ||||
-rw-r--r-- | fileIO.c | 835 | ||||
-rw-r--r-- | fileIO.h | 8 | ||||
-rw-r--r-- | gpl-2.0.txt | 339 | ||||
-rw-r--r-- | hid-example.c | 182 | ||||
-rw-r--r-- | hid_test.c | 575 | ||||
-rw-r--r-- | icd.c | 1541 | ||||
-rw-r--r-- | icd.h | 185 | ||||
-rw-r--r-- | icons.c | 546 | ||||
-rw-r--r-- | ihex.c | 15 | ||||
-rw-r--r-- | instructions.h | 99 | ||||
-rw-r--r-- | op.c | 1358 | ||||
-rw-r--r-- | opgui.c | 2503 | ||||
-rw-r--r-- | opgui.glade | 3797 | ||||
-rw-r--r-- | progAVR.c | 2450 | ||||
-rw-r--r-- | progAVR.h | 8 | ||||
-rw-r--r-- | progEEPROM.c | 2311 | ||||
-rw-r--r-- | progEEPROM.h | 12 | ||||
-rw-r--r-- | progP12.c | 666 | ||||
-rw-r--r-- | progP12.h | 3 | ||||
-rw-r--r-- | progP16.c | 6546 | ||||
-rw-r--r-- | progP16.h | 20 | ||||
-rw-r--r-- | progP18.c | 2662 | ||||
-rw-r--r-- | progP18.h | 6 | ||||
-rw-r--r-- | progP24.c | 3917 | ||||
-rw-r--r-- | progP24.h | 7 | ||||
-rw-r--r-- | progP32.c | 2454 | ||||
-rw-r--r-- | progP32.h | 4 | ||||
-rw-r--r-- | read.png | bin | 0 -> 1305 bytes | |||
-rw-r--r-- | read_eeprom.sh | 1 | ||||
-rw-r--r-- | readme | 98 | ||||
-rw-r--r-- | resources.xml | 10 | ||||
-rw-r--r-- | strings.c | 1070 | ||||
-rw-r--r-- | strings.h | 282 | ||||
-rw-r--r-- | style.css | 3 | ||||
-rw-r--r-- | sys.png | bin | 0 -> 312 bytes | |||
-rw-r--r-- | write.png | bin | 0 -> 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 @@ -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(§ions[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&§ions[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; +} @@ -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; +} @@ -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; +} + @@ -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); @@ -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"}; + + @@ -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 @@ -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 @@ -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 -> 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 -> 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 Binary files differnew file mode 100644 index 0000000..c00de0e --- /dev/null +++ b/read.png 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 @@ -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 Binary files differdiff --git a/write.png b/write.png Binary files differnew file mode 100644 index 0000000..6ed5776 --- /dev/null +++ b/write.png |