; Orange programmer module v2.4 FASTSPI ; (c) 2006-2014 CnCLab ;CHIP=AT25DF161,2048K(256),at25df161.hpl ;VCC=3250 ;Primary tested: AT25DF161, ; SPI SERIAL FLASH MEMORY ;Status Register: 7 6 5 4 3 2 1 0 ; SPRL SPM EPE 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,w PINO=SCK,0 PINO=SI,1 PINO=CS,2 PINO=WP,3 PINO=HOLD,4 PINI=SO,1 BUSO=SPIOUT,0xD4 BUSO=SPIOUT24,0xD6 BUSI=SPIIN,0xD4 R9=STATUS,C8,SPRL,SPM,EPE,WPP,SWP1,SWP0,WEL,BUSY R11=STATUS2,C8,x,x,x,RSTE,SLE,PS,ES,BUSY ;R9=STATUS,B8 R10=ADDRESS,H R12=Sector,L,Unlocked,Locked [_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 ;return R1,R2 [_RDSR2] SCK=0 CS=0 _SENDBYTE(00000101b) ;RDSR SI=1 R1=0 LOOP=(7,0){SCK=1,R1[I]=SO,SCK=0} R2=0 LOOP=(7,0){SCK=1,R2[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] HOLD=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 OTP [_RDOTP] CS=0 _SENDBYTE(0x77) ;Read OTP _SENDADR _SENDBYTE(0) ;dummy _SENDBYTE(0) ;dummy SI=1 ;LOOP=(7,0){SCK=1,DATA[I]=SO,SCK=0} DATA=SPIIN CS=1 [READ] $AREA?1{_RDOTP,RETURN} CS=0 _SENDBYTE(0x03) ;Read FLASH _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} $AREA?1{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 _RDSR2 R9=R1 R11=R2 GET=("Status",R9,R11) [WriteStatus] GET=("Write Status",R9) RA?0{EXIT} WP=1 ;enable ;PRINT=("value %02lX",R9) _WREN R0=R9 _WRSR P=100000 [Erase] $AREA?!0{PRINT=E("Select FLASH area!"),EXIT} 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!")} ;DF041-DF161 - 32K [EraseSector] $AREA?!0{PRINT=E("Select FLASH area!"),EXIT} 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!")} ["Sector status"] GET=("Sector Address",R10) RA?0{EXIT} ;CS=0 ;_SENDBYTE(0x3C) ;Rd prot ;;LOOP=(23,0){SI=R10[I],SCK=P} ;SPIOUT24=R10 ;SI=1 ;R12=SPIIN ;CS=1 CS=0 _SENDBYTE(0x35) ;Rd lock ;LOOP=(23,0){SI=R10[I],SCK=P} SPIOUT24=R10 SI=1 R12=SPIIN CS=1 R12=&1 ;prot ;R12[0]=R0[0] GET=("Sector status",R12)