diff options
Diffstat (limited to 'progP18.c')
-rw-r--r-- | progP18.c | 626 |
1 files changed, 444 insertions, 182 deletions
@@ -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" } |