; Orange programmer module v2.5 FASTSPI ; (c) 2009-2012 CnCLab ; Macronix DATAFLASH ;CHIP=MX25L1005,128K(256),mx25l8005.hpl ;? ;VCC=3250 ;CHIP=MX25L2006,256K(256),mx25l8005.hpl ;VCC=3250 ;CHIP=MX25L4005,512K(256),mx25l8005.hpl ;VCC=3250 ;CHIP=MX25L8005,1024K(256),mx25l8005.hpl ;VCC=3250 ;CHIP=MX25L1605,2048K(256),mx25l8005.hpl ;VCC=3250 ;CHIP=MX25L1606,2048K(256),mx25l8005.hpl ;VCC=3250 ;CHIP=MX25L1608,2048K(256),mx25l8005.hpl ;VCC=3250 ;CHIP=MX25L1635,2048K(256),mx25l8005.hpl ;VCC=3250 ;PMC (PFlash) ;CHIP=Pm25LD010,128K(256),mx25l8005.hpl ;VCC=3250 ;CHIP=Pm25LD010,256K(256),mx25l8005.hpl ;VCC=3250 ; SPI SERIAL FLASH MEMORY ;Status Register: 7 6 5 4 3 2 1 0 ; SRWD X X BP2 BP1 BP0 WEL WIP ; r/o r/o ; Tested MX25L2005, MX25L2025MC, MX25L8005, MX25L1605, MX25L1608, MX25L3205, Pm25LD010 INFO="Serial FLASH. Use ERASE before WRITE" 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 BUSO=SPIOUT,0xD4 BUSO=SPIOUT24,0xD6 BUSI=SPIIN,0xD4 R9=STATUS,C8,SRWD,x,x,BP2,BP1,BP0,WEL,WIP ;R9=STATUS,B8 R10=ADDRESS,H R12=Erase,L,"Off,Sector,All chip" [_SENDBYTE] ;LOOP=(7,0){SI=R0[I],SCK=P} ;speed-up SPIOUT=R0 [_SENDADR] ;LOOP=(23,0){SI=ADR[I],SCK=P} SPIOUT24=ADR [_WREN] SCK=0 CS=0 _SENDBYTE(00000110b) ; Write enable CS=1 [_WRDI] SCK=0 CS=0 _SENDBYTE(00000100b) ; Write disable CS=1 ;return R1 [_RDSR] SCK=0 CS=0 _SENDBYTE(0x05) ;RDSR = 05 ;R0=0x05,LOOP=(7,0){SCK=0,SI=R0[I],SCK=1} SI=1 R1=0 LOOP=(7,0){R1[I]=SO,SCK=1,SCK=0} CS=1 [_WAITWR] ;Wait for end write memory... SCK=0 LOOP=(40000){ _RDSR R1[0]?0{BREAK} ;WIP bit P=5 } [_WRSR] R1=R0 SCK=0 CS=0 _SENDBYTE(00000001b) ;WRSR _SENDBYTE(R1) ;Status Register CS=1 P=10000 _WAITWR ;max 500ms [_RDID] SCK=0 CS=1 CS=0 R7=0 ;1010 1011 ABh Read Manufacturer and Product ID _SENDBYTE(0x9F) ;RDID SI=1,P=30 LOOP=(23,0){SCK=1,R7[I]=SO,SCK=0} CS=1 [INIT] HOLD=1 WP=0 CS=1 SCK=0 P=10 _RDID ; READ ID cmd 9F R7=&0xFFFF R7?0xFFFF{ PRINT=A("Chip not respond, continue?") RA?0{EXIT} } P=10 [READ] CS=0 _SENDBYTE(3) ;Read _SENDADR SI=1 ;LOOP=(7,0){SCK=1,DATA[I]=SO,SCK=0} DATA=SPIIN CS=1 [READBLOCK] CS=0 ;_SENDBYTE(00000011b) ;Read _SENDBYTE(0x0B) ;Fast Read _SENDADR _SENDBYTE(0) ; dummy SI=1 LOOP=($BLOCKSIZE){ ;LOOP=(7,0){SCK=1,DATA[I]=SO,SCK=0} ;speed-up: DATA=SPIIN ADR=+1 } CS=1 [_READBLOCKT] ;$BLOCKSIZE=512 ;dbg CS=0 _SENDBYTE(00000011b) ;Read _SENDADR SI=1 LOOP=($BLOCKSIZE){ LOOP=(7,0){SCK=1,DATA[I]=SO,SCK=0} ADR=+1 } CS=1 [WRITEINIT] HOLD=1 WP=1 CS=1 P=5000 _WREN _WRSR(0) ;Status Register clear [WRITE] _WREN CS=0 _SENDBYTE(00000010b) ; Write _SENDADR _SENDBYTE(DATA) SI=1,CS=1 P=2000 _WAITWR [WRITEBLOCK] ;R2=ADR ;check empty (0xFF) block _WREN CS=0 _SENDBYTE(0x02) ; Write + increment _SENDADR LOOP=($BLOCKSIZE){ _SENDBYTE(DATA) ADR=+1 } CS=1,SI=1 P=10 _WAITWR [WRITEEND] _WRDI [READID] ;WP=1 SCK=0 CS=1 _RDID ;cmd 9F PRINT=L("RDID value = %02lXH\n",R7) R0=R7 R0?0xFFFFFF{R0=0} R0?0{ ;try old id CS=0 R7=0 ;1010 1011 ABh Read Manufacturer and Product ID _SENDBYTE(0x90) ;REMS _SENDBYTE(0) ; DUMMY adr _SENDBYTE(0) _SENDBYTE(0) SI=1,P=100 LOOP=(15,0){SCK=1,R7[I]=SO,SCK=0} CS=1 PRINT=L("ID value = %02lXH",R7) P=10000 R0=R7 } [ReadStatus] ;HOLD=1 ;WP=1 ;_WRDI ;_WREN WP=0 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 _WRSR(R9) P=50000 _RDSR PRINT=S("Status=%02X",R1) P=500000 ;One Sector [_ERS1] GET=("Sector Address",R10) RA?0{EXIT} HOLD=1 WP=1 SCK=0 CS=1 _WREN _WRSR(0) _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 LOOP=(0,10000){ CS=0 PRINT=S("Erase %lu",R2) R2=+1 _RDSR R1[0]?0{BREAK} ;RDY bit P=1000 } _WRDI P=200000 ;Bulk chip Erase [_ERSA] HOLD=1 WP=1 SCK=0 CS=1 _WREN _WRSR(0) _WREN CS=0 _SENDBYTE(0x60) ;BE Bulk Erase CS=1 R7=$SIZE, R7=/50 ;; Full erase time - 64 000 ms (64sec)! PRINT=P(0,R7) SCK=0 R2=0 LOOP=(R7){ CS=0 R2=+1 PRINT=P(R2) _RDSR PRINT=S("STATUS=%02X",R1) R1[0]?0{BREAK} ;RDY bit P=1000 } _WRDI P=200000 [Erase] R12=0 GET=("Select Erase mode",R12) RA?0{EXIT} R12?0{EXIT} R12?1{_ERS1} R12?2{_ERSA}