; Orange programmer module v4.1 ; (c) 2000-2014 CnCLab, Pavel ;CHIP=PIC16F913,4Kx14,P16F917.hpl ;AREA=CODE,4Kx14,0,0 ;AREA=DATA,256,0,0x4200,b ;AREA=CONFIG,1x14,0,0x400E,m ;CHIP=PIC16F914,4Kx14,P16F917.hpl ;AREA=CODE,4Kx14,0,0 ;AREA=DATA,256,0,0x4200,b ;AREA=CONFIG,1x14,0,0x400E,m ;CHIP=PIC16F916,8Kx14,P16F917.hpl ;AREA=CODE,8Kx14,0,0 ;AREA=DATA,256,0,0x4200,b ;AREA=CONFIG,1x14,0,0x400E,m ;CHIP=PIC16F917,8Kx14,P16F917.hpl ;AREA=CODE,8Kx14,0,0 ;AREA=DATA,256,0,0x4200,b ;AREA=CONFIG,1x14,0,0x400E,m ;CHIP=PIC16F946,8Kx14,P16F917.hpl ;AREA=CODE,8Kx14,0,0 ;AREA=DATA,256,0,0x4200,b ;AREA=CONFIG,1x14,0,0x400E,m ; 41244F.pdf PIC16F91X/946 Memory Programming Specification for ; PIC16F913 PIC16F914 PIC16F946 PIC16F916 PIC16F917 ;device can be erased without affecting the Calibration Word. ;This simplifies the erase procedure, for these values do not need ;to be read and restored after the device is erased ; Primary Tested: PIC16F913 ; todo: EIGHT-WORD PROGRAMMING for speed-up ALLPINS=40 INFO="PIC Adapter" OPTIONS=f, ; PING=SDA,1,40 ;RB7 PINO=CLK,0,39 ;RB6 PINO=MCLR,5,1 ;/MCLR PING=GND,255,12 ;Vss PING=GND2,255,31 ;Vss PINO=VDD,254,11 PINO=VDD2,254,32 CDELAY=2 R1=CONFIG,H R1A=Erase,L,Off,Code,Data,All R1B=CALIB1,H4 R1C=CALIB2,H4 R10=DEBUG,L,On,Off R11=FCMEN,L,Off,On R12=IESO,L,Off,On R13=BOREN,L,00:Off,01:SBOREN,10:OnNoSleep,11:On R14=CPD,L,On,Off R15=CP,L,On,Off R16=MCLRE,L,0:RB3-Input,1:RB3-MCLR R17=PWRTE,L,On,Off R18=WDTE,L,Off,On R19=FOSC,L,000:LP,001:XT,010:HS,011:EC(RA6-IO),100:intOSCIO,101:intOSC,110:RCIO,111:RC [!#SETUP] $WDELAY=5000 [_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 [_INWORD] R1=0 SDA=1,_PULSE LOOP=(0,13){_PULSE,R1[I]=SDA} SDA=1,_PULSE [_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 } [INIT] VPP=0 MCLR=0,CLK=1,SDA=1 PRINT=S("Power up...") $VERSION=/65536 $VERSION?3{ 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=1000 SDA=1 P=100000 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 ; - DEBUG FCMEN IESO BOREN1 BOREN0 CPD CP MCLRE PWRTE WDTE F0SC2 F0SC1 F0SC0 R10=0,R11=0,R12=0,R13=0,R14=0,R15=0,R16=0,R17=0,R18=0,R19=0 R19[0]=R1[0],R19[1]=R1[1],R19[2]=R1[2] ;FOSC R18[0]=R1[3] ;WDTE R17[0]=R1[4] ;PWRTE R16[0]=R1[5] ;MCLRE R15[0]=R1[6] ;CP R14[0]=R1[7] ;CPD R13[0]=R1[8],R13[1]=R1[9] ;BOREN R12[0]=R1[10] ;IESO R11[0]=R1[11] ;FCMEN R10[0]=R1[12] ;DEBUG [_BIT2FUSE] ;copy separate bits to config word R1=0x3FFF R1[0]=R19[0],R1[1]=R19[1],R1[2]=R19[2] ;FOSC R1[3]=R18[0] ;WDTE R1[4]=R17[0] ;PWRTE R1[5]=R16[0] ;MCLRE R1[6]=R15[0] ;CP R1[7]=R14[0] ;CPD R1[8]=R13[0],R1[9]=R13[1] ;BOREN R1[10]=R12[0] ;IESO R1[11]=R11[0] ;FCMEN R1[12]=R10[0] ;DEBUG [_READFUSES] _COMMAND(0) ;LDCONF _OUTWORD(0x3FFF) ; dummy!!! ADR=0 LOOP=(0,6){ ; goto adr 0x2007 _COMMAND(6) ;INCADD } _COMMAND(4) ;RDPROG _INWORD ;PRINT=("Configuration Word = %04lX",R1) DATA=R1 ;_FUSE2BIT [_WRITEFUSES] ADR=0 R1=DATA ;PRINT=S("Write Config:%04lX",R1) ADR=0 _COMMAND(0) ;LDCONF _OUTWORD(0x3FFF) ;dummy LOOP=(0,6){ ; goto adr 0x2007 _COMMAND(6) ;INCADD } ;R1=DATA _COMMAND(2) ;LDPROG _OUTWORD(R1) ;config _COMMAND(0x08) ;BEGPRG P=12000 ; check? _COMMAND(4) ;RDPROG R2=R1 _INWORD R1?!R2{PRINT=("Write error! [%04lX]",R1)} [_RDCALIB] _COMMAND(0) ;LDCONF _OUTWORD(0x3FFF) ; dummy ADR=0 LOOP=(0,7){ ; goto adr 0x2008 _COMMAND(4) ;RDPROG _INWORD ;dummy read - ®¡ï§ â¥«ì­®... ADR=+1 _INCADD } _COMMAND(4) ;RDPROG ;2008 _INWORD R1B=R1 _COMMAND(6) ;INCADD _COMMAND(4) ;RDPROG ;2009 _INWORD R1C=R1 ;------------------------------------------------- [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 òîëüêî ÷åðåç ðåãèñòð! [WRITE] $AREA?2{_WRITEFUSES,RETURN} _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(0x08) ;BEGPRG P=$WDELAY $AREA?!0{P=$WDELAY} ; Program memory faster [~!#"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 R0=0xB,_COMMAND ;Bulk Erase Data ;R0=8,_COMMAND ;begin P=50000 [Erase] ;R1A=Erase,L,Off,Code,Data,All GET=("Erase",R1A) RA?0{EXIT} R1A?0{EXIT} ;Off _COMMAND(0) ;LDCONF _OUTWORD(03FFFH) R1A?1{_EraseCode} ;Code R1A?2{_EraseData} ;Data R1A?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,CLK=0,SDA=0,VCC=0 R2=&3FF0H ;id mask R2=>>4 R2?0138H{PRINT=("ID = %04lX - PIC16F917",R1),EXIT} R2?013AH{PRINT=("ID = %04lX - PIC16F916",R1),EXIT} R2?013CH{PRINT=("ID = %04lX - PIC16F914",R1),EXIT} R2?013EH{PRINT=("ID = %04lX - PIC16F913",R1),EXIT} R2?0146H{PRINT=("ID = %04lX - PIC16F946",R1),EXIT} PRINT=("ID = %04lX",R1) ["Read Calibration"] _RDCALIB GET=("Read Calibration",R1B,R1C) [END] MCLR=0 VPP=0 CLK=0,SDA=0