; Orange programmer module v1.12  for Orange4/5
; (c) 2009-2011 CnCLab
; Samsung NAND Flash Memory 5bytes addr.

; CHIP=K9F2G08 ECC,528K(2112),K9K4G08PE.HP4
; VCC=3250                             
; CHIP=K9K4G08 ECC,528K(2112),K9K4G08PE.HP4
; VCC=3250                             
; CHIP=K9LAG08 ECC,528K(2112),k9k4g08PE.HP4
; VCC=3250
; CHIP=K9W8G08 ECC,528K(2112),K9K4G08PE.HP4
; VCC=3250

; Primary tested 
; page read and write
;K9F2G08  256MB page=512K pages=512    +
;K9K4G08  512MB page=512K pages=1024
;K9LAG08 2048MB page=512K pages=4096
;K9W8G08 1024MB page=512K pages=2048


INFO="NAND FLASH Adapter"

SOCKET=0

ALLPINS=48

;Input pins:
PINI=P0,0,29
PINI=P1,1,30
PINI=P2,2,31
PINI=P3,3,32
PINI=P4,4,41
PINI=P5,5,42
PINI=P6,6,43
PINI=P7,7,44

;Output pins:
PINO=CLE,8,16	;	Command Latch Enable    
PINO=ALE,9,17	;	Address Latch Enable    
PINO=CE,10,9	;	Chip Enable             
PINO=RDE,11,8	;	Read Enable             
PINO=WE,12,18	;	Write Enable            

BUSO=DATAO,0
BUSI=DATAI,0

;Power pins:
PINO=Vcc1,254,23	;           +5V
PINO=Vcc2,254,44	;           +5V
PINO=GND,255,40	;           GND
PINO=Vss1,255,1	;           GND
PINO=Vss2,255,22	;           GND

CDELAY=1
BUSO=PULLUP,255
R10=PAGE,H
R12=Erase,L,Cancel,Erase

[!#SETUP]
R10=0

[INIT]
DATAO=Z
CE=1,RDE=1,WE=1
ALE=0
CLE=0
;PULLUP=1
P=10


;+ECC
[_SENDADRB]
CLE=0,ALE=1
DATAO=0				;ADR A0-A7
WE=N
DATAO=0				;ADR A8-A15
;R0=/256,R0=&0x7,DATAO=R0	;ADR A8-A15
WE=N
R0=ADR
R0=/$BLOCKSIZE,DATAO=R0	;ADR A12-A19...
WE=N
DATAO=R10			;ADR A20...A27 page!
WE=N
R0=R10,R0=/256
DATAO=R0			;ADR A28...A29 page!
WE=N
ALE=0




[_CMD]
ALE=0
CLE=1
DATAO=R0		;cmd 
WE=0
WE=1
CLE=0


[_RDSTAT]
RDE=1,CE=0
_CMD(70h)			;cmd
ALE=1
DATAO=Z ; HiZ state
P=15
ALE=0,RDE=0
P=15
R0=DATAI
RDE=1
CE=1

[_READ]
RDE=1,CE=0
_CMD(0x00)			;cmd rd
_SENDADRB
_CMD(0x30)		;cmd rd2
DATAO=Z ; HiZ state
R0=DATAI
P=25
ALE=0,RDE=0
R0=DATAI
DATA=R0
RDE=1,CE=1

[READBLOCK]
RDE=1,CE=0
_CMD(0x00)	    ;cmd rd
_SENDADRB
_CMD(0x30)	    ;cmd rd2
DATAO=Z,R0=DATAI ; HiZ state

P=25
LOOP($BLOCKSIZE){
RDE=0
R0=DATAI
DATA=R0
RDE=1
ADR=+1
}
CE=1
CE=0
_CMD(0xFF)	;rst
CE=1

[WRITEINIT]
;WP=1
P=20

[WRITEBLOCK]
RDE=1,CE=0

_CMD(0x80)			;cmd
_SENDADRB
ALE=0
LOOP($BLOCKSIZE){
R0=DATA
DATAO=R0
WE=N
ADR=+1
}


_CMD(0x10)			;cmd program
;P=500
;CE=1
P=10
;_RDSTAT
;PRINT=S("Status0=%02lX",R0)

CLE=0
LOOP=(1000){
_RDSTAT
PRINT=S("Write Status=%02lX",R0)
R0=&0x40	;busy bit
R0?!0{BREAK}
P=10
}
R0?0{PRINT=("Page write error!")}
;_RDSTAT
;PRINT=S("Status=%02lX",R0)


[READID]
RDE=1,CE=0,CLE=1,ALE=0
DATAO=90h			;cmd
WE=N
ALE=1,CLE=0
DATAO=0			;ADR A0-A7
WE=N
DATAO=Z ; HiZ state
ALE=0
P=15
RDE=0,P=15
R0=DATAI    ;1
RDE=1,P=15
RDE=0,P=15
R1=DATAI    ;2
RDE=1,P=15
RDE=0,P=15
R2=DATAI    ;3
RDE=1,P=15
RDE=0,P=15
R3=DATAI    ;4
RDE=1

CE=1
PRINT=S("ID=%02lX %02lX %02lX %02lX",R0,R1,R2,R3)
R0=<<8,R0=|R1

R5=R0
_RDSTAT
PRINT=L("Status=%02lX",R0)
R0=R5

["Erase Page"] 
R12=0
GET=("Erase Page",R12)
RA?0{EXIT}
R12?0{EXIT}
;WP=1
R13=$SIZE
RB?0{RB=2112}
R13=/RB

R11=0
PRINT=P(R11,R13)
LOOP=(R13){
PRINT=S("Erase %u",R11)
PRINT=P(R11)

RDE=1,CE=0
_CMD(0x60)			;cmd

ALE=1
DATAO=R11		        ;ADR A12
WE=N

DATAO=R10			;ADR A20...A27 page!
WE=N

R0=R10,R0=/256
DATAO=R0			;ADR A28...A29 page!
WE=N

ALE=0

_CMD(0xD0)			;cmd program
CE=1
P=3000   ;                    Block Erase Time 3 ms max
R11=+1
}



[~!#"Set Page"]
GET=("Set Page",R10)
;R10=&0x1FFF