; Orange programmer module v1.6 ; (c) 2007-2014 CnCLab ;CHIP=AT25F512,64K(256),AT25F2048.HPL ;VCC=3000 ;CHIP=AT25F1024,128K(256),AT25F2048.HPL ;VCC=3000 ;CHIP=AT25F2048,256K(256),AT25F2048.HPL ;VCC=3000 ; 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 ; Primary tested AT25F1024. INFO="Serial FLASH. Use ERASE before WRITE" SOCKET=4 ;"SPI" PINO=SCK,0 PINO=SI,1 PINO=CS,2 PINO=WP,3 PINO=HOLD,4 PINI=SO,1 CDELAY=0.1 ; one set delay R9=STATUS,C8,WPEN,x,x,x,BP1,BP0,WEN,RDY ;R9=STATUS,B8 R10=ADDRESS,H [_SENDBYTE] LOOP=(7,0){SI=R0[I],SCK=P} [_SENDADR] LOOP=(23,0){SI=ADR[I],SCK=P} ;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 [_WREN] SCK=0 CS=0 _SENDBYTE(00000110b) ; Write enable CS=1 [_WRSR] R1=R0 SCK=0 ;CS=0 ;_SENDBYTE(0x50) ;EWSR CS=1 CS=0 _SENDBYTE(00000001b) ;WRSR R0=R1 ;Status Register _SENDBYTE CS=1 [_RDID] CS=0 R7=0 ;1010 1011 ABh Read Manufacturer and Product ID ;_SENDBYTE(10101011b) ;RID _SENDBYTE(0x15) ;RID SI=1 LOOP=(15,0){SCK=1,R7[I]=SO,SCK=0} CS=1 [INIT] HOLD=1 WP=0 CS=1 SCK=0 _RDID R7?0xFFFF{PRINT=S("#ID wrong value = %04X\n",R7)} R7?0x0000{PRINT=S("#ID wrong value = %04X\n",R7)} [READ] CS=0 _SENDBYTE(00000011b) ;Read _SENDADR SI=1 LOOP=(7,0){SCK=1,DATA[I]=SO,SCK=0} CS=1 P=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} ADR=+1 } CS=1 [_WAITWR] ;Wait for end write memory... ;P=100000 SCK=0 LOOP=(0,10000){ _RDSR R1[0]?0{BREAK} ;WIP bit P=10 } [WRITEINIT] HOLD=1 WP=1 CS=1 P=5000 _WREN _WRSR(0); ;Status Register P=60000 ;! [WRITE] R0=DATA,R0?0xFF{RETURN} _WREN CS=0 _SENDBYTE(00000010b) ; Write _SENDADR _SENDBYTE(DATA); SI=1,CS=1 ;P=5000 _WAITWR [WRITEBLOCK] SCK=0 _WREN CS=0 _SENDBYTE(00000010b) ; Write _SENDADR LOOP=($BLOCKSIZE){ _SENDBYTE(DATA) 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(10101011b) ;RID _SENDBYTE(0x15) ;RID 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=1 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 R0=R9 _WRSR P=100000 [Erase] HOLD=1 WP=1 SCK=0 CS=1 _WREN _WRSR(0) P=60000 _WREN CS=0 _SENDBYTE(0x62) ;BE Bulk Chip Erase CS=1 ; Full erase time 25F1024 - 4.4 sec! SCK=0 R2=0 LOOP=(0,8000){ CS=0 _RDSR PRINT=S("Erase [%02X] %lu",R1,R2) R2=+1 R1[0]?0{BREAK} ;RDY bit P=1000 } PRINT=L("Status=%02X\n",R1) P=100000 [EraseSector] GET=("Sector Address",R10) RA?0{EXIT} HOLD=1 WP=1 SCK=0 CS=1 _WREN _WRSR(0) P=60000 _WREN CS=0 _SENDBYTE(0x52) ;BE BLK Erase LOOP=(23,0){SI=R10[I],SCK=1,SCK=0} CS=1 P=100000 ; Sector erase time - 1.1 sec! _WAITWR SCK=0 R2=0 LOOP=(0,5000){ CS=0 PRINT=S("Erase %lu",R2) R2=+1 _RDSR R1[0]?0{BREAK} ;RDY bit P=1000 } PRINT=L("Status=%02X\n",R1)