; Orange programmer module v4.2 ; (c) 2000-2012 CnCLab ; CHIP=PIC16F873A,4Kx14 ; CHIP=PIC16F874A,4Kx14 ; CHIP=PIC16F876A,8Kx14 ; CHIP=PIC16F877A,8Kx14 ;CHIP=PIC16F876A,8Kx14,p16f876a.hpl ;AREA=CODE,8Kx14,0 ;AREA=DATA,256,0,0x4200,b ;AREA=CONFIG,1x14,0,0x400E ; Primary Tested PIC16F876A,877A ALLPINS=28 INFO="PIC Adapter" OPTIONS=f,b ; PING=SDA,1,28 ;RB7 PINO=CLK,0,27 ;RB6 PINO=MCLR,5,1 ;/MCLR PINO=PGM,2,24 ;RB3/PGM PING=GND,255,8 ;Vss PING=GND2,255,19 ;Vss PINO=VDD,254,20 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,RC R6=BOREN,L,On,Off R7=CPD,L,On,Off RB=LVP,L,Off,On R10=WRT,L,0xFFF,0x7FF,0x0FF,Off R11=DEBUG,L,On,Off R1B=Erase,L,Off,Code,Data,All [_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 [_INCADD] R8=ADR LOOP=(0,0xFFFF){ ;increment address to current value! R9?R8{BREAK} _COMMAND(6) ;INCADD R9=+1 } ;The OSC must not have 72 osc clocks while the device MCLR is between VIL and VIHH. [INIT] VPP=0 MCLR=0,CLK=0,SDA=0 PGM=0 $VERSION=/65536 $VERSION?3{ PRINT=S("Power up...") P=200000 ;charge MCLR cap! CLK=0,SDA=0 IDISABLE VCC=0 P=25000 ;no more time 25000! VCC=1 VPP=12800 MCLR=1 ;Vcc pulse for re-enter prg mode IENABLE ;Programm/Verify Mode! } $VERSION?!3{ CLK=0,SDA=0,P=100 VPP=12800 MCLR=1 ;Vcc pulse for re-enter prg mode } P=150000 PRINT=S(" ") R9=0 ;current address register [_init] VPP=0 MCLR=0,CLK=1,SDA=1 PRINT=S("Power up...") P=300000 ;charge MCLR cap! CLK=0,SDA=0 IDISABLE VCC=0 P=30000 ;no more time! VCC=1,MCLR=1 ;Vcc pulse for re-enter prg mode ;MCLR=1,VCC=1 ;Vcc pulse for re-enter prg mode ;Programm/Verify Mode! SDA=1 IENABLE P=200000 PRINT=S(" ") R9=0 ;current address register ;------------------------------------------------- [_FUSE2BIT] ;13 12 11 10 9 8 7 6 5 4 3 2 1 0 ;CP - DEBUG WRT1 WRT0 CPD LVP BOREN - - PWRTE WDTE F0SC1 F0SC0 R2=0,R3=0,R4=0,R5=0,R6=0,R7=0,RB=0,R10=0,R11=0 R5[0]=R1[0],R5[1]=R1[1] ;FOSC R4[0]=R1[2] ;WDT R3[0]=R1[3] ;PWRTEN R6[0]=R1[6] ;BOREN RB[0]=R1[7] ;LVP R7[0]=R1[8] ;CPD R10[0]=R1[9],R10[1]=R1[10] ;WRT R11[0]=R1[11] ;DEBUG R2[0]=R1[13] ;CP [_BIT2FUSE] ;copy separate bits to config word R1=0x3FFF R1[0]=R5[0],R1[1]=R5[1] ;FOSC R1[2]=R4[0] ;WDT R1[3]=R3[0] ;PWR R1[6]=R6[0] ;BOREN R1[7]=RB[0] ;LVP R1[8]=R7[0] ;CPD CP Data R1[9]=R10[0],R1[10]=R10[1] ;WRT R1[11]=R11[0] ;DEBUG R1[13]=R2[0] ;CP ;PRINT=("Configuration Word = %04lX",R1) [_READFUSES] R0=0,_COMMAND ;LDCONF R0=0x3FFF,_OUTWORD ; dummy!!! ADR=0 LOOP=(0,6){ ; goto adr 0x2007 R0=6,_COMMAND ;INCADD } R0=4,_COMMAND ;RDPROG SDA=0,_PULSE SDA=1 R1=0 LOOP=(0,13){_PULSE,R1[I]=SDA} SDA=1,_PULSE ;PRINT=("Configuration Word = %04lX",R1) ADR=0 DATA=R1 _FUSE2BIT [_WRITEFUSES] ADR=0 R1=DATA ADR=0 _COMMAND(0) ;LDCONF _OUTWORD(0x3FFF) ; dummy!!! LOOP=(0,6){ ; goto adr 0x2007 _COMMAND(6) ;INCADD } _COMMAND(2) ;LDPROG R0=R1,_OUTWORD ;config _COMMAND(8) ;BEGERPRG P=10000 _COMMAND(0x17) ;ENDPRG ; check? _COMMAND(4) ;RDPROG SDA=0,_PULSE SDA=1 R2=0x3FFF LOOP=(0,13){_PULSE,R2[I]=SDA} 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{R0=DATA,R0=&0x3FFF,R0?0x3FFF{RETURN}} $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(0x18) ;BEGPRGONLY P=8000 _COMMAND(0x17) ;ENDPRG ; Only for flash, 8 words ; нельзя делать проверку после записи блока - нет команды декремента адреса [_WRITEBLOCK] R7=ADR ;check empty (0x3FFF) block LOOP=($BLOCKSIZE){ R1=DATA R1=&0x3FFF,R1?!0x3FFF{BREAK} ADR=+1 } R1?0x3FFF{RETURN} ;empty ADR=R7 LOOP($BLOCKSIZE){ R7=ADR,PRINT=L("Wr %04X\n",R7) _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 ADR=+1 } _COMMAND(0x18) ;BEGPRGONLY P=8000 _COMMAND(0x17) ;ENDPRG [~!#"Fuse Editor"] $AREA=2 ;FUSES R1=DATA _FUSE2BIT GET=("Edit Fuses",R2,R3,R4,R5,R6,R7,RB,R10,R11) RA?0{EXIT} _BIT2FUSE DATA=R1 [_EraseAll] ADR=0 R0=0,_COMMAND ;LDCONF R0=0x3FFF,_OUTWORD ; dummy!!! R0=0x1F,_COMMAND ;Chip Erase R0=8,_COMMAND ;begin P=50000 P=50000 [_EraseCode] ADR=0 ;R0=2,_COMMAND ; ;R0=03FFFH,_OUTWORD R0=9,_COMMAND ;Bulk Erase Prg R0=8,_COMMAND ;begin P=50000 [_EraseData] ADR=0 R0=0xB,_COMMAND ;Bulk Erase Data R0=8,_COMMAND ;begin P=50000 [Erase] ;R1B=Erase,L,Off,Code,Data,All GET=("Erase",R1B) RA?0{EXIT} R1B?0{EXIT} ;Off P=50000 R1B?1{_EraseCode} ;Code R1B?2{_EraseData} ;Data R1B?3{_EraseAll} ;All P=50000 ["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,CLK=0,SDA=0,VCC=0 R2=&0FE0H ;id mask R2?0920H{PRINT=("ID = %04lX - PIC16F874",R1),EXIT} R2?09E0H{PRINT=("ID = %04lX - PIC16F876",R1),EXIT} R2?09A0H{PRINT=("ID = %04lX - PIC16F877",R1),EXIT} R2?0E00H{PRINT=("ID = %04lX - PIC16F876A",R1),EXIT} R2?0E20H{PRINT=("ID = %04lX - PIC16F877A",R1),EXIT} PRINT=("ID = %04lX",R1) [END] MCLR=0 VPP=0 CLK=0,SDA=0