; Orange programmer module v2.1 FASTSPI ; (c) 2008-2013 CnCLab ; Status registers: 2 ; GROUP=Winbond ; CHIP=W25Q80,1024K(256),W25Q32.HPL ; CHIP=W25Q16,2048K(256),W25Q32.HPL ; CHIP=W25Q32,4096K(256),W25Q32.HPL ; CHIP=W25Q128,16384K(256),W25Q32.HPL ;VCC=3250 ; SPI FLASH ;bits 7 6 5 4 3 2 1 0 ;Status Register1: SRP0 SEC TB BP2 BP1 BP0 WEL BUSY ; r/o r/o ;Status Register2: X X X X X X QE SRP1 ; r/o r/o ; Tested W25Q16 Orange3+ISP, Orange4+ISP, Omega+ISP. ; Tested W25Q16 Orange5. ; Tested W25Q32 Orange5. ; Tested W25Q128 Orange5 (only read & id). 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=STATUS1,C8,SRP0,SEC,TB,BP2,BP1,BP0,WEL,BUSY R10=STATUS2,C2,QE,SRP1 ;R9=STATUS,B8 [INIT] HOLD=1 WP=0 CS=1 SCK=0 [_SENDBYTE] ;LOOP=(7,0){SI=R0[I],SCK=P} ;speed-up SPIOUT=R0 [_SENDADR0] ;LOOP=(23,0){SI=ADR[I],SCK=1,SCK=0} SPIOUT24=R0 [_SENDADR] ;LOOP=(23,0){SI=ADR[I],SCK=1,SCK=0} SPIOUT24=ADR [READ] CS=0 _SENDBYTE(3) ;Read ;LOOP=(23,0){SI=ADR[I],SCK=P} _SENDADR SI=1 DATA=SPIIN CS=1 [READBLOCK] CS=0 _SENDBYTE(3) ;Read SPIOUT24=ADR ; _SENDADR SI=1 LOOP=($BLOCKSIZE){ ;LOOP=(7,0){SCK=1,DATA[I]=SO,SCK=0} DATA=SPIIN ADR=+1 } CS=1 [_RDSTAT] CS=0 _SENDBYTE(00000101b) ;RDSR SI=1 ;R9=0 ;LOOP=(7,0){SCK=1,R9[I]=SO,SCK=0} R9=SPIIN CS=1 [_WAITWR] ;Wait for end write memory... SCK=0 LOOP=(0,500){ _RDSTAT R9[0]?0{BREAK} ;WIP bit P=10 } [_WREN] SCK=0 CS=0 R0=00000110b ; Write enable _SENDBYTE CS=1 [WRITEINIT] HOLD=1 WP=1 CS=1 P=5000 _WREN CS=0 _SENDBYTE(00000001b) ;WRSR _SENDBYTE(0) ;Status Register CS=1 P=15000 ;! _WAITWR [WRITE] R0=DATA,R0?0xFF{RETURN} SCK=0 _WREN CS=0 _SENDBYTE(00000010b) ; Write _SENDADR ;LOOP=(23,0){SI=ADR[I],SCK=P} SPIOUT=DATA ;LOOP=(7,0){SI=DATA[I],SCK=P} SI=1,CS=1 ;P=5000 _WAITWR ; page program time - max 3ms [WRITEBLOCK] _WREN CS=0 _SENDBYTE(00000010b) ; Write CMD _SENDADR ;LOOP=(23,0){SI=ADR[I],SCK=P} LOOP=($BLOCKSIZE){ SPIOUT=DATA ;LOOP=(7,0){SI=DATA[I],SCK=P} ADR=+1 } CS=1 _WAITWR [READID] WP=1 SCK=0 CS=1 CS=0 R7=0 ;_SENDBYTE(0x90) ;Read ID _SENDBYTE(0x9F) ;JEDEC Read ID R0=0 ; DUMMY adr SI=1 LOOP=(23,0){SCK=1,R7[I]=SO,SCK=0} CS=1 P=100 R0=R7 R7?0xEF10{PRINT=S("ID = %04lXH. Winbond W25P10",R7),RETURN} R7?0xEF11{PRINT=S("ID = %04lXH. Winbond W25P20",R7),RETURN} R7?0xEF12{PRINT=S("ID = %04lXH. Winbond W25P40",R7),RETURN} R7?!0xFFFF{PRINT=S("ID = %04lXH",R7),RETURN} R0=R8 R8?0xEF2014{PRINT=S("ID = %04lXH. Winbond W25P80",R8),RETURN} R8?0xEF2015{PRINT=S("ID = %04lXH. Winbond W25P16",R8),RETURN} R8?0xEF2016{PRINT=S("ID = %04lXH. Winbond W25P32",R8),RETURN} R8?0xEF3011{PRINT=S("ID = %04lXH. Winbond W25X10",R8),RETURN} R8?0xEF3012{PRINT=S("ID = %04lXH. Winbond W25X20",R8),RETURN} R8?0xEF3013{PRINT=S("ID = %04lXH. Winbond W25X40",R8),RETURN} R8?0xEF3014{PRINT=S("ID = %04lXH. Winbond W25X80",R8),RETURN} R8?0xEF3015{PRINT=S("ID = %04lXH. Winbond W25X16",R8),RETURN} R8?0xEF3016{PRINT=S("ID = %04lXH. Winbond W25X32",R8),RETURN} R8?0xEF3017{PRINT=S("ID = %04lXH. Winbond W25X64",R8),RETURN} R8?0xEF4014{PRINT=S("ID = %04lXH. Winbond W25Q80",R8),RETURN} R8?0xEF4015{PRINT=S("ID = %04lXH. Winbond W25Q16",R8),RETURN} R8?0xEF4016{PRINT=S("ID = %04lXH. Winbond W25Q32",R8),RETURN} PRINT=S("ID value = %04lXH",R8) [ReadStatus] ;HOLD=1 WP=1 SCK=0 CS=1 CS=0 R9=0 _SENDBYTE(0x05) ;RDSR SI=1 LOOP=(7,0){SCK=1,R9[I]=SO,SCK=0} CS=1 P=10 R10=0 CS=0 _SENDBYTE(0x35) ;RDSR2 SI=1 LOOP=(7,0){SCK=1,R10[I]=SO,SCK=0} CS=1 P=10000 GET=("Status",R9,R10) [WriteStatus] GET=("Write Status",R9,R10) RA?0{EXIT} WP=1 CS=1 SCK=0 ;PRINT=("value %02lX",R9) _WREN CS=0 R0=00000001b ;WRSR _SENDBYTE R0=R9 ;Status Register _SENDBYTE CS=1 P=200000 ;Write Status Register Time 67... 150 ms [Erase] PRINT=S("Erase...") HOLD=1 WP=1 SCK=0 CS=1 _WREN CS=0 _SENDBYTE(00000001b) ;WRSR _SENDBYTE(0) ;Status Register CS=1 P=100000 ;Write Status Register Time 67... 150 ms! _WAITWR _WREN CS=0 _SENDBYTE(11000111b) ;BE Bulk Erase 0xC7 CS=1 ; Full erase time: ; Winbond 25..80 sec SCK=0 R3=0 PRINT=P(0,22000) LOOP=(22000){ ;110 sec _RDSTAT R9[0]?0{BREAK} ;BUSY bit P=5000 R3=+1 PRINT=P(R3) } PRINT=S("Erase status %02X",R9) P=400000 R9?!0{ P=600000 PRINT=L("Erase error. Status %02X\n",R9) }