; Orange programmer module v3.9 ; (c) 2000-2012 CnCLab ; CHIP=PIC16F882,2Kx14+128 28pin ; CHIP=PIC16F883,4Kx14+256 28pin ; CHIP=PIC16F884,4Kx14+256 40pin ; CHIP=PIC16F886,8Kx14+256 28pin ; CHIP=PIC16F887,8Kx14+256 40pin ;CHIP=PIC16F882,2Kx14,p16f887.hpl ;AREA=CODE,2Kx14(4),0 ;AREA=DATA,128,0,0x4200,b ;AREA=CONFIG,1x14,0,0x400E ;CHIP=PIC16F883,4Kx14,p16f887.hpl ;AREA=CODE,4Kx14(4),0 ;AREA=DATA,256,0,0x4200,b ;AREA=CONFIG,1x14,0,0x400E ;CHIP=PIC16F884,4Kx14,p16f887.hpl ;AREA=CODE,4Kx14(4),0 ;AREA=DATA,256,0,0x4200,b ;AREA=CONFIG,1x14,0,0x400E ;CHIP=PIC16F886,8Kx14,p16f887.hpl ;AREA=CODE,8Kx14(4),0 ;AREA=DATA,256,0,0x4200,b ;AREA=CONFIG,1x14,0,0x400E ;CHIP=PIC16F887,8Kx14,p16f887.hpl ;AREA=CODE,8Kx14(4),0 ;AREA=DATA,256,0,0x4200,b ;AREA=CONFIG,1x14,0,0x400E ; Primary Tested PIC16F886 ALLPINS=28 INFO="PIC Adapter" ; PING=SDA,1,28 ;RB7 PINO=CLK,0,27 ;RB6 PINO=PGM,2,24 ;RB4/PGM PINO=MCLR,5,1 ;/MCLR PING=GND,255,8 ;Vss PING=GND2,255,19 ;Vss PINO=VDD,254,20 CDELAY=2 R10=DEBUG,L,"0:On,1:Off" R11=LVP,L,"0:RB3 digitalIO,1:RB3-PGM" R12=FCMEN,L,0:Off,1:On R13=IESO,L,0:Off,1:On R14=BOREN,L,00:Off,01:SBOREN,10:OnNoSleep,11:On R15=CPD,L,0:On,1:Off R16=CP,L,0:On,1:Off R17=MCLRE,L,0:RE3-MCLR,1:RE3-Input R18=PWRTE,L,On,Off R19=WDTEN,L,"0:WDT Off,1:WDT On" R1A=FOSC,L,000:LP,001:XT,010:HS,011:EC(RA6-IO),100:intOSCIO,101:intOSC,110:RCIO,111:RC R1B=Erase,L,Off,Code,Data,All [!#SETUP] $WDELAY=3000 ;Program memory [_PULSE] CLK=1,P=1,CLK=0,P=1 [_COMMAND] ; R0 - CMD P=1 LOOP=(0,5){SDA=R0[I],CLK=P} P=1 [_OUTWORD] SDA=0,CLK=P LOOP=(0,13){SDA=R0[I],_PULSE} SDA=0,CLK=P [_INCADD] R8=ADR LOOP=(0,0xFFFF){ ;increment address to current value! R9?R8{BREAK} R0=6,_COMMAND ;INCADD R9=+1 } [INIT] ;Two methods are available to enter Program/Verify mode. ;1 The "VPP-first" - not used ;2 "VDD-first", is entered by applying VDD, holding ICSPDAT and ICSPCLK low, ;then raising MCLR pin from VIL to VIHH (high voltage), VPP=0 PGM=0 MCLR=0 CLK=0,SDA=0 $VERSION=/65536,$VERSION?3{ ;Orange3 Only P=200000 ;charge MCLR cap! } VPP=12800 MCLR=1 P=5000 PRINT=S(" ") R9=0 ;current address register ;------------------------------------------------- [_FUSE2BIT] ;13 12 11 10 9 8 7 6 5 4 3 2 1 0 ;DEBUG LVP FCMEN IESO BOREN1 BOREN0 CPD CP MCLRE PWRTE WDTE F0SC1 F0SC1 F0SC0 ;------------------------------------------------- R10=0,R11=0,R12=0,R13=0,R14=0,R15=0,R16=0,R17=0,R18=0,R19=0,R1A=0 R1A[0]=RA[0],R1A[1]=R1[1],R1A[2]=R1[2] ;FOSC R19[0]=R1[3] ;WDTE R18[0]=R1[4] ;PWRTE R17[0]=R1[5] ;MCLRE R16[0]=R1[6] ;CP R15[0]=R1[7] ;CPD R14[0]=R1[8],R14[1]=R1[9] ;BOREN R13[0]=R1[10] ;IESO R12[0]=R1[11] ;FCMEN R11[0]=R1[12] ;LVP R10[0]=R1[13] ;DEBUG [_BIT2FUSE] ;copy separate bits to config word R1=0x3FFF R1[0]=R1A[0],R1[1]=R1A[1],R1[2]=R1A[2] ;FOSC R1[3]=R19[0] ;WDTE R1[4]=R18[0] ;PWRTE R1[5]=R17[0] ;MCLRE R1[6]=R16[0] ;CP R1[7]=R15[0] ;CPD R1[8]=R14[0],R1[9]=R14[1] ;BOREN R1[10]=R13[0] ;IESO R1[11]=R12[0] ;FCMEN R1[12]=R11[0] ;LVP R1[13]=R10[0] ;DEBUG ;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 ;RE?!2{ ;GET=("Fuses",R2,R3,R4,R5,R6,R7,RB,R10,R11) ;} [_WRITEFUSES] ADR=0 R1=DATA ;_FUSE2BIT ;GET=("Write Fuses",R2,R3,R4,R5,R6,R7,RB,R10,R11) ;RA?0{EXIT} ;_BIT2FUSE ;copy separate bits to config world ADR=0 R0=0,_COMMAND ;LDCONF R0=0x3FFF,_OUTWORD ; dummy!!! LOOP=(0,6){ ; goto adr 0x2007 R0=6,_COMMAND ;INCADD } R0=2,_COMMAND ;LDPROG R0=R1,_OUTWORD ;config R0=0x08,_COMMAND ;BEGERPRG P=10000 ; check? R0=4,_COMMAND ;RDPROG SDA=0,_PULSE SDA=1 R2=0x3FFF LOOP=(0,13){_PULSE,R2[I]=SDA} SDA=1,_PULSE R1?!R2{PRINT=E("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}} ;не пишем пустые во FLASH для ускорения $AREA?2{_WRITEFUSES,EXIT} _INCADD R0=2 ;LDPROG $AREA?1{R0=3} ;LDDATA _COMMAND SDA=0,CLK=P LOOP=(0,13){SDA=DATA[I],_PULSE} SDA=0,CLK=P _COMMAND(0x08) ;BEGPRG Internally Timed P=$WDELAY $AREA?!0{P=$WDELAY} ; Program memory faster, Data - 6ms ; ONLY FOR CODE FLASH! [_WRITEBLOCK] ;not work ;R0=ADR,R1=DATA,PRINT=L("ADR=%04X,D=%02X\n",R0,R1) LOOP($BLOCKSIZE){ _INCADD _COMMAND(2) ;LDPROG SDA=0,CLK=1,CLK=0 LOOP=(0,13){SDA=DATA[I],_PULSE} SDA=0,CLK=1,CLK=0 ADR=+1 } _COMMAND(0x08) ;BEGPRG Internally Timed P=$WDELAY [~!#"Fuse Editor"] $AREA=2 ;FUSES R1=DATA _FUSE2BIT GET=("Edit Fuses",R10,R11,R12,R13,R14,R15,R16,R17,R18,R19) RA?0{EXIT} _BIT2FUSE DATA=R1 [_EraseCode] PRINT=S("Erase Code...") ;_RDCALIB ADR=0 P=50000 ;R0=2,_COMMAND ; ;R0=03FFFH,_OUTWORD R0=9,_COMMAND ;Bulk Erase Prg ;R0=8,_COMMAND ;begin P=50000 [_EraseData] PRINT=S("Erase Data...") ADR=0 P=50000 _COMMAND(0x0B) ; 1011 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 _COMMAND(0) ;LDCONF _OUTWORD(03FFFH) R1B?1{_EraseCode} ;Code R1B?2{_EraseData} ;Data R1B?3{_EraseCode,_EraseData} ;All ["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=&0FFE0H ;id mask R2?02020H{PRINT=("ID = %04lX - PIC16F883",R1),EXIT} R2?02040H{PRINT=("ID = %04lX - PIC16F884",R1),EXIT} R2?02060H{PRINT=("ID = %04lX - PIC16F886",R1),EXIT} R2?02080H{PRINT=("ID = %04lX - PIC16F888",R1),EXIT} PRINT=("ID = %04lX",R1) [END] MCLR=0 VPP=0 CLK=0,SDA=0