; Orange programmer module v3.9
; (c) 2000-2015 CnCLab

;CHIP=PIC16F684,2Kx14,P16F690.HPL
;AREA=CODE,2Kx14,0,0
;AREA=DATA,256,0,0x4200,b
;AREA=USER_ID,4x14,0,0x4000
;AREA=CONFIG,1x14,0,0x400E,m


;CHIP=PIC16F688,4Kx14,P16F690.HPL
;AREA=CODE,4Kx14,0,0
;AREA=DATA,256,0,0x4200,b
;AREA=USER_ID,4x14,0,0x4000
;AREA=CONFIG,1x14,0,0x400E,m


; Microchip 41204.pdf PIC12F6XX/16F6XX Memory Programming Specification:
; PIC12F635  PIC16F684
; PIC12F683  PIC16F685
; PIC16F631  PIC16F687
; PIC16F636  PIC16F688
; PIC16F639  PIC16F689
; PIC16F677  PIC16F690

; Primary Tested PIC12F683,PIC16F690
; Orange3,4,5,SE

ALLPINS=14
INFO="PIC Adapter"

PING=SDA,1,13 ;GP0
PINO=CLK,0,12 ;GP1
PINO=MCLR,5,4 ;/MCLR
PINO=VDD,254,1  ;Vdd
PING=GND,255,14 ;Vss

CDELAY=2
OPTIONS=f,

R1=CONFIG,H
R6=Erase,L,None,Code,Code+Calibr+ID,Data
R10=FOSC,L,000:LP,001:XT,010:HS,011:EC(GP4-IO),100:intOSCIO,101:intOSC,110:extRCIO,111:extRC
R11=WDTE,L,0:On,1:Off
R12=PWRTE,L,0:On,1:Off
R13=MCLRE,L,0:Off,1:On
R14=CP,L,0:Code Protect,1:Off
R15=CPD,L,0:Data Protect,1:Off
R16=BOREN,L,00,01,10,11
R17=IESO,L,0:Off,1:On
R18=FCMEN,L,0:Off,1:On
R19=WURE,L,0:Reset,1:Standard

;R19 - ID
R1A=CALIBR,H4
;R1B=OSCCAL,H4

;R8 use for store address


