00001 /******************* 00002 * Function: icsp driver for pic18f87j10 00003 * icsp is brief of in-circuit serial programing 00004 * 00005 * 00006 * compiler: vc++ 6.0 00007 * author: book 00008 * date : 2009.07.13 00009 ******************** 00010 */ 00011 #include "includes.h" 00012 00013 //OutputPpt(U8); cost 1 us 00014 00015 #define IcspPgdLow() (IcspData=IcspData&0xfe) 00016 #define IcspPgdHigh() (IcspData=IcspData|0x01) 00017 #define IcspPgcLow() (IcspData=IcspData&0xfd) 00018 #define IcspPgcHigh() (IcspData=IcspData|0x02) 00019 #define IcspPgmLow() (IcspData=IcspData&0xfb) 00020 #define IcspPgmHigh() (IcspData=IcspData|0x04) 00021 #define IcspMclrLow() (IcspData=IcspData&0xf7) 00022 #define IcspMclrHigh() (IcspData=IcspData|0x08) 00023 00024 #define F_IcspMPgdIn() (InputPpt()&(0x40)) 00025 00026 U8 IcspData; 00027 U32 Signature; 00028 U8 IcspBuffer[64]; 00029 ICSP_CONTROL IcspCtrl; 00030 00031 void F_IcspInit(void){ 00032 IcspData=0; 00033 IcspMclrHigh(); 00034 IcspPgdLow(); 00035 IcspPgcLow(); 00036 IcspPgmLow(); 00037 OutputPpt(IcspData); 00038 OutputPpt(IcspData); 00039 OutputPpt(IcspData); 00040 } 00041 void F_IcspReset(void){ 00042 IcspData=0; 00043 IcspMclrHigh(); 00044 IcspPgdLow(); 00045 IcspPgcLow(); 00046 IcspPgmLow(); 00047 OutputPpt(IcspData); 00048 OutputPpt(IcspData); 00049 OutputPpt(IcspData); 00050 } 00051 void F_IcspPgdLow(void){ 00052 IcspPgdLow(); 00053 OutputPpt(IcspData); 00054 OutputPpt(IcspData); 00055 OutputPpt(IcspData); 00056 } 00057 void F_IcspPgdHigh(void){ 00058 IcspPgdHigh(); 00059 OutputPpt(IcspData); 00060 OutputPpt(IcspData); 00061 OutputPpt(IcspData); 00062 } 00063 void F_IcspPgcLow(void){ 00064 IcspPgcLow(); 00065 OutputPpt(IcspData); 00066 OutputPpt(IcspData); 00067 OutputPpt(IcspData); 00068 } 00069 void F_IcspPgcHigh(){ 00070 IcspPgcHigh(); 00071 OutputPpt(IcspData); 00072 OutputPpt(IcspData); 00073 OutputPpt(IcspData); 00074 } 00075 void F_IcspPgmLow(void){ 00076 IcspPgmLow(); 00077 OutputPpt(IcspData); 00078 OutputPpt(IcspData); 00079 OutputPpt(IcspData); 00080 } 00081 void F_IcspPgmHigh(void){ 00082 IcspPgmHigh(); 00083 OutputPpt(IcspData); 00084 OutputPpt(IcspData); 00085 OutputPpt(IcspData); 00086 } 00087 void F_IcspMclrLow(void){ 00088 IcspMclrLow(); 00089 OutputPpt(IcspData); 00090 OutputPpt(IcspData); 00091 OutputPpt(IcspData); 00092 } 00093 void F_IcspMclrHigh(void){ 00094 IcspMclrHigh(); 00095 OutputPpt(IcspData); 00096 OutputPpt(IcspData); 00097 OutputPpt(IcspData); 00098 } 00099 void F_IcspProgramModeEnter(void){ 00100 U8 i; 00101 00102 Signature=0xa12c2b2; // inverse bit order of signature 0x4d434850 ("MCHP") 00104 F_IcspMclrHigh(); 00105 F_IcspMclrLow(); 00106 OutputPpt(IcspData); 00107 Sleep(P19); // 1 ms 00108 for(i=0;i<32;i++){ // rising edge latch 00109 if(Signature&0x1){ 00110 F_IcspPgdHigh(); 00111 } 00112 else{ 00113 F_IcspPgdLow(); 00114 } 00115 Signature=Signature>>1; 00116 F_IcspPgcHigh(); // <10mhz 00117 F_IcspPgcLow(); // <10mhz 00118 } 00120 F_IcspMclrHigh(); 00121 Sleep(2); // 400 us 00122 } 00123 void F_IcspProgramModeExit(void){ 00124 00125 F_IcspMclrHigh(); 00126 F_IcspPgdLow(); 00127 F_IcspPgcLow(); 00128 //Sleep(P16); // 20 ns...no need 00129 F_IcspMclrLow(); 00130 F_IcspMclrLow(); 00131 F_IcspMclrLow(); 00132 F_IcspMclrLow(); 00133 F_IcspMclrLow(); 00134 F_IcspMclrLow(); 00135 F_IcspMclrLow(); 00136 F_IcspMclrLow(); 00137 F_IcspMclrLow(); 00138 F_IcspMclrLow(); 00139 } 00140 void F_IcspInstructionSend(U32 Instruction){ 00141 U8 i; 00142 00143 // falling edge trigger 00144 for(i=0;i<4;i++){ 00145 if(Instruction&0x1){ 00146 F_IcspPgdHigh(); 00147 } 00148 else{ 00149 F_IcspPgdLow(); 00150 } 00151 Instruction=Instruction>>1; 00152 F_IcspPgcHigh(); 00153 F_IcspPgcLow(); 00154 } 00155 //Sleep(P5); // 40 ns...no need 00156 for(i=0;i<16;i++){ 00157 if(Instruction&0x1){ 00158 F_IcspPgdHigh(); 00159 } 00160 else{ 00161 F_IcspPgdLow(); 00162 } 00163 Instruction=Instruction>>1; 00164 F_IcspPgcHigh(); 00165 F_IcspPgcLow(); 00166 } 00167 } 00168 void F_IcspBulkErase(void){ 00169 U32 i; 00170 U8 j; 00171 00172 i=ICSP_CORE_INSTRUCTION+0x0e3c*0x10; // movlw 3ch 00173 F_IcspInstructionSend(i); 00174 i=ICSP_CORE_INSTRUCTION+0x6ef8*0x10; // movwf tblptru 00175 F_IcspInstructionSend(i); 00176 i=ICSP_CORE_INSTRUCTION+0x0e00*0x10; // movlw 00h 00177 F_IcspInstructionSend(i); 00178 i=ICSP_CORE_INSTRUCTION+0x6ef7*0x10; // movwf tblptrh 00179 F_IcspInstructionSend(i); 00180 i=ICSP_CORE_INSTRUCTION+0x0e05*0x10; // movlw 05 00181 F_IcspInstructionSend(i); 00182 i=ICSP_CORE_INSTRUCTION+0x6ef6*0x10; // movwf tblptrl 00183 F_IcspInstructionSend(i); 00184 i=ICSP_TABLE_WRITE+0x0101*0x10; // write 01 to 3c0005 00185 F_IcspInstructionSend(i); 00186 i=ICSP_CORE_INSTRUCTION+0x0e3c*0x10; // movlw 3ch 00187 F_IcspInstructionSend(i); 00188 i=ICSP_CORE_INSTRUCTION+0x6ef8*0x10; // movwf tblptru 00189 F_IcspInstructionSend(i); 00190 i=ICSP_CORE_INSTRUCTION+0x0e00*0x10; // movlw 00h 00191 F_IcspInstructionSend(i); 00192 i=ICSP_CORE_INSTRUCTION+0x6ef7*0x10; // movwf tblptrh 00193 F_IcspInstructionSend(i); 00194 i=ICSP_CORE_INSTRUCTION+0x0e04*0x10; // movlw 05 00195 F_IcspInstructionSend(i); 00196 i=ICSP_CORE_INSTRUCTION+0x6ef6*0x10; // movwf tblptrl 00197 F_IcspInstructionSend(i); 00198 i=ICSP_TABLE_WRITE+0x8080*0x10; // write 80 to 3c0004 00199 F_IcspInstructionSend(i); 00200 i=ICSP_CORE_INSTRUCTION+0x0000*0x10; // nop 00201 F_IcspInstructionSend(i); 00202 F_IcspPgdLow(); 00203 for(j=0;j<4;j++){ 00204 F_IcspPgcHigh(); 00205 F_IcspPgcLow(); 00206 } 00207 Sleep(P11); // delay 475 ms 00208 for(j=0;j<16;j++){ 00209 F_IcspPgcHigh(); 00210 F_IcspPgcLow(); 00211 } 00212 } 00213 void F_IcspRowErase(void){ 00214 U32 i; 00215 U8 j; 00216 U32 k; 00217 00218 // step 1. enable write 00219 i=ICSP_CORE_INSTRUCTION+0x84a6*0x10; // movwf tblptrl 00220 F_IcspInstructionSend(i); 00221 // step 2. point to row address 00222 i=ICSP_CORE_INSTRUCTION+0x0e*0x1000+((IcspCtrl.Address>>16)&0x000000ff)*0x10; // address[23~16] 00223 F_IcspInstructionSend(i); 00224 i=ICSP_CORE_INSTRUCTION+0x6ef8*0x10; // movwf tblptru 00225 F_IcspInstructionSend(i); 00226 i=ICSP_CORE_INSTRUCTION+0x0e*0x1000+((IcspCtrl.Address>>8)&0x000000ff)*0x10; // address[23~16] 00227 F_IcspInstructionSend(i); 00228 i=ICSP_CORE_INSTRUCTION+0x6ef7*0x10; // movwf tblptrh 00229 F_IcspInstructionSend(i); 00230 i=ICSP_CORE_INSTRUCTION+0x0e*0x1000+(IcspCtrl.Address&0x000000ff)*0x10; // address[23~16] 00231 F_IcspInstructionSend(i); 00232 i=ICSP_CORE_INSTRUCTION+0x6ef6*0x10; // movwf tblptrl 00233 F_IcspInstructionSend(i); 00234 i=ICSP_CORE_INSTRUCTION+0x88a6*0x10; // enable EECON1.FREE 00235 F_IcspInstructionSend(i); 00236 i=ICSP_CORE_INSTRUCTION+0x82a6*0x10; // enable EECON1.WR 00237 F_IcspInstructionSend(i); 00238 F_IcspPgdLow(); 00239 F_IcspPgcHigh(); 00240 F_IcspPgcLow(); 00241 F_IcspPgcHigh(); 00242 F_IcspPgcLow(); 00243 F_IcspPgcHigh(); 00244 F_IcspPgcLow(); 00245 F_IcspPgcHigh(); // hold pgc high at 4th pgc 00246 Sleep(P10); // delay 10 ms 00247 F_IcspPgcLow(); 00248 for(j=0;j<16;j++){ 00249 F_IcspPgcHigh(); 00250 F_IcspPgcLow(); 00251 } 00252 } 00253 void F_IcspPageProgram(void){ 00254 U32 i; 00255 U8 j; 00256 U32 k; 00257 00258 // step 1. enable write 00259 i=ICSP_CORE_INSTRUCTION+0x84a6*0x10; // EECON1.WREN=1 00260 F_IcspInstructionSend(i); 00261 // step 2. set page address 00262 i=ICSP_CORE_INSTRUCTION+0x0e*0x1000+((IcspCtrl.Address>>16)&0x000000ff)*0x10; // address[23~16] 00263 F_IcspInstructionSend(i); 00264 i=ICSP_CORE_INSTRUCTION+0x6ef8*0x10; // movwf tblptru 00265 F_IcspInstructionSend(i); 00266 i=ICSP_CORE_INSTRUCTION+0x0e*0x1000+((IcspCtrl.Address>>8)&0x000000ff)*0x10; // address[23~16] 00267 F_IcspInstructionSend(i); 00268 i=ICSP_CORE_INSTRUCTION+0x6ef7*0x10; // movwf tblptrh 00269 F_IcspInstructionSend(i); 00270 i=ICSP_CORE_INSTRUCTION+0x0e*0x1000+(IcspCtrl.Address&0x000000ff)*0x10; // address[23~16] 00271 F_IcspInstructionSend(i); 00272 i=ICSP_CORE_INSTRUCTION+0x6ef6*0x10; // movwf tblptrl 00273 F_IcspInstructionSend(i); 00274 //step 3. repeat for all but the last bytes. any unused should be ff 00275 for(j=0;j<31;j++){ // 0~61 bytes 00276 k=IcspCtrl.pData[j*2]+IcspCtrl.pData[j*2+1]*0x100; 00277 i=ICSP_TABLE_WRITE_POST_INC2+k*0x10; // address[23~16] 00278 F_IcspInstructionSend(i); 00279 } 00280 k=IcspCtrl.pData[62]+IcspCtrl.pData[63]*0x100; 00281 i=ICSP_TABLE_WRITE_PROG+k*0x10; // page program start 00282 F_IcspInstructionSend(i); 00283 F_IcspPgdLow(); 00284 F_IcspPgcHigh(); 00285 F_IcspPgcLow(); 00286 F_IcspPgcHigh(); 00287 F_IcspPgcLow(); 00288 F_IcspPgcHigh(); 00289 F_IcspPgcLow(); 00290 F_IcspPgcHigh(); 00291 Sleep(P9); // delay 4 ms 00292 F_IcspPgcLow(); 00293 for(j=0;j<16;j++){ 00294 F_IcspPgcHigh(); 00295 F_IcspPgcLow(); 00296 } 00297 } 00298 void F_IcspPageRead(void){ 00299 U32 i; 00300 U8 j,k; 00301 U8 DataBit; 00302 U8 DataByte; 00303 00304 // step 1. set address 00305 i=ICSP_CORE_INSTRUCTION+0x0e*0x1000+((IcspCtrl.Address>>16)&0x000000ff)*0x10; // address[23~16] 00306 F_IcspInstructionSend(i); 00307 i=ICSP_CORE_INSTRUCTION+0x6ef8*0x10; // movwf tblptru 00308 F_IcspInstructionSend(i); 00309 i=ICSP_CORE_INSTRUCTION+0x0e*0x1000+((IcspCtrl.Address>>8)&0x000000ff)*0x10; // address[23~16] 00310 F_IcspInstructionSend(i); 00311 i=ICSP_CORE_INSTRUCTION+0x6ef7*0x10; // movwf tblptrh 00312 F_IcspInstructionSend(i); 00313 i=ICSP_CORE_INSTRUCTION+0x0e*0x1000+(IcspCtrl.Address&0x000000ff)*0x10; // address[23~16] 00314 F_IcspInstructionSend(i); 00315 i=ICSP_CORE_INSTRUCTION+0x6ef6*0x10; // movwf tblptrl 00316 F_IcspInstructionSend(i); 00317 00318 for(j=0;j<64;j++){ 00319 F_IcspPgdHigh(); 00320 F_IcspPgcHigh(); 00321 F_IcspPgcLow(); 00322 00323 F_IcspPgdLow(); 00324 F_IcspPgcHigh(); 00325 F_IcspPgcLow(); 00326 00327 F_IcspPgdLow(); 00328 F_IcspPgcHigh(); 00329 F_IcspPgcLow(); 00330 00331 F_IcspPgdHigh(); 00332 F_IcspPgcHigh(); 00333 F_IcspPgcLow(); 00334 00335 F_IcspPgdLow(); 00336 for(k=0;k<8;k++){ 00337 F_IcspPgcHigh(); 00338 F_IcspPgcLow(); 00339 } 00340 DataByte=0; 00341 for(k=0;k<8;k++){ 00342 F_IcspPgcHigh(); 00343 DataBit=F_IcspMPgdIn(); 00344 DataBit=F_IcspMPgdIn(); 00345 DataBit=F_IcspMPgdIn(); 00346 DataBit=F_IcspMPgdIn(); 00347 DataBit=F_IcspMPgdIn(); 00348 DataBit=F_IcspMPgdIn(); 00349 DataBit=F_IcspMPgdIn(); 00350 DataBit=F_IcspMPgdIn(); 00351 DataBit=F_IcspMPgdIn(); 00352 F_IcspPgcLow(); 00353 if(DataBit==0x40){ 00354 DataByte=DataByte>>1; 00355 DataByte=DataByte|0x80; 00356 } 00357 else{ 00358 DataByte=DataByte>>1; 00359 DataByte=DataByte&0x7f; 00360 } 00361 } 00362 IcspCtrl.pData[j]=DataByte; 00363 } 00364 } 00365 void F_IcspTest(void){ 00366 U32 i; 00367 U32 j; 00368 00369 F_IcspProgramModeEnter(); 00370 /*i=ICSP_CORE_INSTRUCTION+0x0e00*0x10; // movlw 0x00 00371 F_IcspInstructionSend(i); 00372 i=ICSP_CORE_INSTRUCTION+0x6e88*0x10; // movwf PORTJ,0...access 00373 F_IcspInstructionSend(i); 00374 i=ICSP_CORE_INSTRUCTION+0x6e9a*0x10; // movwf TRISJ,0...access 00375 F_IcspInstructionSend(i); 00376 for(j=0;j<5;j++){ 00377 i=ICSP_CORE_INSTRUCTION+0x0e0e*0x10; // movlw 0x00 00378 F_IcspInstructionSend(i); 00379 i=ICSP_CORE_INSTRUCTION+0x6e88*0x10; // movwf PORTJ,0...access 00380 F_IcspInstructionSend(i); 00381 Sleep(200); 00382 i=ICSP_CORE_INSTRUCTION+0x0e0d*0x10; // movlw 0x0f 00383 F_IcspInstructionSend(i); 00384 i=ICSP_CORE_INSTRUCTION+0x6e88*0x10; // movwf PORTJ,0...access 00385 F_IcspInstructionSend(i); 00386 Sleep(200); 00387 i=ICSP_CORE_INSTRUCTION+0x0e0b*0x10; // movlw 0x0f 00388 F_IcspInstructionSend(i); 00389 i=ICSP_CORE_INSTRUCTION+0x6e88*0x10; // movwf PORTJ,0...access 00390 F_IcspInstructionSend(i); 00391 Sleep(200); 00392 i=ICSP_CORE_INSTRUCTION+0x0e07*0x10; // movlw 0x0f 00393 F_IcspInstructionSend(i); 00394 i=ICSP_CORE_INSTRUCTION+0x6e88*0x10; // movwf PORTJ,0...access 00395 F_IcspInstructionSend(i); 00396 Sleep(200); 00397 }*/ 00398 /*IcspCtrl.Address=0; 00399 IcspCtrl.pData=&IcspBuffer[0]; 00400 F_IcspPageRead(); 00401 F_IcspBufferDump(); 00402 */ 00403 for(j=0;j<0x20;j++){ 00404 IcspCtrl.Address=0+0x40*j; 00405 IcspCtrl.pData=&IcspBuffer[0]; 00406 F_IcspPageRead(); 00407 F_IcspBufferDump(); 00408 } 00409 00410 IcspCtrl.Address=0x1ffc0; 00411 IcspCtrl.pData=&IcspBuffer[0]; 00412 F_IcspPageRead(); 00413 F_IcspBufferDump(); 00414 00415 F_IcspProgramModeExit(); 00416 F_IcspReset(); 00417 } 00418 void F_IcspBufferDump(void){ 00419 U8 i,j; 00420 00421 printf("\n Address: %8x ",IcspCtrl.Address); 00422 j=16; 00423 for(i=0;i<64;i++){ 00424 if(j==16){ 00425 printf("\n "); 00426 j=0; 00427 } 00428 printf(" %2x",IcspBuffer[i]); 00429 j++; 00430 } 00431 }
1.5.9