; Orange programmer module v2.4 ; (c) 2013 CnCLab ; SPI FLASH with OTP area. ;GROUP=EON ;CHIP=EN25S40,512K(256),EN25F16.HPL ;AREA=FLASH,512K(256) ;AREA=OTP,256(256) ;VCC=3250 ;CHIP=EN25B16,2048K(256),EN25B80.hpl ;VCC=3250 ;CHIP=EN25F16,2048K(256),EN25F16.hpl ;AREA=FLASH,2048K(256) ;AREA=OTP,512(256) ;VCC=3250 ;tested: EON EN25B40-50HCP, EON EN25B40-75GCP, EN25D80, EN25S40, EN25F16 ; OTP AREA: ; EN25F05 - 256 ; EN25F20 - 256 ; EN25F40 - 256 ; EN25S40 - 256 ; EN25D80 - 256 ; EN25F80 - 256 ; EN25T80 - 256 ; EN25F16 - 512 ; EN25T16 - 512 ; EN25QH16- 512 ; EN25Q32 - 512 ; EN25B64 - 512 ; EN25Q64 - 512 ; EN25BXX - Boot Sector ; EN25FXX - Uniform Sector ; read, write, erase = M25P40 ; ID = SST25V010.hpl ;Status Register: 7 6 5 4 3 2 1 0 ; SRP X X BP2 BP1 BP0 WEL WIP ; r/o r/o SOCKET=4 ;"SPI" OPTIONS=f PINO=SCK,0 PINO=SI,1 PINO=CS,2 PINO=WP,3 PINO=HOLD,4 PINI=SO,1 CDELAY=0.1 ; one set delay R10=STATUS,C8,SRP,x,x,BP2,BP1,BP0,WEL,WIP ;MAIN R11=STATUS,C8,OTP_LOCK,x,x,BP2,BP1,BP0,WEL,WIP ;OTP ;R9=STATUS,B8 [_SENDBYTE] LOOP=(7,0){SI=R0[I],SCK=P} [INIT] HOLD=1 WP=0 CS=1 SCK=0 $AREA?1{ CS=0 _SENDBYTE(0x3A) ;Enter OTP mode 3Ah SI=1 CS=1 } [READ] CS=0 _SENDBYTE(00000011b) ;Read LOOP=(23,0){SI=ADR[I],SCK=P} SI=1 LOOP=(7,0){SCK=1,DATA[I]=SO,SCK=0} CS=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} ;speed-up 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 [_WAITWR] ;Wait for end write memory... SCK=0 LOOP=(0,5000){ CS=0 _SENDBYTE(00000101b) ;RDSR SI=1 R9=0 LOOP=(7,0){SCK=1,R9[I]=SO,SCK=0} CS=1 R9[0]?0{BREAK} ;WIP bit P=10 } [_WREN] SCK=0 CS=0 _SENDBYTE(00000110b) ; Write enable CS=1 [WRITEINIT] HOLD=1 WP=1 CS=1 P=5000 _WREN ;Note : In OTP mode, the WRSR command will ignore any input ;data and program OTP_LOCK bit to 1, user must clear the protect ;bits before entering OTP mode and program the OTP code, then execute ;WRSR command to lock the OTP sector before leaving OTP mode. $AREA?0{ ;для области OTP не трогать, залочится!!!!!!! CS=0 _SENDBYTE(00000001b) ;WRSR _SENDBYTE(00000000b) ;Status Register CS=1 P=50000 ;! } $AREA?1{ ;для области OTP CS=0 R10=0 _SENDBYTE(00000101b) ;RDSR SI=1 LOOP=(7,0){SCK=1,R10[I]=SO,SCK=0} CS=1 R10[7]?1{PRINT=S("#OTP area locked!")} } [WRITE] 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 ;_SENDBYTE(0x04) ;Write Disable / Exit OTP mode ;SI=1 ; New ID (JEDEC) CS=0 _SENDBYTE(0x9F) ;JEDEC Read ID - New SI=1 R7=0 LOOP=(23,0){SCK=1,R7[I]=SO,SCK=0} CS=1 PRINT=L("ID1=%06X\n",R7) ;R7?0xFFFFFF{ ;not supported id cmd? ;Try Old ID (90H) CS=0 _SENDBYTE(0x90) ;RES R0=0 ; DUMMY LOOP=(23,0){SI=R0[I],SCK=P} SI=1 R8=0 LOOP=(15,0){SCK=1,R8[I]=SO,SCK=0} CS=1 ;R0=R8 PRINT=L("ID2=%06X\n",R8) ;} R0=R7 R7?0xFFFFFF{R0=R8} [ReadStatus] ;HOLD=1 WP=1 SCK=0 CS=1 CS=0 R10=0 _SENDBYTE(00000101b) ;RDSR SI=1 LOOP=(7,0){SCK=1,R10[I]=SO,SCK=0} CS=1 P=10000 R11=R10 $AREA?0{GET=("Status",R10)} $AREA?1{GET=("Status",R11)} [WriteStatus] $AREA?0{GET=("Write Status",R10)} $AREA?1{PRINT=A("Permanent lock OTP area?"),R10=0} RA?0{EXIT} WP=1 CS=1 SCK=0 ;PRINT=("value %02lX",R9) _WREN CS=0 R0=00000001b ;WRSR _SENDBYTE R0=R10 ;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=200000 ;Write Status Register Time 67... 150 ms _WREN CS=0 R0=11000111b ;BE Bulk Erase _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) } [END] R2=R0 ;PUSH CS=0 _SENDBYTE(0x04) ;Write Disable / Exit OTP mode SI=1 P=1000 R0=R2 ;POP