[_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

[_INWORD]
R1=0
SDA=1,_PULSE
LOOP=(0,13){_PULSE,R1[I]=SDA}
SDA=1,_PULSE


[_INCADD]
R8=ADR
LOOP=(0,0xFFFF){  ;increment address to current value!
R9?R8{BREAK}
_COMMAND(6) ;INCADD
R9=+1
}

[!#SETUP]
R6=0

[INIT]
VPP=0,MCLR=0,CLK=0,SDA=0
$VERSION=/65536
;PRINT=("%u",$VERSION)
MCLR=0
$VERSION?3{
PRINT=S("Power up...")
P=600000  	;charge Vpp cap!
}
;CLK=0,SDA=0
IDISABLE
VCC=0
P=90000
VPP=12500,P=10	       ;O4!
MCLR=1,VCC=1           ;Vcc pulse for re-enter prg mode
                       ;Programm/Verify Mode!
P=160000
IENABLE

PRINT=S(" ")

R9=0 ;current address register
R7=0 ;


;--------------------------------------------------------

[_FUSE2BIT]
; unpack config word
;13  12    11   10     9      8    7  6    5     4     3    2     1     0
; - WURE FCMEN IESO BOREN1 BOREN0 CPD CP MCLRE PWRTE WDTE FOSC2 F0SC1 F0SC0


R10=0,R11=0,R12=0,R13=0,R14=0,R15=0,R16=0,R17=0,R18=0

R10[0]=R1[0]    ;FOSC0
R10[1]=R1[1]    ;FOSC1
R10[2]=R1[2]	;FOSC2
R11[0]=R1[3]	;WDTE
R12[0]=R1[4]	;PWRTE
R13[0]=R1[5]	;MCLRE
R14[0]=R1[6]	;CP
R15[0]=R1[7]	;CPD
R16[0]=R1[8]	;BOREN0
R16[1]=R1[9]	;BOREN1
R17[0]=R1[10]	;IESO
R18[0]=R1[11]	;FCMEN
R19[0]=R1[12]	;WURE


[_BIT2FUSE]
;copy separate bits to config word
R1=0x3FFF	; Unimplemented bit, read as '1'
R1[0]=R10[0]    ;FOSC0
R1[1]=R10[1]    ;FOSC1
R1[2]=R10[2]	;FOSC2
R1[3]=R11[0]	;WDTE
R1[4]=R12[0]	;PWRTE
R1[5]=R13[0]	;MCLRE
R1[6]=R14[0]	;CP
R1[7]=R15[0]	;CPD
R1[8]=R16[0]	;BOREN0
R1[9]=R16[1]	;BOREN1
R1[10]=R17[0]	;IESO
R1[11]=R18[0]	;FCMEN
R1[12]=R19[0]	;WURE

;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
_INWORD
;PRINT=("Configuration Word = %04lX",R1)
;copy config world to separate bits

ADR=0
DATA=R1
;_FUSE2BIT
;RE?!2{
;GET=("Fuses Read",R10,R11,R12,R13,R14,R15,R16,R17,R18)
;}


[_WRITEFUSES]
ADR=0
R1=DATA
;_FUSE2BIT
;GET=("Write Fuses",R10,R11,R12,R13,R14,R15,R16,R17,R18)
;RA?0{EXIT}
;_BIT2FUSE	;copy separate bits to config world
;DATA=R1

;ADR=0
_COMMAND(0) ;LDCONF
_OUTWORD(0x3FFF)	; dummy data

LOOP=(0,6){ 		; goto adr 0x2007
_COMMAND(6) 		;INCADD
}

_COMMAND(2) 		;LDPROG
_OUTWORD(R1)		;config
_COMMAND(8) 		;BEGPRG int. timed.
P=12000

; check?
_COMMAND(4) ;RDPROG
R2=R1
_INWORD
R1?!R2{PRINT=("Write error! [%04lX]",R1)}

;--------------------------------------------------------



[READ]
$AREA?<2{  ;code,data
_INCADD
}

$AREA?>1{  ;USERID,CONFIG
_COMMAND(0) 		;LDCONF
_OUTWORD(0x3FFF)	; dummy

$AREA?2{R1=ADR} ;USERID
$AREA?3{R1=7}   ;CONFIG

R1?!0{
LOOP(R1){_COMMAND(6)} ;INCADD to 2000...2007h
}
}


R0=4          	;RDPROG
$AREA?1{R0=5}   ;RDDATA
_COMMAND

_INWORD
DATA=R1


[_WRITE]
$AREA?0{R0=DATA,R0=&0x3FFF,R0?0x3FFF{RETURN}}      ;не пишем пустые во FLASH для ускорения
$AREA?2{_WRITEFUSES,EXIT}

_INCADD
$AREA?1{_COMMAND(3)}    ;LDDATA
$AREA?0{_COMMAND(2)}	;LDPROG


_OUTWORD(DATA)
_COMMAND(0x08) ;BEGPRG Internally Timed

P=4000 ;<3ms
$AREA?1{P=3000} ;EEPROM <6ms


[WRITE]
$AREA?<2{
$AREA?0{
R3=DATA,R3=&0x3FFF,R3?0x3FFF{RETURN} ; skip empty code word
}
_INCADD
}

$AREA?>1{
_COMMAND(0) 		;LDCONF
_OUTWORD(0x3FFF)	; dummy

$AREA?2{R1=ADR} ;USERID
$AREA?3{R1=7}   ;CONFIG

R1?!0{
LOOP(R1){_COMMAND(6)} ;INCADD to 2000...2007h
}
}

R0=2             ;LDPROG
$AREA?1{R0=3}    ;LDDATA
_COMMAND

_OUTWORD(DATA)
_COMMAND(0x08) ;BEGPRG Internally Timed

P=4000 ;<3ms
$AREA?1{P=3000} ;EEPROM <6ms



[~!#"Fuse Editor"]
$AREA=3	;FUSES
R1=DATA
_FUSE2BIT
GET=("Edit Fuses",R10,R11,R12,R13,R14,R15,R16,R17,R18)
RA?0{EXIT}
_BIT2FUSE
DATA=R1


[Erase]
GET=("Erase mode",R6)
RA?0{EXIT}
;R6=Erase,L,None,Code,Code+Calibr,Data
R6?0{EXIT}

R6?1{
_COMMAND(9) ;Code Bulk Erase
}

R6?2{	;Code+Calibr
_COMMAND(0) ;LDCONF
_OUTWORD(03FFFH)
R0=6,LOOP=(8){_COMMAND} ;INCADD
_COMMAND(9) ;Bulk Erase
}

R6?3{   ;Bulk Erase DATA
_COMMAND(0) ;LDCONF
_OUTWORD(03FFFH)
R0=6,LOOP=(0,6){_COMMAND} ;INCADD
_COMMAND(0xB) ;Bulk Erase DATA
}

P=50000

PRINT=S("Erase finished")
P=350000

["Read Calibration"]
_COMMAND(0) ;LDCONF
_OUTWORD(0x3FFF)	; dummy
ADR=0

LOOP=(0,7){ 		; goto adr 0x2005
_COMMAND(4) 		;RDPROG
_INWORD                 ;dummy read - обязательно...
ADR=+1
_INCADD
}

_COMMAND(4) ;RDPROG           ;2006
_INWORD
R1A=R1

GET=("Read Calibration",R1A)



[_READID]
_COMMAND(0) ;LDCONF
_OUTWORD(0x3FFF)	; dummy
ADR=0

LOOP=(0,5){ 		; goto adr 0x2005
_COMMAND(4) 		;RDPROG
_INWORD                 ;dummy read - обязательно...
ADR=+1
_INCADD
}

_COMMAND(4) ;RDPROG           ;2006
_INWORD
R19=R1

["Read ID"]
_READID
R1=R19,R1=/32,R1=&01FFH
R1?001111101B{PRINT=("PIC12F635\nID=%04lX",R19),EXIT}
R1?000100011B{PRINT=("PIC12F683\nID=%04lX",R19),EXIT}
R1?010100001B{PRINT=("PIC16F631\nID=%04lX",R19),EXIT}
R1?010000101B{PRINT=("PIC16F636,639\nID=%04lX",R19),EXIT}  ;?????
R1?010100010B{PRINT=("PIC16F677\nID=%04lX",R19),EXIT}
R1?010000100B{PRINT=("PIC16F684\nID=%04lX",R19),EXIT}
R1?000100101B{PRINT=("PIC16F685\nID=%04lX",R19),EXIT}
R1?000110001B{PRINT=("PIC16F687\nID=%04lX",R19),EXIT}
R1?010001100B{PRINT=("PIC16F688\nID=%04lX",R19),EXIT}
R1?010011010B{PRINT=("PIC16F689\nID=%04lX",R19),EXIT}
R1?010100000B{PRINT=("PIC16F690\nID=%04lX",R19),EXIT}
PRINT=("ID=%04lX",R19)

[END]
MCLR=0,VPP=0,CLK=0,SDA=0,P=100