; Orange programmer module v2.0 FASTSPI ; (c) 2009-2012 CnCLab, pavel-pervomaysk ;CHIP=PM25LV512,64K(128),PM25L010.HPL ;VCC=3250 ;CHIP=PM25LV010,128K(128),PM25L010.HPL ;VCC=3250 ;CHIP=PM25LV020,256K(128),PM25L010.HPL ;VCC=3250 ; SPI SERIAL FLASH MEMORY ;Status Register: 7 6 5 4 3 2 1 0 ; WPEN X X X BP1 BP0 WEN RDY ; r/o r/o ; tested PM25LV512, PM25LV020 ; For Pm25LD010,Pm25LD020 use mx25l8005.hpl 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,WPEN,x,x,x,BP1,BP0,WEN,RDY R11=CONFIG,C8,x,x,x,SP0_3,SP0_2,SP0_1,SP0_0,SCFG ;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 ;return R1 [_RDSR] SCK=0 CS=0 _SENDBYTE(00000101b) ;RDSR SI=1 ;R1=0 ;LOOP=(7,0){SCK=1,R1[I]=SO,SCK=0} R1=SPIIN CS=1 [_WREN] SCK=0 CS=0 _SENDBYTE(00000110b) ; Write enable CS=1 [_WAITWS] ;Wait for erase/write status... 100 ms SCK=0 LOOP=(0,5000){ _RDSR ;PRINT=S("SR=%02X\n",R1) R1[0]?0{BREAK} ;WIP bit = 0 P=40 } [_WAITWR] ;Wait for write memory... 5ms SCK=0 LOOP=(0,1000){ _RDSR R1[0]?0{BREAK} ;WIP bit = 0 P=20 } [_WRSR] R1=R0 SCK=0 CS=0 _SENDBYTE(00000001b) ;WRSR R0=R1 ;Status Register _SENDBYTE CS=1 _WAITWS [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] CS=0 _SENDBYTE(00000011b) ;Read _SENDADR SI=1 ;LOOP=(7,0){SCK=1,DATA[I]=SO,SCK=0} DATA=SPIIN CS=1 ;P=1 [READBLOCK] CS=0 _SENDBYTE(00000011b) ;Read ;_SENDBYTE(00001011b) ;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 [WRITEINIT] HOLD=1 WP=1 CS=1 P=5000 _WREN _WRSR(0) ;Status Register P=60000 [WRITE] SCK=0 _WREN CS=0 _SENDBYTE(00000010b) ; Write _SENDADR ; LOOP=(23,0){SI=ADR[I],SCK=1,SCK=0} SPIOUT=DATA ;LOOP=(7,0){SI=DATA[I],SCK=1,SCK=0} SI=1,CS=1 ;P=5000 _WAITWR R1[0]?1{PRINT=S("Write timeout!"),P=100} [WRITEBLOCK] SCK=0 _WREN CS=0 _SENDBYTE(00000010b) ; Write _SENDADR LOOP=($BLOCKSIZE){ SPIOUT=DATA ;LOOP=(7,0){SI=DATA[I],SCK=1,SCK=0} ADR=+1 } CS=1 _WAITWR R1[0]?1{PRINT=S("Write timeout!"),P=100} [READID] 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 = %02lXH",R7) P=50000 R0=R7 [ReadStatus] HOLD=1 WP=0 SCK=0 CS=1 _RDSR R9=R1 GET=("Status",R9) [WriteStatus] HOLD=1 GET=("Write Status",R9) RA?0{EXIT} WP=1 ;enable ;PRINT=("value %02lX",R9) _WREN _WRSR(R9) _RDSR PRINT=S("SR=%02X\n",R1) P=700000 [ReadConfig] HOLD=1 WP=0 SCK=0 CS=1 CS=0 _SENDBYTE(10100001b) ;RDCR SI=1 R11=0 LOOP=(7,0){SCK=1,R11[I]=SO,SCK=0} CS=1 GET=("Configuration",R11) ;Erase full chip [_ERSA] HOLD=1 WP=1 _WREN P=10 _WRSR(0) P=100000 _WREN P=100 CS=0 _SENDBYTE(11000111b) ;BE Bulk Erase CS=1 ; Full erase time - 4 sec! SCK=0 R2=0 LOOP=(0,50000){ ;CS=0 ;PRINT=S("Erase %lu",R2) ;R2=+1 _RDSR PRINT=S("SR=%02X\n",R1) R1[0]?0{BREAK} ;RDY bit P=100 } ; Show status LOOP=(0,500){ _RDSR PRINT=S("SR=%02X\n",R1) P=1000 } ;Erase 1 Sector [_ERS1] GET=("Sector Address",R10) RA?0{EXIT} HOLD=1 WP=1 SCK=0 CS=1 _WREN _WRSR(0) P=100000 _WREN CS=0 _SENDBYTE(11010111b) ;BE sec Erase ;_SENDBYTE(11011000b) ;BE BLK Erase LOOP=(23,0){SI=R10[I],SCK=1,SCK=0} CS=1 P=5000 ; Full erase time - 4 sec! _WAITWS SCK=0 LOOP=(0,5000){ CS=0 _RDSR PRINT=S("Erase sector, SR=%02X",R1) R1[0]?0{BREAK} ;RDY bit P=1000 } P=100000 [Erase] R12=0 GET=("Select Erase mode",R12) RA?0{EXIT} R12?0{EXIT} R12?1{_ERS1} R12?2{_ERSA}