; Orange programmer module v1.9
; (c) 2011 CnCLab

; GROUP=Spansion
; CHIP=S25FL128,16384K(256),S25FL128.HPL
; VCC=3250

;Status Register:    7   6   5   4   3   2   1   0
;                  SRWD  X   X  BP2  BP1 BP0 WEL WIP
;					    r/o r/o

; Write  & Erase not tested
; parallel mode not supported

INFO="For SO16 - Special adapter!"

;      WSON8   SO16
;CS      1      7
;SO      2      8
;WP      3      9
;GND     4     10
;SI      5     15
;SCK     6     16
;HOLD    7      1
;VCC     8      2



SOCKET=4 ;"SPI"
OPTIONS=f

PINO=SCK,0
PINO=SI,1
PINO=CS,2
PINO=WP,3
PINO=HOLD,4
PINI=SO,1

CDELAY=0 ; one set delay 

R9=STATUS,C8,SRWD,x,x,BP2,BP1,BP0,WEL,WIP
R10=ADDRESS,H

[!#SETUP]
R9=0
R10=0

[INIT]
HOLD=1
WP=0
CS=1
SCK=0

[_SENDBYTE]
LOOP=(7,0){SI=R0[I],SCK=P}

[READ]
CS=0
R0=00000011b,_SENDBYTE     ;Read
LOOP=(23,0){SI=ADR[I],SCK=P}
SI=1
LOOP=(7,0){SCK=1,DATA[I]=SO,SCK=0}
CS=1
P=1


[READBLOCK]
CS=0
_SENDBYTE(00000011b)     ;Read
LOOP=(23,0){SI=ADR[I],SCK=P}
SI=1
LOOP=($BLOCKSIZE){
LOOP=(7,0){SCK=1,DATA[I]=SO,SCK=0}
ADR=+1
}
CS=1

;return R1
[_RDSR]
SCK=0
CS=0
_SENDBYTE(00000101b)     ;RDSR
SI=1
R1=0
LOOP=(7,0){SCK=1,R1[I]=SO,SCK=0}
CS=1


[_WAITWR]	;Wait for end write memory...
SCK=0
CS=1
LOOP=(0,12000){
_RDSR
R1[0]?0{BREAK}   ;WIP bit
P=10
}

[_WREN]
SCK=0
CS=0
_SENDBYTE(00000110b)   ; Write enable
CS=1


[_WRSR]
R1=R0
SCK=0
_WREN
CS=0
_SENDBYTE(00000001b)     ;WRSR 
_SENDBYTE(R1)		 ;Status Register
CS=1
P=50000		;max 150 ms!
_WAITWR


[WRITEINIT]
HOLD=1
WP=1
CS=1
P=2000
_WRSR(0)	;clear


[WRITE]
CS=1
SCK=0
_WREN
CS=0
_SENDBYTE(00000010b)   ; Write
LOOP=(23,0){SI=ADR[I],SCK=P}
LOOP=(7,0){SI=DATA[I],SCK=P}
SI=1,CS=1
;P=5000
_WAITWR

[WRITEBLOCK]
SCK=0
_WREN
CS=0
_SENDBYTE(00000010b)   ; Write
LOOP=(23,0){SI=ADR[I],SCK=P}
LOOP=($BLOCKSIZE){
LOOP=(7,0){SI=DATA[I],SCK=P}
ADR=+1
}
CS=1
_WAITWR


[READID]
WP=1
SCK=0
CS=1
CS=0
R7=0
;1010 1011 ABh Read Manufacturer and Product ID

_SENDBYTE(0x9F)	 ;RID
SI=1
LOOP=(23,0){SCK=1,R7[I]=SO,SCK=0}
CS=1
PRINT=S("ID value = %06lXH",R7)
P=50000
R0=R7


[ReadStatus]
;HOLD=1
WP=1
SCK=0
CS=1
R9=0
_RDSR
R9=R1
P=10000
GET=("Status",R9)

[WriteStatus]
GET=("Write Status",R9)
RA?0{EXIT}
WP=1
CS=1
SCK=0
;PRINT=("value %02lX",R9)
_WRSR(R9)
P=200000 ;Write Status Register Time 67... 150 ms

[Erase]
PRINT=S("Erase...")
HOLD=1
WP=1
SCK=0
_WRSR(0)	;clear

_WREN
CS=0
R0=11000111b		;BE Bulk Erase 0xC7
_SENDBYTE
CS=1

; Full erase time: 
; m25p20     - 4 sec
; S25FL016A   10..96 sec

SCK=0
R3=0
PRINT=P(0,20000)
LOOP=(0,20000){ ;100 sec
CS=0
R0=00000101b,_SENDBYTE     ;RDSR
SI=1
R9=0
LOOP=(7,0){SCK=1,R9[I]=SO,SCK=0}
CS=1
R9[0]?0{BREAK}   ;WIP bit
P=5000
R3=+1
PRINT=P(R3)
}


[EraseSector]
GET=("Sector Address",R10)
RA?0{EXIT}
HOLD=1
WP=1
SCK=0

_WRSR(0)

_WREN
CS=0
_SENDBYTE(0xD8)		;BE sec Erase
LOOP=(23,0){SI=R10[I],SCK=P}
CS=1
P=100000

; Full erase time - 4 sec!
_WAITWR
SCK=0
R2=0
PRINT=P(0,5000)
LOOP=(0,5000){
CS=0
PRINT=P(R2)
R2=+1
_RDSR
R1[0]?0{BREAK}   ;RDY bit
P=1000
}

R1[0]?1{PRINT=E("Erase timeout error!")}