; Orange programmer module v3.8 ; (c) 2000-2011 CnCLab ; CHIP=PIC12F675,1023x14, ADC 10-BIT ; CHIP=PIC12F629,1023x14, COMPARATOR ; OSCALL вынесен из общего адресного пространства ; Для изменения использовать команду Erase CODE ; Запоминать и восстанавливать значение BG ; Improved, Primary Tested ; Orange3,4,5,SE ALLPINS=8 INFO="PIC Adapter" ; PING=SDA,1,7 ;GP0 PINO=CLK,0,6 ;GP1 PINO=MCLR,5,4 ;/MCLR PINO=VDD,254,1 ;Vdd PING=GND,255,8 ;Vss CDELAY=3 ;POWER=0 ; управление питанием из HPL R1=CONFIG,H R2=BG,L,00,01,10,11 R3=PWRTE,L,0:On,1:Off R4=WDTE,L,0:Off,1:On R5=FOSC,L,000:LP,001:XT,010:HS,011:EC(GP4-IO),100:intOSC(GP4&GP5-IO),101:intOSC(GP4-CLK.GP5-IO),110:extR(GP4-IO),111:extR(GP4-CLK) R6=BODEN,L,0:On,1:Off R7=MCLRE,L,0:Off,1:On R11=CPD,L,0:On,1:Off R10=CP,L,0:All,1:Off R17=OSCCAL,H4 ;R18 - ID ;R8 use for store address [_PULSE] CLK=1,P=3,CLK=0,P=3 [_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=(0,0xFFFF){ ;increment address to current value! R9?R8{BREAK} _COMMAND(6) ;INCADD R9=+1 } [_INIT] ;OLD! $VERSION=/65536 ;PRINT=("%u",$VERSION) MCLR=0,VPP=0,CLK=0,SDA=0 $VERSION?3{ MCLR=0,VPP=0,VCC=1 PRINT=S("Power up...") P=600000 ;charge Vpp cap! VCC=0 P=250000 } MCLR=1,VPP=10000 P=2000 ;TPPDP Hold time after VPP^ min 5us VCC=1 ;Vcc pulse for re-enter prg mode ;Programm/Verify Mode! ;IENABLE ;PRINT=S(" ") P=150000 ; THLD0 CLOCK, DATA hold time after MCLR min 5us R9=0 ;current address register [INIT] $VERSION=/65536 ;PRINT=("%u",$VERSION) MCLR=0,CLK=0,SDA=0 $VERSION?3{ PRINT=S("Power up...") P=600000 ;charge Vpp cap! } CLK=0,SDA=0 IDISABLE VCC=0 P=90000 MCLR=1,VPP=10000,P=200 ;O4! VCC=1 ;Vcc pulse for re-enter prg mode ;Programm/Verify Mode! IENABLE P=130000 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 ;PRINT=("Configuration Word = %04lX",R1) [_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 [_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=10000 ; 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 ADR=0 R1=DATA ;PRINT=S("%04X",R1) _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) ;---------------------------------------------------------------------- ["Erase CODE"] ; Save OSCCAL: $AREA?!0{PRINT=E("Select CODE area!"),EXIT} ;обязательно для Orange5. ADR=0 LOOP=(0,0x3FF){ _COMMAND(4) ;RDPROG _INWORD _COMMAND(6) ;INCADD } R17=R1 ;PRINT=L("OSCCAL = %04lX",R17) PRINT=S("Erase...") ; Erase CODE, DATA стирать отдельно... _COMMAND(0) ;LDCONF _OUTWORD(03FFFH) R0=6,LOOP=(7){_COMMAND} ;INCADD _COMMAND(9) ;Bulk Erase P=20000 ADR=$SIZE ;ADR=-1 ;OSCALL выключена из адресного пространства. 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 ["Erase DATA"] $AREA=1 ;Data _COMMAND(0) ;LDCONF _OUTWORD(03FFFH) R0=6,LOOP=(0,6){_COMMAND} ;INCADD R0=0xB,_COMMAND ;Bulk Erase DATA P=10000 [_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?1111100B{PRINT=("PIC12F629\nID=%04lX",R18),EXIT} R1?1111110B{PRINT=("PIC12F675\nID=%04lX",R18),EXIT} PRINT=("ID=%04lX",R18) [END] MCLR=0,VPP=0,CLK=0,SDA=0,VCC=0