; Orange programmer module v3.1 ; (c) 2000-2010 CnCLab ; CHIP=PIC16F627A,1Kx14 ; CHIP=PIC16F628A,2Kx14 ; CHIP=PIC16F648A,4Kx14 ; CHIP=PIC16LF627A,1Kx14 ; CHIP=PIC16LF628A,2Kx14 ; CHIP=PIC16LF648A,4Kx14 ; Primary Tested 16F628A, 648A ; "A" chips have different erase mode and fuses! ALLPINS=18 INFO="PIC Adapter" ;POWER=0 ; управление питанием из HPL PING=SDA,1,13 ;RB7 PINO=CLK,0,12 ;RB6 PINO=MCLR,5,4 ;/MCLR PINO=PGM,2,10 ;RB4/PGM PING=GND,255,5 ;Vss CDELAY=2 R1=CONFIG,H R2=CP,L,On,Off R3=PWRT,L,On,Off R4=WDT,L,Off,On R5=FOSC,L,LP,XT,HS,extCLK,intRC(RA6-I/O),intRC(RA6-CLK),extR(RA6-I/O),extR(RA6-CLK) R6=BOREN,L,On,Off R7=CPD,L,On,Off RB=LVP,L,Off,On RC=MCLRE,L,Ra5,On [_PULSE] CLK=1,P=2,CLK=0,P=2 [_COMMAND] ; R0 - CMD P=1 LOOP=(0,5){SDA=R0[I],_PULSE} P=1 [_OUTWORD] SDA=0,CLK=1,CLK=0 LOOP=(0,13){SDA=R0[I],_PULSE} SDA=0,CLK=1,CLK=0 [_INCADD] R8=ADR LOOP=(0xFFFF){ ;increment address to current value! R9?R8{BREAK} _COMMAND(6) ;INCADD R9=+1 } [INIT] ;Configuration bit is set (i.e., LVP feature is enabled), ;PGM pin must not be allowed to toggle while programming. ;The PGM pin is edge sensitive and if an ;edge is detected during programming, it may cause the PC to reset. ;If the LVP feature is disabled, the PGM pin no effect on programming. ; Vpp (MCLR) должно подаваться раньше, чем Vcc. PGM=0,VPP=0,MCLR=0,CLK=0,SDA=0 $VERSION=/65536 $VERSION?3{ ;Orange3 VCC=1 MCLR=0,CLK=0,SDA=0 ; P=250000 MCLR=1,VPP=12500 ;Programm/Verify Mode! P=250000 } $VERSION?!3{ ;Orange4,5,SE VCC=0 P=250000 VPP=12500,MCLR=1 P=150000 VCC=1,CLK=0,SDA=0 P=100000 } P=800 ;Hold time after MCLR^ TPPDP min 5 us R9=0 ;current address register ;------------------------------------------------- [_FUSE2BIT] ; unpack config word ;13 12 11 10 9 8 7 6 5 4 3 2 1 0 ;CP - - - - CPD LVP BOREN MCLRE FOSC2 PWRTE WDTE F0SC1 F0SC0 R2=0,R3=0,R4=0,R5=0,R6=0,R7=0,RB=0,RC=0 R5[0]=R1[0],R5[1]=R1[1],R5[2]=R1[4] ;FOSC R4[0]=R1[2] ;WDT R3[0]=R1[3] ;PWR RC[0]=R1[5] ;MCLRE R6[0]=R1[6] ;BOREN RB[0]=R1[7] ;LVP R7[0]=R1[8] ;CPD R2[0]=R1[13] ;CP [_BIT2FUSE] ;copy separate bits to config word R1=0x3FFF R1[0]=R5[0],R1[1]=R5[1],R1[4]=R5[2] ;FOSC, R1[2]=R4[0] ;WDT R1[3]=R3[0] ;PWR R1[5]=RC[0] ;MCLRE R1[6]=R6[0] ;BOREN ; also bit 3 R1[7]=RB[0] ;LVP R1[8]=R7[0] ;CPD R1[13]=R2[0] ;CP ;PRINT=("Configuration Word = %04lX",R1) [_READFUSES] _COMMAND(0) ;LDCONF _OUTWORD(0x3FFF) ; 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 SDA=0,_PULSE R1=0 LOOP=(0,13){_PULSE,SDA=1,R1[I]=SDA,SDA=0} SDA=1,_PULSE ;PRINT=("Configuration Word = %04lX",R1) ADR=0 DATA=R1 [_WRITEFUSES] ADR=0 R1=DATA ;_FUSE2BIT _COMMAND(0) ;LDCONF _OUTWORD(0x3FFF) ; dummy LOOP=(0,6){ ; goto adr 0x2007 _COMMAND(2) ; LDPROG _OUTWORD(0x3FFF) ; dummy data ;R0=8,_COMMAND ; BEGPRG - don't really programm ;P=10000 P=100 ADR=+1 _INCADD } _COMMAND(2) ;LDPROG _OUTWORD(R1) ;config _COMMAND(8) ; BEGPRG P=20000 ; check only if not code protected! _COMMAND(4) ;RDPROG SDA=0,_PULSE R2=0x3FFF LOOP=(0,13){_PULSE,SDA=1,R2[I]=SDA,SDA=0} SDA=1,_PULSE R1?!R2{PRINT=("Write error!")} ;------------------------------------------------- [READ] $AREA?2{_READFUSES,RETURN} _INCADD R0=4 ;RDPROG $AREA?1{R0=5} ;RDDATA _COMMAND SDA=1,_PULSE R0=0 LOOP=(0,13){_PULSE,R0[I]=SDA} SDA=1,_PULSE DATA=R0 ;For Orange5 только через регистр! ;CLK=1,CLK=0 ;R0=6,_COMMAND ;INCADD [WRITE] $AREA?0{R3=DATA,R3=&0x3FFF,R3?0x3FFF{RETURN}} ; skip empty code word $AREA?2{_WRITEFUSES,EXIT} _INCADD R0=2 ;LDPROG $AREA?1{R0=3} ;LDDATA _COMMAND SDA=0,CLK=1,CLK=0 LOOP=(0,13){SDA=DATA[I],_PULSE} SDA=0,CLK=1,CLK=0 _COMMAND(8) ;BEGPRG P=10000 [~!#"Fuse Editor"] $AREA=2 ;FUSES R1=DATA _FUSE2BIT GET=("Edit Fuses",R2,R3,R4,R5,R6,R7,RB,RC) RA?0{EXIT} _BIT2FUSE DATA=R1 [EraseCode] ADR=0 P=50000 ;R0=2,_COMMAND ; ;R0=03FFFH,_OUTWORD _COMMAND(9) ;Bulk Erase Prg _COMMAND(8) ;begin P=50000 [EraseData] ADR=0 P=50000 _COMMAND(0xB) ;Bulk Erase Data _COMMAND(8) ;begin P=50000 [END] MCLR=0 VPP=0 CLK=0,SDA=0 VCC=0 ;[ReadID] ;ADR=0x2000 ;R7=0 ;LOOP=(0,3){ ;_INCADD ;R0=4,_COMMAND ;RDPROG ;SDA=0 ;CLK=1,CLK=0 ;R0=0 ;LOOP=(0,13){_PULSE,SDA=1,R0[I]=SDA,SDA=0} ;CLK=1,CLK=0 ;R0=&0xF ;R7=|R0 ;R7=<<4 ;} ;R7=/16 ;PRINT=("ID = %04lX",R7) ;[ReadCFGAll] ;R0=0,_COMMAND ;ADR=0 ; goto 2007: ;LOOP=(0,7){ ;R0=4,_COMMAND ;RDPROG ;SDA=1,_PULSE ;R7=0 ;LOOP=(0,13){_PULSE,R7[I]=SDA} ;SDA=0,_PULSE ;PRINT=("Configuration = %04lX [%04lX]",R7,ADR) ;ADR=+1,_INCADD ;} ["Read ID"] _COMMAND(0) ;LDCONF R0=0x3FFF,_OUTWORD ; dummy!!! ADR=0 LOOP=(0,5){ ;goto adr 0x2007 _COMMAND(6) ;INCADD } _COMMAND(4) ;RDPROG ;2006h SDA=0,_PULSE SDA=1 R1=0 LOOP=(0,13){_PULSE,R1[I]=SDA} SDA=1,_PULSE R2=R1 MCLR=0,VPP=0,CLK=0,SDA=0,VCC=0 R2=&3FE0H ;id mask R2?1040H{PRINT=("ID = %04lX - PIC16F627A",R1),RETURN} R2?1060H{PRINT=("ID = %04lX - PIC16F628A",R1),RETURN} R2?1100H{PRINT=("ID = %04lX - PIC16F648A",R1),RETURN} PRINT=("ID = %04lX",R1)