; Orange programmer module v2.1 ; (c) 2008-2012 CnCLab ;GROUP=Spansion ;CHIP=S25FL016,2048K(256),S25FL016.HPL ;VCC=3250 ;CHIP=S25FL032,4096K(256),S25FL016.hpl ;VCC=3250 ;CHIP=S25FL064A,8192K(256),S25FL016.hpl ;VCC=3250 ;CHIP=S25FL064P,8192K(256),S25FL016.hpl ;VCC=3250 ; S25FL064P have OTP! ;Status Register: 7 6 5 4 3 2 1 0 ; SRWD X X BP2 BP1 BP0 WEL WIP ; r/o r/o ; tested: S25FL016, S25FL064P SOCKET=4 ;"SPI" OPTIONS=f, CDELAY=0.1 ; one set delay PINO=SCK,0 PINO=SI,1 PINO=CS,2 PINO=WP,3 PINO=HOLD,4 PINI=SO,1 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} ;speed-up SI=R0[7],SCK=P SI=R0[6],SCK=P SI=R0[5],SCK=P SI=R0[4],SCK=P SI=R0[3],SCK=P SI=R0[2],SCK=P SI=R0[1],SCK=P SI=R0[0],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} SCK=1 R0[7]=SO,SCK=N R0[6]=SO,SCK=N R0[5]=SO,SCK=N R0[4]=SO,SCK=N R0[3]=SO,SCK=N R0[2]=SO,SCK=N R0[1]=SO,SCK=N R0[0]=SO,SCK=0 DATA=R0 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!")}