summaryrefslogtreecommitdiffstats
path: root/progP18.c
diff options
context:
space:
mode:
Diffstat (limited to 'progP18.c')
-rw-r--r--progP18.c626
1 files changed, 444 insertions, 182 deletions
diff --git a/progP18.c b/progP18.c
index de77e99..90d2d62 100644
--- a/progP18.c
+++ b/progP18.c
@@ -1,6 +1,6 @@
/**
* \file progP18F.c - algorithms to program the PIC18 family of microcontrollers
- * Copyright (C) 2009-2023 Alberto Maccioni
+ * Copyright (C) 2009-2025 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
@@ -260,6 +260,20 @@ struct ID18{
{0x6220,"18LF65K80 rev%d\r\n",0x1F},
{0x6240,"18LF45K80 rev%d\r\n",0x1F},
{0x6260,"18LF25K80 rev%d\r\n",0x1F},
+ {0x6900,"18F47K40 rev%c%d\r\n",0xFFFF},
+ {0x6920,"18F46K40 rev%c%d\r\n",0xFFFF},
+ {0x6940,"18F45K40 rev%c%d\r\n",0xFFFF},
+ {0x6960,"18F27K40 rev%c%d\r\n",0xFFFF},
+ {0x6980,"18F26K40 rev%c%d\r\n",0xFFFF},
+ {0x69A0,"18F25K40 rev%c%d\r\n",0xFFFF},
+ {0x69C0,"18F24K40 rev%c%d\r\n",0xFFFF},
+ {0x69E0,"18LF47K40 rev%c%d\r\n",0xFFFF},
+ {0x6A00,"18LF46K40 rev%c%d\r\n",0xFFFF},
+ {0x6A20,"18LF45K40 rev%c%d\r\n",0xFFFF},
+ {0x6A40,"18LF27K40 rev%c%d\r\n",0xFFFF},
+ {0x6A60,"18LF26K40 rev%c%d\r\n",0xFFFF},
+ {0x6A80,"18LF25K40 rev%c%d\r\n",0xFFFF},
+ {0x6AA0,"18LF24K40 rev%c%d\r\n",0xFFFF},
{0x6B80,"18F57K42 rev%c%d\r\n",0xFFFF},
{0x6BA0,"18F56K42 rev%c%d\r\n",0xFFFF},
{0x6BC0,"18F55K42 rev%c%d\r\n",0xFFFF},
@@ -268,6 +282,8 @@ struct ID18{
{0x6C20,"18F45K42 rev%c%d\r\n",0xFFFF},
{0x6C40,"18F27K42 rev%c%d\r\n",0xFFFF},
{0x6C60,"18F26K42 rev%c%d\r\n",0xFFFF},
+ {0x6C80,"18F25K42 rev%c%d\r\n",0xFFFF},
+ {0x6CA0,"18F24K42 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},
@@ -276,10 +292,19 @@ struct ID18{
{0x6D60,"18LF45K42 rev%c%d\r\n",0xFFFF},
{0x6D80,"18LF27K42 rev%c%d\r\n",0xFFFF},
{0x6DA0,"18LF26K42 rev%c%d\r\n",0xFFFF},
+ {0x6DC0,"18LF25K42 rev%c%d\r\n",0xFFFF},
+ {0x6DE0,"18LF24K42 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},
+ {0x70E0,"18F47Q10 rev%c%d\r\n",0xFFFF},
+ {0x7100,"18F27Q10 rev%c%d\r\n",0xFFFF},
+ {0x7120,"18F46Q10 rev%c%d\r\n",0xFFFF},
+ {0x7140,"18F45Q10 rev%c%d\r\n",0xFFFF},
+ {0x7180,"18F26Q10 rev%c%d\r\n",0xFFFF},
+ {0x71A0,"18F25Q10 rev%c%d\r\n",0xFFFF},
+ {0x71C0,"18F24Q10 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},
@@ -310,6 +335,12 @@ struct ID18{
{0x77E0,"18F45Q71 rev%c%d\r\n",0xFFFF},
{0x7820,"18F54Q71 rev%c%d\r\n",0xFFFF},
{0x7860,"18F55Q71 rev%c%d\r\n",0xFFFF},
+ {0x7A40,"18F16Q20 rev%c%d\r\n",0xFFFF},
+ {0x7A60,"18F06Q20 rev%c%d\r\n",0xFFFF},
+ {0x7A80,"18F15Q20 rev%c%d\r\n",0xFFFF},
+ {0x7AA0,"18F05Q20 rev%c%d\r\n",0xFFFF},
+ {0x7AC0,"18F14Q20 rev%c%d\r\n",0xFFFF},
+ {0x7AE0,"18F04Q20 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},
@@ -1620,24 +1651,30 @@ void Write18Fx(int dim,int dim2,int wbuf,int eraseW1,int eraseW2,int options)
#define PROGRAM_DATA 0xC0
#define PROGRAM_DATA_INC 0xE0
#define END_EXT_PROG 0x82
+#define PROGRAM_ACCESS_EN 0x4C
void Read18FKx(int dim,int dim2,int options)
-// read 16 bit PIC 18FxxKx3 with new 8b commands
+// read 16 bit PIC 18FxxKx with new 8b commands
// dim=program size (bytes)
-// dim2=if>0 use eeprom, size is automatic when reading DCI
+// dim2=if>0 use eeprom, size is automatic when reading DCI; otherwise dim2=ee size (bytes)
// 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
+// code config EE DCI DIA model
+// 0 5 (W) 0x310000 0x3FFF00 0x3F0000 K42 K83
+// 1 10 (B) 0x380000 0x3C0000 0x2C0000 Q40-43
+// 2 35 (B) 0x380000 0x3C0000 0x2C0000 Q83-84
+// 3 6 (W) 0x310000 no no K40
+// 4 6 (W) 0x310000 no no Q10
+// 5 14 (B) 0x380000 0x3C0000 0x2C0000 Q20
+//config length refers to number of read commands required; some types
+//respond with 1 byte, some with 2 bytes.
{
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 EEaddr=0,DCIaddr=0,DIAaddr=0,DIAlen=0,UIDlen=0,CONFIGlen=0,CONFIGorg=0;
int type=(options>>4)&0xF;
if(type==0){ //K42 K83
EEaddr=0x310000;
@@ -1646,6 +1683,7 @@ void Read18FKx(int dim,int dim2,int options)
DIAlen=0x40;
UIDlen=0x10;
CONFIGlen=5;
+ CONFIGorg=0; //word organization
}
else if(type==1){ //Q43
EEaddr=0x380000;
@@ -1654,6 +1692,7 @@ void Read18FKx(int dim,int dim2,int options)
DIAlen=0x100;
UIDlen=0x40;
CONFIGlen=10;
+ CONFIGorg=1; //byte organization
}
else if(type==2){ //Q83-84
EEaddr=0x380000;
@@ -1662,6 +1701,34 @@ void Read18FKx(int dim,int dim2,int options)
DIAlen=0x100;
UIDlen=0x40;
CONFIGlen=35;
+ CONFIGorg=1; //byte organization
+ }
+ else if(type==3){ //K40
+ EEaddr=0x310000;
+ DCIaddr=0;
+ DIAaddr=0;
+ DIAlen=0;
+ UIDlen=8;
+ CONFIGlen=6;
+ CONFIGorg=0; //word organization
+ }
+ else if(type==4){ //Q10
+ EEaddr=0x310000;
+ DCIaddr=0;
+ DIAaddr=0;
+ DIAlen=0;
+ UIDlen=0x100;
+ CONFIGlen=6;
+ CONFIGorg=0; //word organization ***only for read! write is different from K40
+ }
+ else if(type==5){ //Q20
+ EEaddr=0x380000;
+ DCIaddr=0x3C0000;
+ DIAaddr=0x2C0000;
+ DIAlen=0x100;
+ UIDlen=0x40;
+ CONFIGlen=26; // 0xB to 0x17 are reserved
+ CONFIGorg=1; //byte organization
}
else PrintMessage("unexpected parameter");
if(dim>0x1FFFFF||dim<0){
@@ -1689,8 +1756,8 @@ void Read18FKx(int dim,int dim2,int options)
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<sizeof(memID);j++) memID[j]=0xFF;
+ for(j=0;j<48;j++) memCONFIG[j]=0xFF;
for(j=0;j<DIAlen;j++) memDIA[j]=0xFF;
unsigned int start=GetTickCount();
j=0;
@@ -1722,23 +1789,25 @@ void Read18FKx(int dim,int dim2,int options)
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;
+ if(DCIaddr>0){
+ 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;
@@ -1759,30 +1828,34 @@ void Read18FKx(int dim,int dim2,int options)
PrintMessage1("DevID: 0x%04X\r\n",devID);
PrintMessage1("RevID: 0x%04X\r\n",devREV);
if(!PIC18_ID(devID+(devREV<<16))) return;
- 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]);
+ if(DCIaddr>0){
+ 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]);
+ }
}
+ else sizeEE=dim2;
//****************** read code ********************
PrintMessage(strings[S_CodeReading1]); //read code ...
+ if(saveLog) fprintf(logfile,strings[S_sepLine]);
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
@@ -1814,6 +1887,7 @@ void Read18FKx(int dim,int dim2,int options)
else PrintMessage(strings[S_Compl]);
//****************** read config area ********************
PrintMessage(strings[S_Read_CONFIG_A]); //read config ...
+ if(saveLog) fprintf(logfile,strings[S_sepLine]);
if(saveLog) fprintf(logfile,"%s\n",strings[S_Read_CONFIG_A]); //read config ...
MemAddr=0x300000<<1; //config area
bufferU[j++]=TX16;
@@ -1833,7 +1907,7 @@ void Read18FKx(int dim,int dim2,int options)
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
+ if(CONFIGorg==0) memCONFIG[k2++]=bufferI[z+1]; //MSB if organized as words
z+=2;
}
}
@@ -1844,12 +1918,14 @@ void Read18FKx(int dim,int dim2,int options)
}
}
}
- if(k2!=10){
+ if(CONFIGorg==0) CONFIGlen*=2; //adjust expected size
+ if(k2!=CONFIGlen){
PrintMessage("\r\n");
- PrintMessage2(strings[S_ReadConfigErr],10,k2); //"Error reading config area, requested %d bytes, read %d\r\n"
+ PrintMessage2(strings[S_ReadConfigErr],CONFIGlen,k2); //"Error reading config area, requested %d bytes, read %d\r\n"
}
else PrintMessage(strings[S_Compl]);
//****************** read user ID ********************
+ if(saveLog) fprintf(logfile,strings[S_sepLine]);
if(saveLog) fprintf(logfile,"Read user ID\n");
MemAddr=0x200000<<1; //user ID
bufferU[j++]=TX16;
@@ -1885,39 +1961,42 @@ void Read18FKx(int dim,int dim2,int options)
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;
+ if(DIAaddr>0){
+ if(saveLog) fprintf(logfile,strings[S_sepLine]);
+ 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"
}
- }
- 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"
+ 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
@@ -1929,6 +2008,7 @@ void Read18FKx(int dim,int dim2,int options)
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,strings[S_sepLine]);
if(saveLog) fprintf(logfile,"%s\n",strings[S_ReadEE]); //Read EEPROM ...
MemAddr=EEaddr<<1; //EE base address
bufferU[j++]=TX16;
@@ -1981,14 +2061,17 @@ void Read18FKx(int dim,int dim2,int options)
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++){
+ if(CONFIGorg==0){ //word organization K42 K83 etc.
+ for(i=0;i<CONFIGlen;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]);
+ else{ //byte organization Q43 Q8X etc.
+ for(i=0;i<CONFIGlen;i++){
+ if(type==5&&(i>=0xB&&i<=0x17)); //reserved area for Q20
+ else PrintMessage2("CONFIG%d: 0x%02X\r\n",i+1,memCONFIG[i]); //Naming is not the same as datasheet
+ }
}
PrintMessage(strings[S_CodeMem]); //"\r\nCode memory:\r\n"
DisplayCODE18F(dim);
@@ -2004,22 +2087,26 @@ void Read18FKx(int dim,int dim2,int options)
}
void Write18FKx(int dim,int dim2,int options,int nu1,int nu2, int nu3)
-// write 16 bit PIC 18FxxKx3 with new 8b commands
+// write 16 bit PIC 18FxxKx 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
+// code config EE DCI DIA model program cycle delays ms (E,W,EE)
+// 0 5 (W) 0x310000 0x3FFF00 0x3F0000 K42 K83 multiple-word 25.5 2.8 5.6
+// 1 10 (B) 0x380000 0x3C0000 0x2C0000 Q40-43 one-word 11 0.075 11
+// 2 35 (B) 0x380000 0x3C0000 0x2C0000 Q83-84 one-word 11 0.075 11
+// 3 6 (W) 0x310000 no no K40 multiple-word 25.5 2.8 5.6
+// 4 6 (W) 0x310000 no no Q10 one-word 75 0.065 11
+// 5 11+2 (B) 0x380000 0x3C0000 0x2C0000 Q20 one-word 11 0.075 11 SAFLOCK bit
{
int k=0,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 EEaddr=0,DCIaddr=0,DIAaddr=0,DIAlen=0,UIDlen=0,CONFIGlen=0,CONFIGorg=0;
+ int delayErase=0,delayWrite=0,delayWriteConfig=0;
int type=(options>>4)&0xF;
if(type==0){ //K42 K83
EEaddr=0x310000;
@@ -2028,6 +2115,10 @@ void Write18FKx(int dim,int dim2,int options,int nu1,int nu2, int nu3)
DIAlen=0x40;
UIDlen=0x10;
CONFIGlen=5;
+ CONFIGorg=0; //word organization
+ delayErase=25500; //in us
+ delayWrite=2800; //in us
+ delayWriteConfig=5600; //in us
}
else if(type==1){ //Q43
EEaddr=0x380000;
@@ -2036,6 +2127,9 @@ void Write18FKx(int dim,int dim2,int options,int nu1,int nu2, int nu3)
DIAlen=0x100;
UIDlen=0x40;
CONFIGlen=10;
+ CONFIGorg=1; //byte organization
+ delayErase=11500; //in us
+ delayWriteConfig=11000; //in us
}
else if(type==2){ //Q83-84
EEaddr=0x380000;
@@ -2044,6 +2138,45 @@ void Write18FKx(int dim,int dim2,int options,int nu1,int nu2, int nu3)
DIAlen=0x100;
UIDlen=0x40;
CONFIGlen=35;
+ CONFIGorg=1; //byte organization
+ delayErase=11500; //in us
+ delayWriteConfig=11000; //in us
+ }
+ else if(type==3){ //K40
+ EEaddr=0x310000;
+ DCIaddr=0;
+ DIAaddr=0;
+ DIAlen=0;
+ UIDlen=8;
+ CONFIGlen=6;
+ CONFIGorg=0; //word organization
+ rowN=32; //max 64 in 27K40 but can be 32
+ delayErase=25500; //in us
+ delayWrite=2800; //in us
+ delayWriteConfig=5600; //in us
+ }
+ else if(type==4){ //Q10
+ EEaddr=0x310000;
+ DCIaddr=0;
+ DIAaddr=0;
+ DIAlen=0;
+ UIDlen=0x100;
+ CONFIGlen=6;
+ CONFIGorg=2; //word organization
+ delayErase=75500; //in us
+ delayWrite=11000; //in us (because it is used for SET_T3 during erase like Kxx devices)
+ delayWriteConfig=11000; //in us
+ }
+ else if(type==5){ //Q20 (SAFLOCK)
+ EEaddr=0x380000;
+ DCIaddr=0x3C0000;
+ DIAaddr=0x2C0000;
+ DIAlen=0x100;
+ UIDlen=0x40;
+ CONFIGlen=11; // 0xB to 0x17 are reserved, then 0x19 and 0x18 (SAFLOCK)
+ CONFIGorg=1; //byte organization
+ delayErase=11500; //in us
+ delayWriteConfig=11000; //in us
}
else PrintMessage("unexpected parameter");
if(dim>0x1FFFFF||dim<0){
@@ -2095,18 +2228,7 @@ void Write18FKx(int dim,int dim2,int options,int nu1,int nu2, int nu3)
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++]=LOAD_PC_ADDR;
bufferU[j++]=MemAddr>>16;
bufferU[j++]=(MemAddr>>8)&0xFF;
bufferU[j++]=MemAddr&0xFF;
@@ -2114,15 +2236,28 @@ void Write18FKx(int dim,int dim2,int options,int nu1,int nu2, int nu3)
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;
+ if(DCIaddr>0){
+ MemAddr=DCIaddr<<1; //DCI
+ bufferU[j++]=TX16;
+ bufferU[j++]=2;
+ bufferU[j++]=LOAD_PC_ADDR;
+ 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++]=LOAD_PC_ADDR;
bufferU[j++]=0x0;
bufferU[j++]=0x0;
bufferU[j++]=0x0;
@@ -2140,41 +2275,48 @@ void Write18FKx(int dim,int dim2,int options,int nu1,int nu2, int nu3)
PrintMessage1("DevID: 0x%04X\r\n",devID);
PrintMessage1("RevID: 0x%04X\r\n",devREV);
if(!PIC18_ID(devID+(devREV<<16))) return;
- 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]);
+ if(DCIaddr>0){
+ 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
+ if(saveLog){
+ fprintf(logfile,strings[S_sepLine]);
+ fprintf(logfile,strings[S_StartErase]);
+ fprintf(logfile,strings[S_NL]);
+ }
+ if(type==0||type==3||type==4){ //K42 K83 K40 Q10
bufferU[j++]=SET_PARAMETER;
bufferU[j++]=SET_T3;
- bufferU[j++]=25500>>8;
- bufferU[j++]=25500&0xff;
+ bufferU[j++]=delayErase>>8;
+ bufferU[j++]=delayErase&0xff;
MemAddr=0x300000<<1; //address to erase Flash+User+Config
bufferU[j++]=TX16;
bufferU[j++]=2;
- bufferU[j++]=0x80;
+ bufferU[j++]=LOAD_PC_ADDR;
bufferU[j++]=MemAddr>>16;
bufferU[j++]=(MemAddr>>8)&0xFF;
bufferU[j++]=MemAddr&0xFF;
@@ -2184,7 +2326,7 @@ void Write18FKx(int dim,int dim2,int options,int nu1,int nu2, int nu3)
MemAddr=0x310000<<1; //address to erase EEPROM
bufferU[j++]=TX16;
bufferU[j++]=2;
- bufferU[j++]=0x80;
+ bufferU[j++]=LOAD_PC_ADDR;
bufferU[j++]=MemAddr>>16;
bufferU[j++]=(MemAddr>>8)&0xFF;
bufferU[j++]=MemAddr&0xFF;
@@ -2193,34 +2335,39 @@ void Write18FKx(int dim,int dim2,int options,int nu1,int nu2, int nu3)
bufferU[j++]=WAIT_T3; //TERAB
bufferU[j++]=SET_PARAMETER;
bufferU[j++]=SET_T3;
- bufferU[j++]=2800>>8;
- bufferU[j++]=2800&0xff;
+ bufferU[j++]=delayWrite>>8;
+ bufferU[j++]=delayWrite&0xff;
bufferU[j++]=FLUSH;
for(;j<DIMBUF;j++) bufferU[j]=0x0;
- PacketIO(52);
+ PacketIO(delayErase/1000*2);
}
- else if(type==1){ //Q43
+ else if(type==1||type==2||type==5){ //Q4x-Q8x-Q20
bufferU[j++]=ICSP8_LOAD;
bufferU[j++]=BULK_ERASE;
bufferU[j++]=0;
bufferU[j++]=0xF;
+ bufferU[j++]=SET_PARAMETER;
+ bufferU[j++]=SET_T3;
+ bufferU[j++]=delayWriteConfig>>8;
+ bufferU[j++]=delayWriteConfig&0xff;
bufferU[j++]=FLUSH;
for(;j<DIMBUF;j++) bufferU[j]=0x0;
PacketIO(1);
- msDelay(12); //bulk erase delay
+ msDelay(delayErase/1000); //bulk erase delay
}
PrintMessage(strings[S_Compl]); //"completed\r\n"
//****************** write code ********************
PrintMessage(strings[S_StartCodeProg]); //"code write ... "
PrintStatusSetup();
if(saveLog){
+ fprintf(logfile,strings[S_sepLine]);
fprintf(logfile,"WRITE CODE\ndim=%d(0x%X)\n",dim,dim); //
}
- if(type==1){ //Q43
+ if(type==1||type==2||type==4||type==5){ //Q4x-Q8x Q43 Q10 Q20 one word algorithm
j=0;
bufferU[j++]=TX16;
bufferU[j++]=2;
- bufferU[j++]=0x80;
+ bufferU[j++]=LOAD_PC_ADDR;
bufferU[j++]=0x0;
bufferU[j++]=0x0;
bufferU[j++]=0x0;
@@ -2245,7 +2392,7 @@ void Write18FKx(int dim,int dim2,int options,int nu1,int nu2, int nu3)
MemAddr=i<<1;
bufferU[j++]=TX16;
bufferU[j++]=2;
- bufferU[j++]=0x80;
+ bufferU[j++]=LOAD_PC_ADDR;
bufferU[j++]=MemAddr>>16;
bufferU[j++]=(MemAddr>>8)&0xFF;
bufferU[j++]=MemAddr&0xFF;
@@ -2289,7 +2436,7 @@ void Write18FKx(int dim,int dim2,int options,int nu1,int nu2, int nu3)
}
err+=i-k;
}
- else if(type==0){ //K42 K83
+ else if(type==0||type==3){ //K42 K83 K40 multiple word algorithm
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
@@ -2310,7 +2457,7 @@ void Write18FKx(int dim,int dim2,int options,int nu1,int nu2, int nu3)
MemAddr=i<<1;
bufferU[j++]=TX16; //load new address
bufferU[j++]=2;
- bufferU[j++]=0x80;
+ bufferU[j++]=LOAD_PC_ADDR;
bufferU[j++]=MemAddr>>16;
bufferU[j++]=(MemAddr>>8)&0xFF;
bufferU[j++]=MemAddr&0xFF;
@@ -2345,11 +2492,14 @@ void Write18FKx(int dim,int dim2,int options,int nu1,int nu2, int nu3)
//****************** verify code ********************
PrintMessage(strings[S_CodeV]); //"Verifying code ... "
PrintStatusSetup();
- if(saveLog) fprintf(logfile,"%s\n",strings[S_CodeV]);
+ if(saveLog){
+ fprintf(logfile,strings[S_sepLine]);
+ fprintf(logfile,"%s\n",strings[S_CodeV]);
+ }
j=0;
bufferU[j++]=TX16;
bufferU[j++]=2;
- bufferU[j++]=0x80;
+ bufferU[j++]=LOAD_PC_ADDR;
bufferU[j++]=0x0;
bufferU[j++]=0x0;
bufferU[j++]=0x0;
@@ -2366,7 +2516,7 @@ void Write18FKx(int dim,int dim2,int options,int nu1,int nu2, int nu3)
MemAddr=i<<1;
bufferU[j++]=TX16;
bufferU[j++]=2;
- bufferU[j++]=0x80;
+ bufferU[j++]=LOAD_PC_ADDR;
bufferU[j++]=MemAddr>>16;
bufferU[j++]=(MemAddr>>8)&0xFF;
bufferU[j++]=MemAddr&0xFF;
@@ -2401,8 +2551,8 @@ void Write18FKx(int dim,int dim2,int options,int nu1,int nu2, int nu3)
}
bufferU[j++]=SET_PARAMETER;
bufferU[j++]=SET_T3;
- bufferU[j++]=5600>>8;
- bufferU[j++]=5600&0xff;
+ bufferU[j++]=delayWriteConfig>>8;
+ bufferU[j++]=delayWriteConfig&0xff;
bufferU[j++]=FLUSH;
for(;j<DIMBUF;j++) bufferU[j]=0x0;
PacketIO(1);
@@ -2414,25 +2564,28 @@ void Write18FKx(int dim,int dim2,int options,int nu1,int nu2, int nu3)
if(dim2){
PrintMessage(strings[S_EEAreaW]); //"Write EEPROM ... "
PrintStatusSetup();
- if(saveLog) fprintf(logfile,"WRITE EEPROM\ndim2=%d(0x%X)\n",dim2,dim2);
+ if(saveLog){
+ fprintf(logfile,strings[S_sepLine]);
+ 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++]=LOAD_PC_ADDR;
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
+ if(type==1||type==2||type==4||type==5){ //Q4x-Q8x Q10 Q20
bufferU[j++]=ICSP8_LOAD;
bufferU[j++]=PROGRAM_DATA;
bufferU[j++]=0;
bufferU[j++]=memEE[i];
}
- else if(type==0){ //K42 K83
+ else if(type==0||type==3){ //K42 K83 K40
bufferU[j++]=ICSP8_LOAD;
bufferU[j++]=LOAD_NVM;
bufferU[j++]=0; //High byte
@@ -2453,12 +2606,12 @@ void Write18FKx(int dim,int dim2,int options,int nu1,int nu2, int nu3)
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
+ w=(float)w*(delayWriteConfig/1000.0);//(type==1||type==2)?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];
+ w=(type==1||type==2||type==4||type==5)?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"
@@ -2471,7 +2624,7 @@ void Write18FKx(int dim,int dim2,int options,int nu1,int nu2, int nu3)
}
}
k++;
- z+=type==1?4:5;
+ z+=(type==1||type==2||type==4||type==5)?4:5;
}
}
j=0;
@@ -2490,25 +2643,28 @@ void Write18FKx(int dim,int dim2,int options,int nu1,int nu2, int nu3)
#define IDaddr 0x200000
if(programID){
PrintMessage(strings[S_IDW]); //"Write ID ... "
- if(saveLog) fprintf(logfile,"Write ID\n");
+ if(saveLog){
+ fprintf(logfile,strings[S_sepLine]);
+ fprintf(logfile,"Write ID\n");
+ }
int errID=0;
j=0;
MemAddr=IDaddr<<1;
bufferU[j++]=TX16;
bufferU[j++]=2;
- bufferU[j++]=0x80;
+ bufferU[j++]=LOAD_PC_ADDR;
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
+ if(type==1||type==2||type==4||type==5){ //Q4x-Q8x Q10 Q20
bufferU[j++]=ICSP8_LOAD;
bufferU[j++]=PROGRAM_DATA;
bufferU[j++]=memID[i+1];
bufferU[j++]=memID[i];
}
- else if(type==0){ //K42 K83
+ else if(type==0||type==3){ //K42 K83 K40
bufferU[j++]=ICSP8_LOAD;
bufferU[j++]=LOAD_NVM;
bufferU[j++]=memID[i+1];
@@ -2528,12 +2684,12 @@ void Write18FKx(int dim,int dim2,int options,int nu1,int nu2, int nu3)
PrintStatus(strings[S_CodeWriting],99,IDaddr+i); //"Writing: %d%%, add. %03X"
bufferU[j++]=FLUSH;
for(;j<DIMBUF;j++) bufferU[j]=0x0;
- PacketIO(80);
+ PacketIO(9*delayWriteConfig/1000+2); //at most 9 writes per IO packet
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];
+ if(type==1||type==2||type==4||type==5) w=(bufferI[z+3]<<8)+bufferI[z+4]; //Q4x-Q8x Q10 Q20
+ else if(type==0||type==3) w=(bufferI[z+4]<<8)+bufferI[z+5]; //K42 K83 K40
x=(memID[k+1]<<8)+memID[k];
if(x!=w){
PrintMessage("\r\n");
@@ -2547,7 +2703,7 @@ void Write18FKx(int dim,int dim2,int options,int nu1,int nu2, int nu3)
}
}
k+=2;
- z+=type==1?4:5;
+ z+=(type==1||type==2||type==4||type==5)?4:5;
}
}
j=0;
@@ -2565,24 +2721,21 @@ void Write18FKx(int dim,int dim2,int options,int nu1,int nu2, int nu3)
#define CONFIGaddr 0x300000
if(err<max_err){
PrintMessage(strings[S_ConfigW]); //"Write CONFIG ..."
- if(saveLog) fprintf(logfile,"Write CONFIG\n");
+ if(saveLog){
+ fprintf(logfile,strings[S_sepLine]);
+ fprintf(logfile,"Write CONFIG\n");
+ }
int errC=0;
j=0;
MemAddr=CONFIGaddr<<1;
bufferU[j++]=TX16;
bufferU[j++]=2;
- bufferU[j++]=0x80;
+ bufferU[j++]=LOAD_PC_ADDR;
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
+ if(CONFIGorg==0){ // word organization K42 K83 K40 etc
bufferU[j++]=ICSP8_LOAD;
bufferU[j++]=LOAD_NVM;
bufferU[j++]=memCONFIG[i*2+1]; //High byte
@@ -2590,6 +2743,18 @@ void Write18FKx(int dim,int dim2,int options,int nu1,int nu2, int nu3)
bufferU[j++]=ICSP8_SHORT;
bufferU[j++]=BEGIN_INT_PROG; //internally timed
}
+ else if(CONFIGorg==1){ //byte organization Q4x-Q8x Q43 etc
+ bufferU[j++]=ICSP8_LOAD;
+ bufferU[j++]=PROGRAM_DATA;
+ bufferU[j++]=0; //High byte=0
+ bufferU[j++]=memCONFIG[i]; //Low byte
+ }
+ else if(CONFIGorg==2){ //word organization Q10 etc
+ bufferU[j++]=ICSP8_LOAD;
+ bufferU[j++]=PROGRAM_DATA;
+ bufferU[j++]=memCONFIG[i*2+1]; //High byte
+ bufferU[j++]=memCONFIG[i*2]; //Low byte
+ }
bufferU[j++]=WAIT_T3; //Tprogram 11ms or 5.6ms
bufferU[j++]=ICSP8_READ;
bufferU[j++]=READ_NVM_INC;
@@ -2597,14 +2762,18 @@ void Write18FKx(int dim,int dim2,int options,int nu1,int nu2, int nu3)
PrintStatus(strings[S_CodeWriting],99,i+CONFIGaddr); //"Writing: %d%%, addr. %03X"
bufferU[j++]=FLUSH;
for(;j<DIMBUF;j++) bufferU[j]=0x0;
- PacketIO(80);
+ PacketIO(9*delayWriteConfig/1000.0+2); //at most 9 writes per IO packet
for(z=0;z<DIMBUF-4;z++){
if(bufferI[z]==ICSP8_LOAD){
- if(type==1){ //Q43 single byte
+ if(CONFIGorg==1){ //Q4x-Q8x Q43 single byte
w=bufferI[z+4];
x=memCONFIG[k];
}
- else if(type==0){ //K42 K83 2 bytes
+ else if(CONFIGorg==2){ //Q10 2 bytes
+ w=(bufferI[z+3]<<8)+bufferI[z+4];
+ x=(memCONFIG[k+1]<<8)+memCONFIG[k];
+ }
+ else if(CONFIGorg==0){ //K42 K83 K40 2 bytes
w=(bufferI[z+4]<<8)+bufferI[z+5];
x=(memCONFIG[k+1]<<8)+memCONFIG[k];
}
@@ -2619,11 +2788,15 @@ void Write18FKx(int dim,int dim2,int options,int nu1,int nu2, int nu3)
z=DIMBUF;
}
}
- if(type==1){ //Q43 single byte
+ if(CONFIGorg==1){ //Q4x-Q8x single byte
k++;
z+=4;
}
- else if(type==0){ //K42 K83 2 bytes
+ else if(CONFIGorg==2){ //Q10 2 bytes
+ k+=2;
+ z+=4;
+ }
+ else if(CONFIGorg==0){ //K42 K83 2 bytes
k+=2;
z+=5;
}
@@ -2635,8 +2808,97 @@ void Write18FKx(int dim,int dim2,int options,int nu1,int nu2, int nu3)
}
}
}
- errC+=10-k;
+ if(CONFIGorg==1) errC+=CONFIGlen-k; //byte
+ else errC+=CONFIGlen*2-k; //word
err+=errC;
+ if(useSAFLOCK_flag&&type==5&&memCONFIG[0x18]!=0xFF&&err>0) PrintMessage(strings[S_SkipSaflock]); //"skip SAFLOCK"
+ if(useSAFLOCK_flag&&type==5&&memCONFIG[0x18]!=0xFF&&err==0){ //Q20 with SAFLOCK
+ PrintMessage("\r\nWrite SAFLOCK");
+ if(saveLog){
+ fprintf(logfile,strings[S_sepLine]);
+ fprintf(logfile,"Write SAFLOCK\n");
+ }
+ errC=0;
+ if(memCONFIG[0x19]!=0xFF){ //SAFZ@0x300019
+ errC=1;
+ j=0;
+ MemAddr=0x300019<<1;
+ bufferU[j++]=TX16;
+ bufferU[j++]=2;
+ bufferU[j++]=LOAD_PC_ADDR;
+ bufferU[j++]=MemAddr>>16;
+ bufferU[j++]=(MemAddr>>8)&0xFF;
+ bufferU[j++]=MemAddr&0xFF;
+ bufferU[j++]=ICSP8_LOAD;
+ bufferU[j++]=PROGRAM_DATA;
+ bufferU[j++]=0; //High byte=0
+ bufferU[j++]=memCONFIG[0x19]; //Low byte
+ bufferU[j++]=WAIT_T3; //Tprogram 11ms or 5.6ms
+ bufferU[j++]=ICSP8_READ;
+ bufferU[j++]=READ_NVM_INC;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(delayWriteConfig/1000.0+2);
+ for(z=0;z<DIMBUF-4;z++){
+ if(bufferI[z]==ICSP8_LOAD){
+ w=bufferI[z+4];
+ x=memCONFIG[0x19];
+ if(~x&w){ //error if written 0 and read 1 (~Written&Read)
+ PrintMessage("\r\n");
+ PrintMessage3(strings[S_CodeWError2],0x300019,x,w); //"Error writing address %3X: written %04X, read %04X\r\n"
+ //stop even if SAFZ is not written correctly
+ PrintMessage(strings[S_IntW]); //"Write interrupted"
+ }
+ else errC=0;
+ z=DIMBUF*2; //only one to check
+ }
+ }
+ err+=errC;
+ }
+ if(errC>0) PrintMessage(strings[S_SkipSaflock]); //"skip SAFLOCK"
+ else{ //only if SAFZ was written and verified correctly
+ errC=1;
+ j=0;
+ MemAddr=0x300018<<1;
+ bufferU[j++]=TX16;
+ bufferU[j++]=2;
+ bufferU[j++]=LOAD_PC_ADDR;
+ bufferU[j++]=MemAddr>>16;
+ bufferU[j++]=(MemAddr>>8)&0xFF;
+ bufferU[j++]=MemAddr&0xFF;
+ //Program Access Enable
+ bufferU[j++]=TX16; //0100 1100 0 10 0111 1010 0001 1010 0101 1 = 4C + 0 + 27A1A5 + 1
+ bufferU[j++]=2; //2x16bit
+ bufferU[j++]=0x4C;
+ bufferU[j++]=0x4F;
+ bufferU[j++]=0x43;
+ bufferU[j++]=0x4B;
+ bufferU[j++]=ICSP8_LOAD;
+ bufferU[j++]=PROGRAM_DATA;
+ bufferU[j++]=0; //High byte=0
+ bufferU[j++]=memCONFIG[0x18]; //Low byte
+ bufferU[j++]=WAIT_T3; //Tprogram 11ms or 5.6ms
+ bufferU[j++]=ICSP8_READ;
+ bufferU[j++]=READ_NVM_INC;
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(delayWriteConfig/1000.0+2);
+ for(z=0;z<DIMBUF-4;z++){
+ if(bufferI[z]==ICSP8_READ){
+ w=bufferI[z+2];
+ x=memCONFIG[0x18];
+ if(~x&w){ //error if written 0 and read 1 (~Written&Read)
+ PrintMessage("\r\n");
+ PrintMessage3(strings[S_CodeWError2],0x300018,x,w); //"Error writing address %3X: written %04X, read %04X\r\n"
+ PrintMessage(strings[S_IntW]); //"Write interrupted"
+ }
+ else errC=0;
+ z=DIMBUF*2; //only one to check
+ }
+ }
+ err+=errC;
+ }
+ }
PrintStatusEnd();
PrintMessage1(strings[S_ComplErr],errC); //"completed, %d errors\r\n"
}