; Orange programmer module v2.5 FASTSPI
; (c) 2006-2015 CnCLab

;CHIP=AT25DF161,2048K(256),at25df161.hpl 
;AREA=FLASH,2048K(256)
;AREA=OTP,128
;VCC=3250

;CHIP=AT25DF321,4096K(256),at25df161.hpl 
;AREA=FLASH,4096K(256)
;AREA=OTP,128
;VCC=3250 



;Primary tested: AT26DF161,AT26DF321

; SPI SERIAL FLASH MEMORY

;Status Register:    7   6   5   4   3    2    1   0
;                   SPRL x   x  WPP SWP1 SWP0 WEL BUSY
;					    r/o r/o



;TABLE 3: SOFTWARE STATUS REGISTER
;Bit Name Function Default at Power-up Read/Write
;0 BUSY 1 = Internal Write operation is in progress
;	0 = No internal Write operation is in progress  ;0 R
;1 WEL 1 = Device is memory Write enabled
;	0 = Device is not memory Write enabled          ;0 R
;2 BP0 Indicate current level of block write protection (See Table 4) 1 R/W
;3 BP1 Indicate current level of block write protection (See Table 4) 1 R/W
;4 BP2 Indicate current level of block write protection (See Table 4) 1 R/W
;5 BP3 Indicate current level of block write protection (See Table 4) 0 R/W
;6 AAI Auto Address Increment Programming status
;	1 = AAI programming mode
;	0 = Byte-Program mode		;0 R
;7 BPL 1 = BP3, BP2, BP1, BP0 are read-only bits
;	0 = BP3, BP2, BP1, BP0 are read/writable	;0 R/W



INFO="Serial FLASH. Use ERASE before WRITE"
SOCKET=4 ;"SPI"
CDELAY=0.1 ; one set delay
OPTIONS=f

PINO=SCK,0
PINO=SI,1
PINO=CS,2
PINO=WP,3
PINO=NC,4  ;not present!
PINI=SO,1

BUSO=SPIOUT,0xD4
BUSO=SPIOUT24,0xD6
BUSI=SPIIN,0xD4


TESTMASK=11111100

R9=STATUS,C8,SPRL,x,x,WPP,SWP1,SWP0,WEL,BUSY
;R9=STATUS,B8
R10=ADDRESS,H


[_SENDBYTE]
;LOOP=(7,0){SI=R0[I],SCK=1,SCK=0}
;speed-up
SPIOUT=R0


[_SENDADR]
;LOOP=(23,0){SI=ADR[I],SCK=1,SCK=0}
SPIOUT24=ADR

;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

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

[_WRSR]
R1=R0
SCK=0
CS=0
_SENDBYTE(00000001b)      ;WRSR
R0=R1		     ;Status Register
_SENDBYTE
CS=1


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

[INIT]
NC=1
WP=0
CS=1
SCK=0
_WAITWR
_RDSR
R1[0]?1{ ;WIP bit = 0
PRINT=A("Chip not respond !\n Continue ?")
RA?0{EXIT}
}


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



[READBLOCK]
CS=0
_SENDBYTE(00000011b)     ;Read
_SENDADR
;_SENDBYTE(0xFF)	;?? dummy
SI=1
LOOP=($BLOCKSIZE){
;LOOP=(7,0){SCK=1,DATA[I]=SO,SCK=0}
;speed-up:
DATA=SPIIN
ADR=+1
}
CS=1

[_UNPROT]
R1=$SIZE
R1=/4096 ;min sec size
R4=0; ADR
LOOP(R1){
_WREN
CS=0
_SENDBYTE(39h)     ;Unprotect Sector
LOOP=(23,0){SI=R4[I],SCK=1,SCK=0} ;SEND ADR
CS=1
R4=+4096
PRINT=S("Unprotect %06X",R4)
}
PRINT=S("")


[WRITEINIT]

WP=1
CS=1
P=5000
_WREN

_WRSR(0);         ;Status Register
P=15000	;!

;_UNPROT

[WRITE]
R0=DATA,R0?0xFF{RETURN}
_WREN
CS=0
_SENDBYTE(00000010b)   ; Write
_SENDADR
_SENDBYTE(DATA);
SI=1,CS=1,P=10
_WAITWR

[WRITEBLOCK]
; write begin
_WREN
CS=0
_SENDBYTE(0x2)   ; Write + increment
_SENDADR
;P=10
LOOP=($BLOCKSIZE){
SPIOUT=DATA ;_SENDBYTE(DATA)
ADR=+1
}
CS=1

_WAITWR


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

_SENDBYTE(10101011b)	 ;RID
_SENDBYTE(0)		; DUMMY adr
_SENDBYTE(0)
_SENDBYTE(0)
SI=1
LOOP=(15,0){SCK=1,R7[I]=SO,SCK=0}
CS=1
PRINT=S("ID value = %04lXH",R7)
P=50000
R0=R7


[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}  ;new
CS=1
PRINT=S("ID value = %06lXH",R7)
R0=R7


[ReadStatus]

WP=1
SCK=0
CS=1
_RDSR
R9=R1
GET=("Status",R9)


[WriteStatus]
GET=("Write Status",R9)
RA?0{EXIT}
WP=1           ;enable
;PRINT=("value %02lX",R9)
_WREN
R0=R9
_WRSR
P=100000


[Erase]

WP=1
SCK=0

;_UNPROT

CS=1
_WREN
_WRSR(0)
P=15000
_WREN
CS=0
_SENDBYTE(0x60)		;BE Bulk Erase
CS=1

; Full erase time - 28 sec!
SCK=0
R2=0
PRINT=P(0,40000)
LOOP=(40000){
CS=0
PRINT=P(R2)
R2=+1
_RDSR
R1[0]?0{BREAK}   ;RDY bit
P=1000
}
PRINT=S("Erase status %02X",R1)
P=500000
R1[0]?1{PRINT=E("Erase timeout error!")}


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

WP=1
SCK=0

;_UNPROT

CS=1
_WREN
_WRSR(0)
P=15000
_WREN
CS=0
;_SENDBYTE(0x20)		;BE sec Erase
_SENDBYTE(0x52)		;BE BLK Erase
LOOP=(23,0){SI=R10[I],SCK=1,SCK=0}
CS=1
P=10000

; 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
}
PRINT=S("Erase status %02X",R1)
P=500000

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