; Orange programmer module v3.7 ; (c) 2000-2009 CnCLab ; CHIP=PIC16F630,1023x14 ; CHIP=PIC16F676,1023x14 ; Based on Microchip DS41191D - PIC12F629/675/PIC16F630/676 Memory Programming ; OSCALL вынесен из общего адресного пространства ; Для изменения использовать команду Erase CODE ; Запоминать и восстанавливать значение BG ; Primary Tested PIC16F630 ; Orange3,4,SE ALLPINS=14 INFO="PIC Adapter" ; PING=SDA,1,13 ;GP0 PINO=CLK,0,12 ;GP1 PINO=MCLR,5,4 ;/MCLR PINO=VDD,254,1 ;Vdd PING=GND,255,14 ;Vss CDELAY=2 R1=CONFIG,H R2=BG,L,00,01,10,11 R3=PWRTE,L,On,Off R4=WDTE,L,Off,On R5=FOSC,L,000:LP,001:XT,010:HS,011:EC(RA4-IO),100:intOSC(RA4&RA5-IO),101:intOSC(RA4-CLK.RA5-IO),110:extR(RA4-IO),111:extR(RA4-CLK) R6=BODEN,L,On,Off R7=MCLRE,L,Off,On R11=CPD,L,On,Off R10=CP,L,All,Off R17=OSCCAL,H4 R1B=Erase,L,Off,Code,Data,All ;R18 - ID ;R8 use for store address [_PULSE] CLK=1,P=2,CLK=0,P=2 [_COMMAND] ; R0 - CMD P=1 LOOP=(0,5){SDA=R0[I],CLK=1,CLK=0} P=1 [_OUTWORD] SDA=0,CLK=1,CLK=0 LOOP=(0,13){SDA=R0[I],_PULSE} SDA=0,CLK=1,CLK=0 [_INWORD] R1=0 SDA=1,_PULSE LOOP=(0,13){_PULSE,R1[I]=SDA} SDA=1,_PULSE [_INCADD] R8=ADR LOOP=(0xFFFF){ ;increment address to current value! R9?R8{BREAK} _COMMAND(6) ;INCADD R9=+1 } [INIT] $VERSION=/65536 ;PRINT=("%u",$VERSION) MCLR=0,CLK=1,SDA=1 $VERSION?3{ PRINT=S("Power up...") P=600000 ;charge Vpp cap! } CLK=0,SDA=0 IDISABLE VCC=0 P=80000 $VERSION?!3{P=40000} VPP=12000,MCLR=1,P=1000 ;O4! VCC=1 ;Vcc pulse for re-enter prg mode ;Programm/Verify Mode! P=100000 IENABLE PRINT=S(" ") R9=0 ;current address register R7=0 ; [_INITOLD] ;Enter Programm/Verify Mode: MCLR=0,CLK=0,SDA=0 PRINT=S("Power up...") P=600000 ;charge MCLR cap! IDISABLE CLK=0,SDA=0 VCC=0 VCC=1 ;TPPDP Hold time after V PP ^5 us MCLR=1 ;Vcc pulse for re-enter prg mode IENABLE P=200000 PRINT=S(" ") R9=0 ;current address register ;-------------------------------------------------------- [_FUSE2BIT] ; unpack config word ;13 12 11 10 9 8 7 6 5 4 3 2 1 0 ;BG1 BG0 - - - CPD CP BODEN MCLRE PWRTE WDTE FOSC2 F0SC1 F0SC0 R2=0,R3=0,R4=0,R5=0,R6=0,R11=0,R10=0,R7=0 R5[0]=R1[0],R5[1]=R1[1],R5[2]=R1[2] ;FOSC R4[0]=R1[3] ;WDT R3[0]=R1[4] ;PWR R7[0]=R1[5] ;MCLRE R6[0]=R1[6] ;BODEN ; R10[0]=R1[7] ;CP R11[0]=R1[8] ;CPD R2[0]=R1[12],R2[1]=R1[13] ;BG [_BIT2FUSE] ;copy separate bits to config word R1=0 ; Unimplemented bit, read as '0' R1[0]=R5[0],R1[1]=R5[1],R1[2]=R5[2] ;FOSC, R1[3]=R4[0] ;WDT R1[4]=R3[0] ;PWR R1[5]=R7[0] ;MCLRE R1[6]=R6[0] ;BODEN ; R1[7]=R10[0] ;CP R1[8]=R11[0] ;CPD R1[12]=R2[0],R1[13]=R2[1] ;BG [_READFUSES] _COMMAND(0) ;LDCONF R0=0x3FFF,_OUTWORD ; dummy ADR=0 LOOP=(0,6){ ; goto adr 0x2007 _COMMAND(4) ;RDPROG SDA=1,_PULSE LOOP=(0,13){_PULSE} ;dummy read... SDA=0,_PULSE ADR=+1 _INCADD } _COMMAND(4) ;RDPROG _INWORD ;PRINT=("Configuration Word = %04lX",R1) ;copy config world to separate bits ADR=0 DATA=R1 ;_FUSE2BIT [_WRITEFUSES] ;ADR=0 R1=DATA ADR=0 _COMMAND(0) ;LDCONF R0=0x3FFF,_OUTWORD ; dummy LOOP=(0,6){ ; goto adr 0x2007 R0=2,_COMMAND ; LDPROG R0=0x3FFF,_OUTWORD ; dummy data ;R0=8,_COMMAND ; BEGPRG - don't really programm ;P=10000 P=10 ADR=+1 _INCADD } _COMMAND(2) ;LDPROG R0=R1,_OUTWORD ;config _COMMAND(8) ;BEGPRG int. timed. P=50000 ; check? _COMMAND(4) ;RDPROG R2=R1 _INWORD R1?!R2{PRINT=("Write error! [%04lX]",R1)} ;-------------------------------------------------------- [READ] $AREA?2{_READFUSES,RETURN} _INCADD R0=4 ;RDPROG $AREA?1{R0=5} ;RDDATA _COMMAND _INWORD DATA=R1 [WRITE] $AREA?0{R0=DATA,R0=&0x3FFF,R0?0x3FFF{RETURN}} ;не пишем пустые во FLASH для ускорения $AREA?2{_WRITEFUSES,EXIT} _INCADD $AREA?1{_COMMAND(3)} ;LDDATA $AREA?0{ _COMMAND(2) ;LDPROG } _OUTWORD(DATA) _COMMAND(8) ;BEGPRG P=10000 [~!#"Fuse Editor"] $AREA=2 ;FUSES R1=DATA _FUSE2BIT GET=("Edit Fuses",R5,R4,R3,R7,R6,R11,R10,R2) RA?0{EXIT} _BIT2FUSE DATA=R1 ;---------------------------------------------------------------------- ;Перед стиранием кристалла необходимо запомнить: ; биты BG0,BG1 (биты 12 и 13 по адресу #2007) ; 14 бит OSCCAL 0x3FF AREA CODE (байт настройки intRC) ;---------------------------------------------------------------------- [_EraseCode] ; Save OSCCAL: $AREA=0 ADR=0 LOOP=(0,0x3FF){ _COMMAND(4) ;RDPROG _INWORD _COMMAND(6) ;INCADD } R17=R1 ;PRINT=("OSCCAL = %04lX",R17) PRINT=S("Erase...") ; Erase CODE, DATA стирать отдельно... _COMMAND(0) ;LDCONF _OUTWORD(03FFFH) R0=6,LOOP=(0,6){_COMMAND} ;INCADD _COMMAND(9) ;Bulk Erase P=20000 ADR=$SIZE ADR=-1 R17?!0x3FFF{DATA=R17} ; Restore OSCALL : GET=("Restore OSCALL value ?",R17) RA?0{EXIT} DATA=R17 ;OSCALL to dump PRINT=S("Restore OSCALL value %04lX",R17) MCLR=0 CLK=0,SDA=0 VCC=0,P=200000 VCC=1 ; re-enter Programming mode. MCLR=1 P=200000 R9=0 ;current address register ADR=0 LOOP=(0,0x3FE){ ;Goto 0x3FF _COMMAND(2) ; LDPROG _OUTWORD(0x3FFF) ; dummy data _COMMAND(6) ;INCADD } _COMMAND(2) ;LDPROG _OUTWORD (R17) _COMMAND(8) ;BEGPRG P=10000 [_EraseData] $AREA=1 ;Data _COMMAND(0) ;LDCONF _OUTWORD(03FFFH) R0=6,LOOP=(0,6){_COMMAND} ;INCADD R0=0xB,_COMMAND ;Bulk Erase DATA P=10000 [Erase] ;R1B=Erase,L,Off,Code,Data,All GET=("Erase",R1B) RA?0{EXIT} R1B?0{EXIT} ;Off ;_COMMAND(0) ;LDCONF ;_OUTWORD(03FFFH) R1B?1{_EraseCode} ;Code R1B?2{_EraseData} ;Data R1B?3{_EraseCode,_EraseData} ;All [_READID] _COMMAND(0) ;LDCONF _OUTWORD(0x3FFF) ; dummy ADR=0 LOOP=(0,5){ ; goto adr 0x2005 _COMMAND(4) ;RDPROG _INWORD ;dummy read - обязательно... ADR=+1 _INCADD } _COMMAND(4) ;RDPROG ;2006 _INWORD R18=R1 ["Read ID"] _READID R1=R18,R1=/32,R1=&01FFH R1?10000110B{PRINT=("PIC16F630\nID=%04lX",R18),EXIT} R1?10000111B{PRINT=("PIC16F676\nID=%04lX",R18),EXIT} PRINT=("ID=%04lX",R18) [END] MCLR=0,CLK=0,SDA=0