; Orange programmer module v4.3 ; (c) 2000-2015 CnCLab ;CHIP=PIC16F526,1023x12,P16F526.hpl ;AREA=CODE,1023x12,0 ;AREA=DATA,64,0x400,0x800,b ;AREA=USER_ID,4x12,0x440,0x880 ;AREA=CONFIG,1x12,0x7FF,0x1FFE ; based on PIC16F505.HPL ;Orange3,4,5,SE ;primary tested ; OSCALL вынесен из общего адресного пространства ; Для изменения использовать команду Erase ; Запоминать и восстанавливать значение 3FF & 444 ; Начальная область не закрывается битом CP!!! OPTIONS=f, ALLPINS=14 INFO="PIC Adapter" PING=SDA,1,13 ;RB0 PINO=CLK,0,12 ;RB1 PINO=MCLR,5,4 ;/MCLR PINO=VDD,254,1 ;Vdd PING=GND,255,14 ;Vss CDELAY=2 R1=CONFIG,H R10=FOSC,L,000:LP,001:XT,010:HS,011:EC,100:INOSC-RB4,101:INOSC-CLKOUT,110:EXTRC-RB4,111:EXTRC-CLKOUT R11=WDTE,L,0:Off,1:On R12=CP,L,0:On,1:Off R13=MCLRE,L,0:RB3,1:MCLR R14=IOSCFS,L,0:4MHz,1:8MHz R15=CPDF,L,0:On,1:Off R16=OSCCAL1,H3 ;0x444 R17=OSCCAL2,H3 R18=OSCCAL3,H3 R19=OSCCAL4,H3 R1E=OSCCAL,H3 ;0x3FF ;R1F=Erase,L,Cancel,Code,All ;R18 - ID ;R8 use for store address [_PULSE] CLK=1,P=2,CLK=0,P=2 [_COMMAND] ; R0 - CMD P=1 LOOP=(0,5){SDA=R0[I],CLK=P} 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 ;Read data to R1 [_RD1] _COMMAND(4) ;RDPROG _INWORD [_INCADD] R8=ADR LOOP=(0x800){ ;increment address to current value! R9?R8{BREAK} _COMMAND(6) ;INCADD R9=+1 } [!#SETUP] $WDELAY=5000 [_INIT] VCC=1 CLK=0,SDA=0 $VERSION=/65536 ;PRINT=("%u",$VERSION) MCLR=0,CLK=0,SDA=0 $VERSION?3{ PRINT=S("Power up...") P=600000 ;charge Vpp cap! } ;VCC=0 P=50000 VPP=12000,P=10 ;O4! MCLR=1 ;Vcc pulse for re-enter prg mode ;Programm/Verify Mode! P=200000 PRINT=S(" ") [INIT] ;PRINT=L("init...\n") _INIT R9=0 ;current address register $AREA?0{ ;code _COMMAND(6) ;INCADD ;goto 0 address! } $AREA?1{ ;DATA _COMMAND(6) ;INCADD ;goto 0 address! PRINT=L("GOTO %03X",RC); LOOP(RC){_COMMAND(6)} ;INCADD 400h } $AREA?2{ ;ID _COMMAND(6) ;INCADD ;goto 0 address! PRINT=L("GOTO %03X",RC); LOOP(RC){_COMMAND(6)} ;INCADD 440h } ;-------------------------------------------------------- ;------------------------------------------------- [_FUSE2BIT] ; unpack config word ; 7 6 5 4 3 2 1 0 ; CPDF IOSCFS MCLRE CP WDTE FOSC2 FOSC1 FOSC0 R10=0,R11=0,R12=0,R13=0,R14=0,R15=0 R10[0]=R1[0],R10[1]=R1[1],R10[2]=R1[2] ;FOSC R11[0]=R1[3] ;WDTE R12[0]=R1[4] ;CP R13[0]=R1[5] ;MCLRE R14[0]=R1[6] ;IOSCFS R15[0]=R1[7] ;CPDF [_BIT2FUSE] ;copy separate bits to config word R1=0xFFF R1[0]=R10[0],R1[1]=R10[1],R1[2]=R10[2] ;FOSC R1[3]=R11[0] ;WDTE R1[4]=R12[0] ;CP R1[5]=R13[0] ;MCLRE R1[6]=R14[0] ;IOSCFS R1[7]=R15[0] ;CPDF [_READFUSES] ; только после входа! _RD1 ;PRINT=("Configuration Word = %04lX",R1) ;copy config world to separate bits ADR=0 DATA=R1 [_WRITEFUSES] ; только сразу после входа! ADR=0 R1=DATA R1=|0x0F00 ;! _COMMAND(2) ;LDPROG _OUTWORD(R1) ;config _COMMAND(8) ;BEGPRG P=20000 _COMMAND(0xE) ;ENDPRG ; check? _COMMAND(4) ;RDPROG R2=R1 _INWORD R1=&0xFF R2=&0xFF R1?!R2{PRINT=("Write error! [%04lX]",R1)} ;-------------------------------------------------------- [READ] _INCADD _COMMAND(4) ;RDPROG _INWORD DATA=R1 [WRITE] $AREA?3{_WRITEFUSES,EXIT} R0=DATA,R0=&0x0FFF,R0?0x0FFF{RETURN} ;не пишем пустые во FLASH для ускорения _INCADD _COMMAND(2) ;LDPROG _OUTWORD(DATA) _COMMAND(0x8) ;BEGPRG P=$WDELAY _COMMAND(0xE) ;ENDPRG [~!#Config Editor"] $AREA=3 ;FUSES R1=DATA _FUSE2BIT GET=("Edit Fuses",R10,R11,R12,R13,R14,R15) RA?0{EXIT} _BIT2FUSE DATA=R1 ;Read backup OSCCAL locations, 0x444-0x447 [_RDBACKOSC] _RD1 ;RDPROG Backup OSCCAL1 R16=R1 _COMMAND(6) ;INCADD _RD1 ;RDPROG Backup OSCCAL2 R17=R1 _COMMAND(6) ;INCADD _RD1 ;RDPROG Backup OSCCAL3 R18=R1 _COMMAND(6) ;INCADD _RD1 ;RDPROG Backup OSCCAL4 R19=R1 ["~Read Calibration"] $AREA?!0{PRINT=E("Select CODE Area first!"),EXIT} ; OSCCAL: _INIT R9=0 ;current address register _COMMAND(6) ;goto 0000 ADR=0 LOOP=(0x444){_COMMAND(6)} ;INCADD goto _RDBACKOSC MCLR=0,VPP=0,P=5000 CLK=0,SDA=0 GET=("OSCALL",R16,R17,R18,R19) ;---------------------------------------------------------------------- ;Перед стиранием кристалла необходимо запомнить: ;Read and save 0x3FF oscillator calibration ;bits and 0x404 backup OSCCAL bits ;into computer/programmer temporary memory. ;---------------------------------------------------------------------- [~Erase] $AREA?!0{PRINT=E("Select CODE Area first!"),EXIT} _INIT R9=0 ;current address register PRINT=S("Erase...") ; Save OSCCAL: ADR=0 LOOP=(0x400){_COMMAND(6)} ;INCADD goto 0x3FF _COMMAND(4) ;RDPROG _INWORD R1E=R1 LOOP=(0x45){_COMMAND(6)} ;INCADD - goto 0x444 _RDBACKOSC PRINT=L("OSCCAL = %03lX\n",R1E) PRINT=L("BACKOSC = %03lX %03lX %03lX %03lX\n",R16,R17,R18,R19) ADR=0x400 R16?!0xFFF{DATA=R16} VPP=0,MCLR=0,P=100,VCC=0,P=100000 ;power off _INIT ADR=0 ;PC=config, _COMMAND(9) ;Bulk Erase (Fuses,Code) P=40000 ;Pc to 0x400 LOOP(0x401){_COMMAND(6)} ;goto DATA _COMMAND(9) ;Bulk Erase (Data) P=40000 ;Pc to 0x440 LOOP(0x40){_COMMAND(6)} ;goto Configuration Memory _COMMAND(9) ;Bulk Erase (USER ID) P=40000 ;RETURN ; Restore OSCALL : GET=("Restore OSCALL value ?",R1E,R16,R17,R18,R19) RA?0{ ;no erase OSCALL RETURN } VPP=0,MCLR=0,P=100,VCC=0,P=100000 ;power off _INIT ADR=0 _COMMAND(6) ;goto 0 LOOP=($SIZE){ ;Goto 0x3FF _COMMAND(6) ;INCADD } _COMMAND(2) ;LDPROG _OUTWORD(R1E) _COMMAND(8) ;BEGPRG P=50000 _COMMAND(0xE) ;ENDPRG LOOP(0x45){ ;Goto 0x444 _COMMAND(6) ;INCADD } _COMMAND(2) ;LDPROG _OUTWORD (R16) _COMMAND(8) ;BEGPRG P=50000 _COMMAND(0xE) ;ENDPRG _COMMAND(6) ;INCADD _COMMAND(2) ;LDPROG _OUTWORD (R17) _COMMAND(8) ;BEGPRG P=50000 _COMMAND(0xE) ;ENDPRG _COMMAND(6) ;INCADD _COMMAND(2) ;LDPROG _OUTWORD (R18) _COMMAND(8) ;BEGPRG P=50000 _COMMAND(0xE) ;ENDPRG _COMMAND(6) ;INCADD _COMMAND(2) ;LDPROG _OUTWORD (R19) _COMMAND(8) ;BEGPRG P=50000 _COMMAND(0xE) ;ENDPRG [END] MCLR=0,VPP=0,P=5000 CLK=0,SDA=0,VCC=0,P=10000 ;PRINT=("END")