diff --git a/ChipInfoDb.dedicfg b/ChipInfoDb.dedicfg index b78899a..9840671 100644 Binary files a/ChipInfoDb.dedicfg and b/ChipInfoDb.dedicfg differ diff --git a/ChipInfoDb.h b/ChipInfoDb.h index 8def8e1..f4ded47 100755 --- a/ChipInfoDb.h +++ b/ChipInfoDb.h @@ -28,6 +28,7 @@ int Dedi_Search_Chip_Db(long RDIDCommand, long UniqueID, CHIP_INFO* Chip_Info, i int Dedi_Search_Chip_Db(char* TypeName, long RDIDCommand, long UniqueID, CHIP_INFO* Chip_Info, int search_all); #endif int Dedi_Search_Chip_Db_ByTypeName(char* TypeName, CHIP_INFO* Chip_Info); -FILE* openChipInfoDb(void); +//FILE* openChipInfoDb(void); +bool GetChipDbPath(char *Path); #endif diff --git a/FlashCommand.c b/FlashCommand.c index 02bcb28..838d783 100755 --- a/FlashCommand.c +++ b/FlashCommand.c @@ -232,3 +232,94 @@ int FlashCommand_SendCommand_SetupPacketForBulkRead(struct CAddressRange* AddrRa // send rq via control pipe return OutCtrlRequest(&rq, vInstruction, rq.Length, Index); } + +int FlashCommand_SendCommand_SetupPacketForBulkReadNAND(unsigned int dwAddr, unsigned int PageNum, unsigned char modeRead,WORD pageSize, WORD blockPages, unsigned char ReadCom,unsigned char AddrLen, unsigned char ReadDummyLen,unsigned char nCA, int USBIndex) +{ + unsigned char vInstruction[18]; + vInstruction[0]=(dwAddr & 0xff) ; + vInstruction[1]=((dwAddr>>8) & 0xff); + vInstruction[2]=((dwAddr>>16) & 0xff); + vInstruction[3]=((dwAddr>>24) & 0xff); + + //dwLength + vInstruction[4]=((unsigned char)(PageNum & 0xff)); // lowest byte of length : page number + vInstruction[5]=((unsigned char)( (PageNum >> 8) & 0xff)); // highest byte of length: page number + vInstruction[6]=((unsigned char)( (PageNum >> 16) & 0xff) ); + vInstruction[7]=((unsigned char)( (PageNum >> 24) & 0xff) ); + + //dwMode + vInstruction[8]=(modeRead); + vInstruction[9]=(modeRead>>8); + + //pagesize + vInstruction[10]=((unsigned char)(pageSize)); + vInstruction[11]=((unsigned char)(pageSize>>8)); + + //blockpages + vInstruction[12]=((unsigned char)(blockPages)); + vInstruction[13]=((unsigned char)(blockPages>>8)); + + vInstruction[14]=((unsigned char)(ReadCom));//cmd + + vInstruction[15]=((unsigned char)AddrLen);//addrLen + + vInstruction[16]=((unsigned char)(ReadDummyLen)); + + vInstruction[17]=((unsigned char)nCA); + + CNTRPIPE_RQ rq ; + rq.Function = URB_FUNCTION_VENDOR_ENDPOINT ; + rq.Direction = VENDOR_DIRECTION_OUT ; + rq.Request = DTC_READ_NAND ; + rq.Value = 0 ; + rq.Index = 0 ; + rq.Length = (unsigned long)(sizeof(vInstruction)) ;//40 + + // send rq via control pipe + return OutCtrlRequest(&rq, vInstruction,rq.Length,USBIndex); +} + +bool FlashCommand_SendCommand_SetupPacketForBulkWriteNAND(unsigned int dwAddr, size_t dwLength,unsigned char modeWrite,WORD pageSize, WORD blockPages, unsigned char WriteCom,unsigned char AddrLen, unsigned char WriteDummyLen,unsigned char nCA, int USBIndex) +{ + unsigned char vInstruction[40]={0}; + //dwAddr; + vInstruction[0]=(dwAddr & 0xff); + vInstruction[1]=((dwAddr>>8) & 0xff); + vInstruction[2]=((dwAddr>>16) & 0xff); + vInstruction[3]=((dwAddr>>24) & 0xff); + + //dwLength + vInstruction[4]=((unsigned char)(dwLength & 0xff)); // lowest byte of length : page number + vInstruction[5]=((unsigned char)( (dwLength >> 8) & 0xff)); // highest byte of length: page number + vInstruction[6]=((unsigned char)( (dwLength >> 16) & 0xff) ); + vInstruction[7]=((unsigned char)( (dwLength >> 24) & 0xff) ); + + //dwMode + vInstruction[8]=((unsigned char)modeWrite); + vInstruction[9]=((unsigned char)(modeWrite>>8)); + + //pagesize + vInstruction[10]=((unsigned char)pageSize); + vInstruction[11]=((unsigned char)(pageSize>>8)); + + //blockpages + vInstruction[12]=(blockPages); + vInstruction[13]=((unsigned char)(blockPages>>8)); + vInstruction[14]=(WriteCom);//cmd + vInstruction[15]=(AddrLen);//addrLen + vInstruction[16]=(4); + vInstruction[17]=(nCA); + + CNTRPIPE_RQ rq ; + + rq.Function = URB_FUNCTION_VENDOR_ENDPOINT ; + rq.Direction = VENDOR_DIRECTION_OUT ; + rq.Request = WRITE_NAND ; + rq.Value = 0 ; + rq.Index = 0 ; + rq.Length = sizeof(vInstruction); + + // send rq via control pipe + return OutCtrlRequest(&rq, vInstruction,rq.Length,USBIndex); +} + diff --git a/FlashCommand.h b/FlashCommand.h index cb7dcdb..b520da2 100755 --- a/FlashCommand.h +++ b/FlashCommand.h @@ -23,5 +23,8 @@ int FlashCommand_SendCommand_SetupPacketForBulkWrite(struct CAddressRange* AddrR int FlashCommand_SendCommand_SetupPacketForAT45DBBulkWrite(struct CAddressRange* AddrRange, unsigned char modeWrite, unsigned char WriteCom, int Index); int FlashCommand_SendCommand_SetupPacketForBulkRead(struct CAddressRange* AddrRange, unsigned char modeRead, unsigned char ReadCom, unsigned int AddrLen, unsigned int DummyLen, int Index); +int FlashCommand_SendCommand_SetupPacketForBulkReadNAND(unsigned int dwAddr, unsigned int PageNum, unsigned char modeRead,WORD pageSize, WORD blockPages, unsigned char ReadCom,unsigned char AddrLen, unsigned char ReadDummyLen,unsigned char nCA, int USBIndex); +bool FlashCommand_SendCommand_SetupPacketForBulkWriteNAND(unsigned int dwAddr, size_t dwLength,unsigned char modeWrite,WORD pageSize, WORD blockPages, unsigned char WriteCom,unsigned char AddrLen, unsigned char WriteDummyLen,unsigned char nCA, int USBIndex); + #endif //FLASHCOMMANDS diff --git a/Macro.h b/Macro.h index a1bdec9..acb6abf 100755 --- a/Macro.h +++ b/Macro.h @@ -9,14 +9,15 @@ #include // new defined macros +#define IS_NAND_FLASH {if()} //programmer info RQ #define PROGINFO_REQUEST 0x08 #define SET_VCC 0x09 ///< set VCC #define SET_VPP 0x03 ///< set VPP -#define SET_CS 0x14 -#define SET_IOMODE 0x15 -#define SET_SPICLK 0x61 -#define SET_HOLD 0x1D +//#define SET_CS 0x14 +//#define SET_IOMODE 0x15 +//#define SET_SPICLK 0x61 +//#define SET_HOLD 0x1D #define SET_SA 0x0A //first field of RQ @@ -30,6 +31,11 @@ //#define READ_EEPROM 0x05 //#define WRITE_EEPROM 0x06 // values of Request Field of a setup packet + +typedef unsigned short WORD; +typedef unsigned char BYTE; +typedef unsigned long DWORD; + typedef struct FirmwareInfo { char Programmer[20]; char Version[10]; @@ -51,13 +57,33 @@ typedef enum { READ_EEPROM = 0x05, WRITE_EEPROM = 0x06, - CHECK_SD_CARD = 0x65, GET_BUTTON_STATUS = 0x11, + GET_UID = 0x12, + SET_CS = 0x14, + SET_IOMODE = 0x15, + FW_UPDATE = 0x1A, + FPGA_UPDATE = 0x1B, + READ_FPGA_VERSION = 0x1C, + SET_HOLD = 0x1D, + DTC_READ_NAND = 0x40, + WRITE_NAND = 0x50, + MICRON_XIP_RESET =0x99, + SET_SPICLK = 0x61, + DOWNLOAD_PROJECT =0x63, + GET_PROJECT_NAME =0x64, + CHECK_SD_CARD = 0x65, + READ_PROJECT =0x66, + DL_IC_INFO_NAND =0x67, + READ_IC_INFO_NAND =0x68, + READ_ONBOARD_NAND =0x73, + GET_FW_STATUS =0x9B, //0x9A: Set //0x9B:Get } USB_CMD; typedef struct ChipInfo { char TypeName[100]; + char ICType[16]; size_t UniqueID; + size_t ChipIDMask; char Class[100]; char Description[256]; @@ -66,6 +92,7 @@ typedef struct ChipInfo { char Voltage[20]; char Clock[20]; char ProgramIOMethod[20]; + char type[16]; size_t ManufactureID; size_t JedecDeviceID; @@ -88,7 +115,164 @@ typedef struct ChipInfo { size_t RDIDCommand; size_t Timeout; size_t VoltageInMv; + // SPI NAND + size_t SpareSizeInByte;//NAND + size_t nCA_Rd; + size_t nCA_Wr; + size_t DefaultDataUnitSize; + size_t DefaultErrorBits; + size_t BBMark; + size_t SupportedProduct; + size_t ECCParityGroup; + size_t ECCProtectStartAddr; + size_t ECCProtectDis; + size_t ECCProtectLength; + bool ECCEnable; + + bool QPIEnable; + size_t ChipEraseTime; + size_t EraseCmd; + size_t ProgramCmd; + size_t ReadCmd; + size_t ProtectBlockMask; + size_t UnlockCmd; + size_t RDSRCnt; + size_t WRSRCnt; + size_t WRSRCmd; + size_t RDSRCmd; + size_t WRCRCmd; + size_t RDCRCmd; + size_t QEbitAddr; + bool SupportLUT; + } CHIP_INFO; +#pragma pack(push,1) +typedef struct spi_nand_info{ + unsigned short Hearder;//A1A1 + unsigned short Version;//0x0001 + unsigned short Type;//0x0001 for spi nand + unsigned short STsize;//size of this struct + unsigned int ChipID; + unsigned int ChipIDMask; + unsigned short RealPagesize; //for real OP. include spare area size , when scanBB , this size not include spare area size + unsigned short PagesPerBlock; + unsigned int Blocks; + //24 + + unsigned int BlockIndex; + unsigned int BlockCount; + + //32 + unsigned short EN_spareArea; + unsigned short SPA_pagesize; //spare area pagesize + unsigned short MA_pagesize; //main area pagesize + + unsigned char BeCmd; + unsigned char RdCmd; + unsigned char WrCmd; + unsigned char AddrLen; + unsigned char nCA_Rd; + unsigned char nCA_Wr; + unsigned char Dummy; +//44 + + unsigned short MaxERR_bits; + unsigned short BBMark; + unsigned char BB_BYTE_TYPE;//0:not skip, 0x11:~0xFF, 0x10:~0x00, 0x21: ~0xFFFF, 0x20:~0x0000 + unsigned char BBM_TYPE;//0:no BBM, 1: skip BB, 2:others + + unsigned short BBK_TOTAL;//only useful after BB scan. + + //52 + unsigned char StartBB; //set 0: no start BB,set 1, start BB scan. If ready, device will set 2. + unsigned char UNprotect_type;// 1 enable. other default + unsigned char En_internalECC;//0 disable, 1 enable. 0xff default +//55 + unsigned int EraseStartBlock; + unsigned int EraseEndBlock; +//63 + unsigned char EraseMode;//0:not enable; 1: force erase; 2: skip bad block(must Start BB before) +//64 + unsigned char EraseStatus;//0:Pass; 1: Fail + + unsigned char saveSTA; //enable save STA + //66 + unsigned short rfu0; + unsigned short perPageSizeForErrBit; + unsigned char ReadSatus_mode;//1:w25N512G + + unsigned short VFMODE; //[3]==0:old:[3:0]MaxErrorBit, [15:4]:ErrorBit reset size; size={256xErrorBit[7:4]+ErrorBit[15:8]} + //[3]==1:new: [15:8]Max Error Bit allowed + //[2:0]==MODE 0:DS 1:DSDSDS..DS 2:DDDD...DSSSS...S 3:DDD...D 4: for internal ECC skip + + unsigned short VFCOFGL; //for mode 0,1,2,3: + unsigned short VFCOFGH; //[31:16]: Data Unit size; + //[15:0]: Ecc Unit size; + //for mode 4: + //[31:16]: User Data mask + //[15:0]: Internal ECC address mask + unsigned short staPVpagesize; + unsigned int staPVpages; + unsigned int staPVsize; + unsigned char rfu[34]; + unsigned short crc; +}SELECT_SPI_NAND_INFO; +#pragma pack(pop) + +struct EraseCommand +{ + unsigned char ChipErase; + unsigned char SectorErase; + unsigned char DieErase; + unsigned char RFU2; +} ; +struct ReadCommand +{ + unsigned char SingleRead; + unsigned char DualRead; + unsigned char QuadRead; + unsigned char RFU3; +} ; +struct ProgramCommand +{ + unsigned char SingleProgram; + unsigned char DualProgram; + unsigned char QuadProgram; + unsigned char RFU4; +} ; + +struct CNANDContext +{ + //bool is_S25FL128P_256KSectors; + const unsigned short cbyRLine[5];// = {0x111,0x121,0x122,0x141,0x144}; + const unsigned short cbyPLine[5] ;//= {0x111,0x111,0x111,0x141,0x144}; + unsigned int realPageSize; + unsigned int realSpareAreaSize; + unsigned int realBlockSize; + unsigned int realChipSize; + struct EraseCommand EraseCmd; + struct ReadCommand ReadCmd; + struct ProgramCommand ProgramCmd; +}; + +struct Block_Parameter +{ + unsigned int block_sart; + unsigned int block_cnt; + unsigned int block_end; +}; + +struct ProgrgmPatitionTable +{ + unsigned int pt_cnt; + struct Block_Parameter PT[]; +}; + +struct BadBlockTable +{ + unsigned short cnt; + unsigned short bbt[255]; +}; //third field of RQ #define CTRL_TIMEOUT 3000 ///< time out for control pipe or for firmwire @@ -124,6 +308,10 @@ typedef struct ChipInfo { #define BULK_AT45xx_READ 0x03 ///< fast read via bulk pipes #define BULK_4BYTE_FAST_READ 0x04 ///< For size is bigger than 128Mb #define BULK_4BYTE_FAST_READ_MICRON 0x05 //for 0x0c +#define BULK_FAST_READ_DIE2 0x06 ///< fast read via bulk pipes +#define BULK_4BYTE_NORM_READ 0x07 //FW 7.2.26_FPGA_D +#define BULK_QUAD_READ 0x09 //FW 7.2.29 + //for flash card #define POLLING 0x02 ///< polling @@ -168,7 +356,7 @@ typedef struct ChipInfo { #define SUPPORT_ATO #define SUPPORT_FIDELIX #define SUPPORT_FUDAN - +#define SUPPORT_GIGADEVICE // memory support list #ifdef SUPPORT_NANTRONICS #define SUPPORT_NANTRONICS_N25Sxx "N25Sxx" @@ -178,6 +366,12 @@ typedef struct ChipInfo { #define SUPPORT_ATO_ATO25Qxx "ATO25Qxx" #endif +#ifdef SUPPORT_GIGADEVICE + #define SUPPORT_GIGADEVICE_GD25SXXX_LARGE "GD25Sxxx_Large" + #define SUPPORT_GIGADEVICE_GD5F1GQ4xCx "GD5F1GQ4xCx" +#endif + + #ifdef SUPPORT_ST #define SUPPORT_ST_M25PExx "M25PExx" #define SUPPORT_ST_M25Pxx "M25Pxx" @@ -298,6 +492,10 @@ typedef struct ChipInfo { #define BIT13 0x2000 #define BIT14 0x4000 #define BIT15 0x8000 +#define BIT16 0x10000 +#define BIT17 0x20000 +#define BIT18 0x40000 + #define ERASE BIT0 #define PROGRAM BIT1 @@ -314,6 +512,10 @@ typedef struct ChipInfo { #define LIST_TYPE BIT12 #define LOADFILEWITHVERIFY BIT13 #define CHECK_INFO BIT14 +#define SPECIAL_ERASE BIT15 +#define SPECIAL_PROGRAM BIT16 +#define SPECIAL_AUTO BIT17 +#define BATCH_WITH_FORCEERASE BIT18 struct CAddressRange { size_t start; @@ -321,39 +523,6 @@ struct CAddressRange { size_t length; }; -struct memory_id { - char TypeName[20]; - size_t UniqueID; - char Class[20]; - char Description[20]; - - char Manufacturer[20]; - char ManufactureUrl[20]; - char Voltage[20]; - char Clock[20]; - char ProgramIOMethod[20]; - - size_t ManufactureID; - size_t JedecDeviceID; - size_t AlternativeID; - - size_t ChipSizeInByte; - size_t SectorSizeInByte; - size_t PageSizeInByte; - size_t BlockSizeInByte; - - size_t MaxErasableSegmentInByte; - - size_t AddrWidth; - - bool DualID; - size_t VppSupport; - bool MXIC_WPmode; - size_t IDNumber; - size_t RDIDCommand; - size_t Timeout; -}; - enum { SITE_NORMAL = 0, SITE_BUSY, @@ -377,4 +546,38 @@ typedef enum { } VCC_VALUE; +typedef enum +{ + IO_Single = 0x00, + IO_Dual1 =0x01, + IO_Dual2 =0x02,//sf600 not support 122 + IO_Quad1 =0x03, + IO_Quad2 =0x04, + IO_Quad3 =0x05, // Quad command 4-4-4 + IO_Octa1 =0x89, // Octal command for Macronix (888) + IO_Octa2 =0x88, // Octal command for Micron (888) +} IO_VALUE; + + +enum { // value dedicated by the spec + STARTUP_APPLI_SF_1 = 0, + STARTUP_APPLI_CARD = 1, + STARTUP_APPLI_SF_2 = 2, + STARTUP_APPLI_SF_SKT = 3, + + STARTUP_SPECIFY_LATER = 0xFE, + STARTUP_PREVIOUS = 0xFF +}; + +enum { + clk_24M = 0x00, + clk_8M = 0x01, + clk_12M = 0x02, + clk_3M = 0x03, + clk_2180K = 0x04, + clk_1500K = 0x05, + clk_750K = 0x06, + clk_375K = 0x07, +}; + #endif //_MACRO_H diff --git a/Makefile b/Makefile index 139e5c0..c4a1677 100644 --- a/Makefile +++ b/Makefile @@ -12,17 +12,17 @@ endif endif PROGRAM = dpcmd -CC = gcc +CC ?= gcc PREFIX ?= /usr/local PKG_CONFIG ?= pkg-config CFLAGS ?= -O2 -Wall -std=gnu99 -CFLAGS += $(shell $(PKG_CONFIG) --cflags libusb-1.0) +CFLAGS += $(shell $(PKG_CONFIG) --cflags libusb-1.0 libxml-2.0) LDFLAGS ?= LDFLAGS += -lpthread -LDFLAGS += $(shell $(PKG_CONFIG) --libs libusb-1.0) +LDFLAGS += $(shell $(PKG_CONFIG) --libs libusb-1.0 libxml-2.0) DEPDIR := .deps DEPFLAGS = -MT $@ -MMD -MP -MF $(DEPDIR)/$*.d @@ -58,7 +58,9 @@ install: $(PROGRAM) [ $(shell id -u) -eq 0 ] || (echo "Error: install needs root privileges" && false) install -v -o 0 -g 0 -m 755 -d $(DESTDIR)$(PREFIX)/bin $(DESTDIR)$(PREFIX)/share/DediProg echo -n "install: " && install -v -o 0 -g 0 -m 0755 $(PROGRAM) $(DESTDIR)$(PREFIX)/bin/$(PROGRAM) +ifneq ($(NOSTRIP),1) strip $(DESTDIR)$(PREFIX)/bin/$(PROGRAM) +endif install -v -o 0 -g 0 -m 755 -d $(DESTDIR)$(PREFIX)/share/DediProg echo -n "install: " && install -v -o 0 -g 0 -m 0644 ChipInfoDb.dedicfg $(DESTDIR)$(PREFIX)/share/DediProg/ChipInfoDb.dedicfg install -v -o 0 -g 0 -m 755 -d $(DESTDIR)/etc/udev/rules.d diff --git a/MotorolaFile.c b/MotorolaFile.c index b276b36..fce4b31 100755 --- a/MotorolaFile.c +++ b/MotorolaFile.c @@ -110,8 +110,8 @@ bool S19FileToBin(const char* filePath, unsigned char* vData, unsigned long* Fil FILE* Filin; /* input files */ /* size in bytes */ - const long MEMORY_SIZE = 1024 * 1024 * 4; - const long ADDRESS_MASK = 0x003FFFFF; + const long MEMORY_SIZE = 1024 * 1024 * 256; + const long ADDRESS_MASK = 0xFFFFFFFF; const int MAX_LINE_SIZE = 512; const int CKS_8 = 0; diff --git a/README.md b/README.md index 3584add..3e8b107 100755 --- a/README.md +++ b/README.md @@ -4,12 +4,18 @@ Linux software for Dediprog SF100 and SF600 SPI flash programmers ## Building To compile the project, first install required dependencies: - libusb-1.0 + - libxml-2.0 + - pkg-config - won't link to libusb without this package Change to the directory where the sources are located and build using make: ```bash $ cd SF100Linux $ make ``` +or use +```bash +$ make install +``` The resulting binary should be called `dpcmd` and located in the root of the source tree. There is no install target at the moment. diff --git a/SerialFlash.c b/SerialFlash.c index 9d462b7..9314e92 100755 --- a/SerialFlash.c +++ b/SerialFlash.c @@ -2,7 +2,9 @@ #include "ChipInfoDb.h" #include "FlashCommand.h" #include "project.h" +#include "dpcmd.h" #include "usbdriver.h" +#include "board.h" #include #include @@ -10,11 +12,19 @@ extern int m_isCanceled; extern int m_bProtectAfterWritenErase; extern int m_boEnReadQuadIO; extern int m_boEnWriteQuadIO; -extern CHIP_INFO Chip_Info; +extern bool g_bSpareAreaUseFile; +extern bool g_bNandForceErase; +extern CHIP_INFO g_ChipInfo; +extern struct CNANDContext g_NANDContext; +extern bool g_bNandInternalECC; +extern int g_iNandBadBlockManagement; +extern struct BadBlockTable g_BBT[16]; extern volatile bool g_bIsSF600[16]; extern volatile bool g_bIsSF700[16]; extern volatile bool g_bIsSF600PG2[16]; +extern unsigned char *pBufferforLoadedFile; extern bool Is_NewUSBCommand(int Index); +extern unsigned int CRC32(unsigned char* v, unsigned long size); unsigned char mcode_WRSR = 0x01; unsigned char mcode_WRDI = 0x04; @@ -81,7 +91,7 @@ bool AT45doRDSR(unsigned char* cSR, int Index) bool AT45WaitForWIP(int USBIndex) { unsigned char cSR; - size_t i = Chip_Info.Timeout * 100; + size_t i = g_ChipInfo.Timeout * 100; if (i == 0) i = 0x10000; // wait until WIP = 0 @@ -114,7 +124,7 @@ unsigned char getWriteMode(int USBIndex) AT45DB642D = 0x1F28, }; - switch (Chip_Info.UniqueID) { + switch (g_ChipInfo.UniqueID) { case AT45DB011D: case AT45DB021D: case AT45DB041D: @@ -144,9 +154,9 @@ void SetPageSize(CHIP_INFO* mem, int USBIndex) mem->PageSizeInByte = pageSize[writeMode]; if (!(writeMode & 0x1)) // for AT45DB:0x1F2200 - 0x1F2800 - mem->ChipSizeInByte = Chip_Info.ChipSizeInByte / 256 * 8 + Chip_Info.ChipSizeInByte; + mem->ChipSizeInByte = g_ChipInfo.ChipSizeInByte / 256 * 8 + g_ChipInfo.ChipSizeInByte; else - mem->ChipSizeInByte = Chip_Info.ChipSizeInByte; + mem->ChipSizeInByte = g_ChipInfo.ChipSizeInByte; AT45ChipSize = mem->ChipSizeInByte; AT45PageSize = mem->PageSizeInByte; @@ -268,11 +278,11 @@ bool AT45batchErase(size_t* vAddrs, size_t AddrSize, int USBIndex) CHIP_INFO mem_id; int i; SetPageSize(&mem_id, USBIndex); - if (strcmp(Chip_Info.Class, SUPPORT_ATMEL_45DBxxxB) == 0) { - mem_id.PageSizeInByte = Chip_Info.PageSizeInByte; - mem_id.ChipSizeInByte = Chip_Info.ChipSizeInByte; + if (strcmp(g_ChipInfo.Class, SUPPORT_ATMEL_45DBxxxB) == 0) { + mem_id.PageSizeInByte = g_ChipInfo.PageSizeInByte; + mem_id.ChipSizeInByte = g_ChipInfo.ChipSizeInByte; } - mem_id.SectorSizeInByte = Chip_Info.SectorSizeInByte; + mem_id.SectorSizeInByte = g_ChipInfo.SectorSizeInByte; struct CAddressRange range; @@ -424,11 +434,11 @@ bool AT45chipErase(unsigned int Addr, unsigned int Length, int USBIndex) CHIP_INFO mem_id; SetPageSize(&mem_id, USBIndex); - if (strcmp(Chip_Info.Class, SUPPORT_ATMEL_45DBxxxB) == 0) { - mem_id.PageSizeInByte = Chip_Info.PageSizeInByte; - mem_id.ChipSizeInByte = Chip_Info.ChipSizeInByte; + if (strcmp(g_ChipInfo.Class, SUPPORT_ATMEL_45DBxxxB) == 0) { + mem_id.PageSizeInByte = g_ChipInfo.PageSizeInByte; + mem_id.ChipSizeInByte = g_ChipInfo.ChipSizeInByte; } - mem_id.SectorSizeInByte = Chip_Info.SectorSizeInByte; + mem_id.SectorSizeInByte = g_ChipInfo.SectorSizeInByte; // AT45xxx_protectBlock(false,USBIndex); struct CAddressRange range; @@ -979,7 +989,7 @@ bool S25FSxxS_Large_doRDCF3V(unsigned char *cSR, int Index) bool S70FSxxx_Large_waitForWIP(bool die1, int Index) { unsigned char cSR; - size_t i = Chip_Info.Timeout * 100; + size_t i = g_ChipInfo.Timeout * 100; if (i == 0) i = MAX_TRIALS; // wait until WIP = 0 @@ -995,7 +1005,7 @@ bool S70FSxxx_Large_waitForWIP(bool die1, int Index) bool SerialFlash_waitForWIP(int Index) { unsigned char cSR; - size_t i = Chip_Info.Timeout * 100; + size_t i = g_ChipInfo.Timeout * 100; if (i == 0) i = MAX_TRIALS; // wait until WIP = 0 @@ -1128,7 +1138,7 @@ bool AT26Fxxx_protectBlock(int bProtect, int Index) UNPROTECTSECTOR = 0x39, // Write Disable READPROTECTIONREGISTER = 0x3C, // Write Disable }; - if (AT26DF041 == Chip_Info.UniqueID) + if (AT26DF041 == g_ChipInfo.UniqueID) return true; // feature is not supported on this chip bool result = false; @@ -1154,7 +1164,7 @@ bool AT26Fxxx_protectBlock(int bProtect, int Index) vInstruction[0] = bProtect ? PROTECTSECTOR : UNPROTECTSECTOR; size_t iUniformSectorSize = 0x10000; // always regarded as 64K - size_t cnt = Chip_Info.ChipSizeInByte / iUniformSectorSize; + size_t cnt = g_ChipInfo.ChipSizeInByte / iUniformSectorSize; size_t i; for (i = 0; i < cnt; ++i) { SerialFlash_doWREN(Index); @@ -1177,7 +1187,7 @@ bool AT26Fxxx_protectBlock(int bProtect, int Index) return false; } - if (AT26DF081A == Chip_Info.UniqueID || AT26DF004 == Chip_Info.UniqueID) // 8K each for the last 64K + if (AT26DF081A == g_ChipInfo.UniqueID || AT26DF004 == g_ChipInfo.UniqueID) // 8K each for the last 64K { vInstruction[1] = (unsigned char)(cnt - 1); for (i = 1; i < 8; ++i) { @@ -1260,7 +1270,7 @@ bool CS25FLxxx_LargedoUnlockDYB(unsigned int cSR, int Index) int i; unsigned int topend, bottomstart, end; - if (strstr(Chip_Info.Class, SUPPORT_SPANSION_S25FLxx_Large) != NULL) //256 + if (strstr(g_ChipInfo.Class, SUPPORT_SPANSION_S25FLxx_Large) != NULL) //256 { topend = 0x20000; bottomstart = 0x1fe0000; @@ -1314,19 +1324,19 @@ bool CS25FLxxx_LargedoUnlockDYB(unsigned int cSR, int Index) int SerialFlash_protectBlock(int bProtect, int Index) { - if (strcmp(Chip_Info.Class, SUPPORT_SST_25xFxx) == 0 || strstr(Chip_Info.Class, SUPPORT_SST_25xFxxB) != NULL) // || strstr(Chip_Info.Class,SUPPORT_SST_25xFxxC)!=NULL) + if (strcmp(g_ChipInfo.Class, SUPPORT_SST_25xFxx) == 0 || strstr(g_ChipInfo.Class, SUPPORT_SST_25xFxxB) != NULL) // || strstr(g_ChipInfo.Class,SUPPORT_SST_25xFxxC)!=NULL) return SST25xFxx_protectBlock(bProtect, Index); - else if (strstr(Chip_Info.Class, SUPPORT_SST_25xFxxA) != NULL) + else if (strstr(g_ChipInfo.Class, SUPPORT_SST_25xFxxA) != NULL) return SST25xFxxA_protectBlock(bProtect, Index); - else if (strstr(Chip_Info.Class, SUPPORT_ATMEL_AT25FSxxx) != NULL || strstr(Chip_Info.Class, SUPPORT_ATMEL_AT25Fxxx) != NULL) + else if (strstr(g_ChipInfo.Class, SUPPORT_ATMEL_AT25FSxxx) != NULL || strstr(g_ChipInfo.Class, SUPPORT_ATMEL_AT25Fxxx) != NULL) return AT25FSxxx_protectBlock(bProtect, Index); - else if (strstr(Chip_Info.Class, SUPPORT_ATMEL_AT26xxx) != NULL) + else if (strstr(g_ChipInfo.Class, SUPPORT_ATMEL_AT26xxx) != NULL) return AT26Fxxx_protectBlock(bProtect, Index); - else if (strstr(Chip_Info.Class, SUPPORT_MACRONIX_MX25Lxxx) != NULL || strstr(Chip_Info.Class, SUPPORT_MACRONIX_MX25Lxxx_Large) != NULL) { + else if (strstr(g_ChipInfo.Class, SUPPORT_MACRONIX_MX25Lxxx) != NULL || strstr(g_ChipInfo.Class, SUPPORT_MACRONIX_MX25Lxxx_Large) != NULL) { unsigned char tmpSRVal; bool result; result = CMX25LxxxdoRDSCUR(&tmpSRVal, Index); - if (result == true && (tmpSRVal & 0x80) && Chip_Info.MXIC_WPmode == true) { + if (result == true && (tmpSRVal & 0x80) && g_ChipInfo.MXIC_WPmode == true) { if (bProtect != false) return true; SerialFlash_doWREN(Index); @@ -1334,11 +1344,11 @@ int SerialFlash_protectBlock(int bProtect, int Index) unsigned char v = GBULK; return FlashCommand_SendCommand_OutOnlyInstruction(&v, 1, Index); } - } else if (strstr(Chip_Info.Class, SUPPORT_SPANSION_S25FLxx) != NULL || strstr(Chip_Info.Class, SUPPORT_SPANSION_S25FLxx_Large) != NULL) { - if (bProtect == false && strstr(Chip_Info.TypeName, "Secure") != NULL) { + } else if (strstr(g_ChipInfo.Class, SUPPORT_SPANSION_S25FLxx) != NULL || strstr(g_ChipInfo.Class, SUPPORT_SPANSION_S25FLxx_Large) != NULL) { + if (bProtect == false && strstr(g_ChipInfo.TypeName, "Secure") != NULL) { CS25FLxxx_LargedoUnlockDYB(0, Index); } - } else if (strstr(Chip_Info.Class, SUPPORT_SST_26xFxxC) != NULL) { + } else if (strstr(g_ChipInfo.Class, SUPPORT_SST_26xFxxC) != NULL) { unsigned char v = 0x98; SerialFlash_waitForWEL(Index); FlashCommand_SendCommand_OutOnlyInstruction(&v, 1, Index); @@ -1665,7 +1675,7 @@ bool CN25Qxxx_MutipleDIe_LargeWREAR(unsigned char cSR, int Index) bool CS25FLxx_LargeEnable4ByteAddrMode(bool Enable4Byte, int Index) { - if ((strstr(Chip_Info.TypeName, "S25FL512Sxxxxxx1x") != NULL) || (strstr(Chip_Info.TypeName, "S25FL512Sxxxxxx1x(Secure)") != NULL)) { + if ((strstr(g_ChipInfo.TypeName, "S25FL512Sxxxxxx1x") != NULL) || (strstr(g_ChipInfo.TypeName, "S25FL512Sxxxxxx1x(Secure)") != NULL)) { SerialFlash_waitForWEL(Index); if (Enable4Byte) { unsigned char v[2]; @@ -1788,15 +1798,15 @@ int S70FSxxx_Large_Enable4ByteAddrMode(int Enable4Byte, int Index) //Simon: unused ??? int SerialFlash_Enable4ByteAddrMode(int bEnable, int Index) { - if (strstr(Chip_Info.Class, SUPPORT_EON_EN25QHxx_Large) != NULL || strstr(Chip_Info.Class, SUPPORT_MACRONIX_MX25Lxxx_Large) != NULL || strstr(Chip_Info.Class, SUPPORT_WINBOND_W25Pxx_Large) != NULL || strstr(Chip_Info.Class, SUPPORT_WINBOND_W25Qxx_Large) != NULL) + if (strstr(g_ChipInfo.Class, SUPPORT_EON_EN25QHxx_Large) != NULL || strstr(g_ChipInfo.Class, SUPPORT_MACRONIX_MX25Lxxx_Large) != NULL || strstr(g_ChipInfo.Class, SUPPORT_WINBOND_W25Pxx_Large) != NULL || strstr(g_ChipInfo.Class, SUPPORT_WINBOND_W25Qxx_Large) != NULL) return CEN25QHxx_LargeEnable4ByteAddrMode(bEnable, Index); - else if (strstr(Chip_Info.Class, SUPPORT_SPANSION_S70FSxx_Large) != NULL) + else if (strstr(g_ChipInfo.Class, SUPPORT_SPANSION_S70FSxx_Large) != NULL) return S70FSxxx_Large_Enable4ByteAddrMode(bEnable, Index); - else if (strstr(Chip_Info.Class, SUPPORT_NUMONYX_N25Qxxx_Large) != NULL) + else if (strstr(g_ChipInfo.Class, SUPPORT_NUMONYX_N25Qxxx_Large) != NULL) return CN25Qxxx_LargeEnable4ByteAddrMode(bEnable, Index); - else if (strstr(Chip_Info.Class, SUPPORT_SPANSION_S25FLxx_Large) != NULL) + else if (strstr(g_ChipInfo.Class, SUPPORT_SPANSION_S25FLxx_Large) != NULL) return CS25FLxx_LargeEnable4ByteAddrMode(bEnable, Index); - else if(Chip_Info.ChipSizeInByte > 0x1000000) + else if(g_ChipInfo.ChipSizeInByte > 0x1000000) return Universal_LargeEnable4ByteAddrMode(bEnable, Index); return SerialFlash_TRUE; @@ -1856,23 +1866,23 @@ int SerialFlash_rangeBlankCheck(struct CAddressRange* Range, int Index) */ int SerialFlash_rangeProgram(struct CAddressRange* AddrRange, unsigned char* vData, int Index) { - if (strstr(Chip_Info.Class, SUPPORT_ATMEL_45DBxxxB) != NULL || strstr(Chip_Info.Class, SUPPORT_ATMEL_45DBxxxD) != NULL) + if (strstr(g_ChipInfo.Class, SUPPORT_ATMEL_45DBxxxB) != NULL || strstr(g_ChipInfo.Class, SUPPORT_ATMEL_45DBxxxD) != NULL) return AT45rangeProgram(AddrRange, vData, mcode_Program, mcode_ProgramCode_4Adr, Index); - else if (strstr(Chip_Info.Class, SUPPORT_SPANSION_S25FLxx_Large) != NULL) { + else if (strstr(g_ChipInfo.Class, SUPPORT_SPANSION_S25FLxx_Large) != NULL) { if ((g_bIsSF600[Index] == true) || (g_bIsSF700[Index] == true) || (g_bIsSF600PG2[Index] == true)) return SerialFlash_bulkPipeProgram(AddrRange, vData, mcode_Program, mcode_ProgramCode_4Adr, Index); else return SerialFlash_bulkPipeProgram(AddrRange, vData, PP_4ADDR_256BYTE_12, mcode_ProgramCode_4Adr, Index); - } else if (strstr(Chip_Info.Class, SUPPORT_SPANSION_S25FLxxL_Large) != NULL) { + } else if (strstr(g_ChipInfo.Class, SUPPORT_SPANSION_S25FLxxL_Large) != NULL) { return SerialFlash_bulkPipeProgram(AddrRange, vData, mcode_Program, mcode_ProgramCode_4Adr_12, Index); - } else if (strstr(Chip_Info.Class, SUPPORT_SPANSION_S70FSxx_Large) != NULL) { + } else if (strstr(g_ChipInfo.Class, SUPPORT_SPANSION_S70FSxx_Large) != NULL) { if ((g_bIsSF600[Index] == true) || (g_bIsSF700[Index] == true)|| (g_bIsSF600PG2[Index] == true)) { return SerialFlash_bulkPipeProgram(AddrRange, vData, PP_4ADDR_256BYTE_S70FS01GS, mcode_ProgramCode_4Adr_12, Index); } else return false; - } else if (strstr(Chip_Info.Class, SUPPORT_WINBOND_W25Mxx_Large) != NULL) { + } else if (strstr(g_ChipInfo.Class, SUPPORT_WINBOND_W25Mxx_Large) != NULL) { return SerialFlash_bulkPipeProgram_twoDie(AddrRange, vData, mcode_Program, mcode_ProgramCode_4Adr, Index); - } else if (strstr(Chip_Info.Class, SUPPORT_NUMONYX_N25Qxxx_Large_4Die) != NULL) { + } else if (strstr(g_ChipInfo.Class, SUPPORT_NUMONYX_N25Qxxx_Large_4Die) != NULL) { return SerialFlash_bulkPipeProgram_Micron_4Die(AddrRange, vData, mcode_Program, mcode_ProgramCode_4Adr, Index); } else { return SerialFlash_bulkPipeProgram(AddrRange, vData, mcode_Program, mcode_ProgramCode_4Adr, Index); @@ -1881,21 +1891,21 @@ int SerialFlash_rangeProgram(struct CAddressRange* AddrRange, unsigned char* vDa int SerialFlash_rangeRead(struct CAddressRange* AddrRange, unsigned char* vData, int Index) { - if (strstr(Chip_Info.Class, SUPPORT_SPANSION_S25FLxx_Large) != NULL) { + if (strstr(g_ChipInfo.Class, SUPPORT_SPANSION_S25FLxx_Large) != NULL) { if ((g_bIsSF600[Index] == true) || (g_bIsSF700[Index] == true)|| (g_bIsSF600PG2[Index] == true)) return SerialFlash_bulkPipeRead(AddrRange, vData, BULK_4BYTE_FAST_READ, mcode_ReadCode, Index); else return SerialFlash_bulkPipeRead(AddrRange, vData, BULK_4BYTE_FAST_READ_MICRON, mcode_ReadCode, Index); - } else if (strstr(Chip_Info.Class, SUPPORT_SPANSION_S25FLxxL_Large) != NULL) { + } else if (strstr(g_ChipInfo.Class, SUPPORT_SPANSION_S25FLxxL_Large) != NULL) { return SerialFlash_bulkPipeRead(AddrRange, vData, mcode_Read, mcode_ReadCode, Index); - } else if (strstr(Chip_Info.Class, SUPPORT_SPANSION_S70FSxx_Large) != NULL) { + } else if (strstr(g_ChipInfo.Class, SUPPORT_SPANSION_S70FSxx_Large) != NULL) { if ((g_bIsSF600[Index] == true) || (g_bIsSF700[Index] == true)|| (g_bIsSF600PG2[Index] == true)) return SerialFlash_bulkPipeRead(AddrRange, vData, BULK_4BYTE_FAST_READ, mcode_ReadCode_0C, Index); else return false; - } else if (strstr(Chip_Info.Class, SUPPORT_WINBOND_W25Mxx_Large) != NULL) { + } else if (strstr(g_ChipInfo.Class, SUPPORT_WINBOND_W25Mxx_Large) != NULL) { return SerialFlash_bulkPipeRead_twoDie(AddrRange, vData, (unsigned char)mcode_Read, (unsigned char)mcode_ReadCode_0C, Index); - } else if (strstr(Chip_Info.Class, SUPPORT_NUMONYX_N25Qxxx_Large_4Die) != NULL) { + } else if (strstr(g_ChipInfo.Class, SUPPORT_NUMONYX_N25Qxxx_Large_4Die) != NULL) { return SerialFlash_bulkPipeRead_Micron_4die(AddrRange, vData, (unsigned char)mcode_Read, (unsigned char)mcode_ReadCode_0C, Index); } else return SerialFlash_bulkPipeRead(AddrRange, vData, (unsigned char)mcode_Read, (unsigned char)mcode_ReadCode, Index); @@ -2047,7 +2057,7 @@ int SerialFlash_batchErase(uintptr_t* vAddrs, size_t AddrSize, int Index) rq.Length = 5; for (i = 0; i < AddrSize; i++) { SerialFlash_waitForWEL(Index); - if (Chip_Info.ChipSizeInByte > 0x1000000) { + if (g_ChipInfo.ChipSizeInByte > 0x1000000) { // MSB~ LSB (31...0) vInstruction[1] = (unsigned char)((vAddrs[i] >> 24) & 0xff); //MSB vInstruction[2] = (unsigned char)((vAddrs[i] >> 16) & 0xff); //M @@ -2073,7 +2083,7 @@ int SerialFlash_batchErase(uintptr_t* vAddrs, size_t AddrSize, int Index) int SerialFlash_rangeErase(unsigned char cmd, size_t sectionSize, struct CAddressRange* AddrRange, int Index) { - if (strstr(Chip_Info.Class, SUPPORT_ATMEL_45DBxxxB) != NULL || strstr(Chip_Info.Class, SUPPORT_ATMEL_45DBxxxD) != NULL) + if (strstr(g_ChipInfo.Class, SUPPORT_ATMEL_45DBxxxB) != NULL || strstr(g_ChipInfo.Class, SUPPORT_ATMEL_45DBxxxD) != NULL) return AT45rangSectorErase(sectionSize, *AddrRange, Index); if (SerialFlash_protectBlock(false, Index) == SerialFlash_FALSE) @@ -2106,7 +2116,7 @@ int SerialFlash_rangeErase(unsigned char cmd, size_t sectionSize, struct CAddres // MSB~ LSB (23...0) size_t addr = (AddrRange->start + i * sectionSize); - if (Chip_Info.ChipSizeInByte > 0x1000000) { + if (g_ChipInfo.ChipSizeInByte > 0x1000000) { // MSB~ LSB (31...0) vInstruction[1] = (unsigned char)((addr >> 24) & 0xff); //MSB vInstruction[2] = (unsigned char)((addr >> 16) & 0xff); //M @@ -2193,12 +2203,12 @@ bool SerialFlash_chipErase(int Index) { if (!SerialFlash_StartofOperation(Index)) return false; - if (strstr(Chip_Info.Class, SUPPORT_ATMEL_45DBxxxB) != NULL || strstr(Chip_Info.Class, SUPPORT_ATMEL_45DBxxxD) != NULL) - return AT45chipErase(0, Chip_Info.ChipSizeInByte, Index); - if (strstr(Chip_Info.Class, SUPPORT_SPANSION_S70FSxx_Large) != NULL) - return S70FSxxx_Large_chipErase(0, Chip_Info.ChipSizeInByte, Index); - if (strstr(Chip_Info.Class, SUPPORT_WINBOND_W25Mxx_Large) != NULL) - return W25Mxx_Large_chipErase(0, Chip_Info.ChipSizeInByte, Index); + if (strstr(g_ChipInfo.Class, SUPPORT_ATMEL_45DBxxxB) != NULL || strstr(g_ChipInfo.Class, SUPPORT_ATMEL_45DBxxxD) != NULL) + return AT45chipErase(0, g_ChipInfo.ChipSizeInByte, Index); + if (strstr(g_ChipInfo.Class, SUPPORT_SPANSION_S70FSxx_Large) != NULL) + return S70FSxxx_Large_chipErase(0, g_ChipInfo.ChipSizeInByte, Index); + if (strstr(g_ChipInfo.Class, SUPPORT_WINBOND_W25Mxx_Large) != NULL) + return W25Mxx_Large_chipErase(0, g_ChipInfo.ChipSizeInByte, Index); if (SerialFlash_protectBlock(false, Index) == SerialFlash_FALSE) return false; @@ -2227,8 +2237,8 @@ int SerialFlash_DieErase(int Index) unsigned char re; vInstruction[0] = mcode_ChipErase; - size_t dieNum = ((strstr(Chip_Info.Class, "2Die") != NULL) ? 2 : 4); - size_t die_size = Chip_Info.ChipSizeInByte / dieNum; + size_t dieNum = ((strstr(g_ChipInfo.Class, "2Die") != NULL) ? 2 : 4); + size_t die_size = g_ChipInfo.ChipSizeInByte / dieNum; size_t i; for (i = 0; i < dieNum; i++) { SerialFlash_waitForWEL(Index); @@ -2272,9 +2282,9 @@ int SerialFlash_bulkPipeProgram(struct CAddressRange* AddrRange, unsigned char* divider = 7; break; case PP_PROGRAM_ANYSIZE_PAGESIZE: - if(Chip_Info.PageSizeInByte == 0x200) + if(g_ChipInfo.PageSizeInByte == 0x200) divider = 9; - else if(Chip_Info.PageSizeInByte == 0x400) + else if(g_ChipInfo.PageSizeInByte == 0x400) divider = 10; else divider = 8; @@ -2284,7 +2294,7 @@ int SerialFlash_bulkPipeProgram(struct CAddressRange* AddrRange, unsigned char* break; } - if (strstr(Chip_Info.Class, SUPPORT_SPANSION_S25FLxxS_Large) != NULL) + if (strstr(g_ChipInfo.Class, SUPPORT_SPANSION_S25FLxxS_Large) != NULL) { unsigned char cSR; S25FSxxS_Large_doRDCF3V(&cSR, Index); @@ -2332,7 +2342,7 @@ int SerialFlash_bulkPipeProgram(struct CAddressRange* AddrRange, unsigned char* down_range.length = down_range.end - down_range.start; packageNum = down_range.length >> divider; - FlashCommand_SendCommand_SetupPacketForBulkWrite(&down_range, modeWrite, WriteCom, Chip_Info.PageSizeInByte, Chip_Info.AddrWidth, Index); + FlashCommand_SendCommand_SetupPacketForBulkWrite(&down_range, modeWrite, WriteCom, g_ChipInfo.PageSizeInByte, g_ChipInfo.AddrWidth, Index); for (i = 0; i < packageNum; ++i) { BulkPipeWrite((unsigned char*)(itr_begin + (i << divider)), 1 << divider, USB_TIMEOUT, Index); if (m_isCanceled) @@ -2342,7 +2352,7 @@ int SerialFlash_bulkPipeProgram(struct CAddressRange* AddrRange, unsigned char* } } else { size_t packageNum = (AddrRange->end - AddrRange->start) >> divider; - FlashCommand_SendCommand_SetupPacketForBulkWrite(AddrRange, modeWrite, WriteCom, 1 << divider, Chip_Info.AddrWidth, Index); + FlashCommand_SendCommand_SetupPacketForBulkWrite(AddrRange, modeWrite, WriteCom, 1 << divider, g_ChipInfo.AddrWidth, Index); for (i = 0; i < packageNum; ++i) { BulkPipeWrite((unsigned char*)((itr_begin + (i << divider))), 1 << divider, USB_TIMEOUT, Index); if (m_isCanceled) @@ -2439,7 +2449,7 @@ int SerialFlash_bulkPipeProgram_Micron_4Die(struct CAddressRange* AddrRange, uns down_range.length = down_range.end - down_range.start; packageNum = down_range.length >> divider; - FlashCommand_SendCommand_SetupPacketForBulkWrite(&down_range, modeWrite, WriteCom, Chip_Info.PageSizeInByte, Chip_Info.AddrWidth, Index); + FlashCommand_SendCommand_SetupPacketForBulkWrite(&down_range, modeWrite, WriteCom, g_ChipInfo.PageSizeInByte, g_ChipInfo.AddrWidth, Index); for (i = 0; i < packageNum; ++i) { BulkPipeWrite((unsigned char*)(itr_begin + (i << divider)), 1 << divider, USB_TIMEOUT, Index); if (m_isCanceled) @@ -2470,7 +2480,7 @@ int SerialFlash_bulkPipeProgram_Micron_4Die(struct CAddressRange* AddrRange, uns down_range.start=AddrRange->start-(0x1000000*EAR); size_t packageNum = (down_range.end - down_range.start) >> divider; - FlashCommand_SendCommand_SetupPacketForBulkWrite(&down_range, modeWrite, WriteCom, Chip_Info.PageSizeInByte, Chip_Info.AddrWidth, Index); + FlashCommand_SendCommand_SetupPacketForBulkWrite(&down_range, modeWrite, WriteCom, g_ChipInfo.PageSizeInByte, g_ChipInfo.AddrWidth, Index); for (i = 0; i < packageNum; ++i) { BulkPipeWrite((unsigned char*)((itr_begin + (i << divider))), 1 << divider, USB_TIMEOUT, Index); if (m_isCanceled) @@ -2574,7 +2584,7 @@ int SerialFlash_bulkPipeProgram_twoDie(struct CAddressRange* AddrRange, unsigned down_range.length = down_range.end - down_range.start; packageNum = down_range.length >> divider; - FlashCommand_SendCommand_SetupPacketForBulkWrite(&down_range_die2, modeWrite, WriteCom, Chip_Info.PageSizeInByte,Chip_Info.AddrWidth, Index); + FlashCommand_SendCommand_SetupPacketForBulkWrite(&down_range_die2, modeWrite, WriteCom, g_ChipInfo.PageSizeInByte,g_ChipInfo.AddrWidth, Index); for (i = 0; i < packageNum; ++i) { BulkPipeWrite((unsigned char*)(itr_begin + (i << divider)), 1 << divider, USB_TIMEOUT, Index); if (m_isCanceled) @@ -2599,7 +2609,7 @@ int SerialFlash_bulkPipeProgram_twoDie(struct CAddressRange* AddrRange, unsigned } size_t packageNum = (AddrRange->end - AddrRange->start) >> divider; - FlashCommand_SendCommand_SetupPacketForBulkWrite(&down_range_die2, modeWrite, WriteCom, Chip_Info.PageSizeInByte, Chip_Info.AddrWidth, Index); + FlashCommand_SendCommand_SetupPacketForBulkWrite(&down_range_die2, modeWrite, WriteCom, g_ChipInfo.PageSizeInByte, g_ChipInfo.AddrWidth, Index); for (i = 0; i < packageNum; ++i) { BulkPipeWrite((unsigned char*)((itr_begin + (i << divider))), 1 << divider, USB_TIMEOUT, Index); if (m_isCanceled) @@ -2627,7 +2637,7 @@ int SerialFlash_bulkPipeRead(struct CAddressRange* AddrRange, unsigned char* vDa int ret = 0; if (!SerialFlash_StartofOperation(Index)) return false; - if (!(strstr(Chip_Info.Class, SUPPORT_NUMONYX_N25Qxxx_Large_2Die) != NULL && strstr(Chip_Info.Class, SUPPORT_NUMONYX_N25Qxxx_Large_4Die) != NULL && ((g_bIsSF600[Index] == true) || (g_bIsSF700[Index] == true)|| (g_bIsSF600PG2[Index] == true)))) + if (!(strstr(g_ChipInfo.Class, SUPPORT_NUMONYX_N25Qxxx_Large_2Die) != NULL && strstr(g_ChipInfo.Class, SUPPORT_NUMONYX_N25Qxxx_Large_4Die) != NULL && ((g_bIsSF600[Index] == true) || (g_bIsSF700[Index] == true)|| (g_bIsSF600PG2[Index] == true)))) SerialFlash_Enable4ByteAddrMode(true, Index); if (SerialFlash_EnableQuadIO(true, m_boEnReadQuadIO, Index) == SerialFlash_FALSE) @@ -2649,7 +2659,7 @@ int SerialFlash_bulkPipeRead(struct CAddressRange* AddrRange, unsigned char* vDa loop = (range_temp.end - range_temp.start) / 0x1000000; for (j = 0; j < loop; j++) { - if (((g_bIsSF600[Index] == false) && (g_bIsSF700[Index] == false)&& (g_bIsSF600PG2[Index] == false)) && (strstr(Chip_Info.Class, SUPPORT_NUMONYX_N25Qxxx_Large_2Die) != NULL || strstr(Chip_Info.Class, SUPPORT_NUMONYX_N25Qxxx_Large_4Die) != NULL)) // for sf100 + if (((g_bIsSF600[Index] == false) && (g_bIsSF700[Index] == false)&& (g_bIsSF600PG2[Index] == false)) && (strstr(g_ChipInfo.Class, SUPPORT_NUMONYX_N25Qxxx_Large_2Die) != NULL || strstr(g_ChipInfo.Class, SUPPORT_NUMONYX_N25Qxxx_Large_4Die) != NULL)) // for sf100 { unsigned char re = 0; int numOfRetry = 5; @@ -2680,7 +2690,7 @@ int SerialFlash_bulkPipeRead(struct CAddressRange* AddrRange, unsigned char* vDa read_range.length = read_range.end - read_range.start; pageNum = read_range.length >> 9; - FlashCommand_SendCommand_SetupPacketForBulkRead(&read_range, modeRead, ReadCom, Chip_Info.AddrWidth,Chip_Info.ReadDummyLen, Index); + FlashCommand_SendCommand_SetupPacketForBulkRead(&read_range, modeRead, ReadCom, g_ChipInfo.AddrWidth,g_ChipInfo.ReadDummyLen, Index); for (i = 0; i < pageNum; ++i) { ret = BulkPipeRead(vData + (BufferLocation + i) * (1<<9), USB_TIMEOUT, Index); if ((ret != (1<<9)) || m_isCanceled) @@ -2691,7 +2701,7 @@ int SerialFlash_bulkPipeRead(struct CAddressRange* AddrRange, unsigned char* vDa } } else { unsigned char EAR = (AddrRange->start * 0x1000000) >> 24; - if (((g_bIsSF600[Index] == false) && (g_bIsSF700[Index] == false) && (g_bIsSF600PG2[Index] == false)) && (strstr(Chip_Info.Class, SUPPORT_NUMONYX_N25Qxxx_Large_2Die) != NULL || strstr(Chip_Info.Class, SUPPORT_NUMONYX_N25Qxxx_Large_4Die) != NULL)) { + if (((g_bIsSF600[Index] == false) && (g_bIsSF700[Index] == false) && (g_bIsSF600PG2[Index] == false)) && (strstr(g_ChipInfo.Class, SUPPORT_NUMONYX_N25Qxxx_Large_2Die) != NULL || strstr(g_ChipInfo.Class, SUPPORT_NUMONYX_N25Qxxx_Large_4Die) != NULL)) { unsigned char re = 0; int numOfRetry = 5; do { @@ -2709,7 +2719,7 @@ int SerialFlash_bulkPipeRead(struct CAddressRange* AddrRange, unsigned char* vDa } } pageNum = AddrRange->length >> 9; - FlashCommand_SendCommand_SetupPacketForBulkRead(AddrRange, modeRead, ReadCom,Chip_Info.AddrWidth,Chip_Info.ReadDummyLen, Index); + FlashCommand_SendCommand_SetupPacketForBulkRead(AddrRange, modeRead, ReadCom,g_ChipInfo.AddrWidth,g_ChipInfo.ReadDummyLen, Index); for (i = 0; i < pageNum; ++i) { ret = BulkPipeRead(vData + i * ret, USB_TIMEOUT, Index); if ((ret != 512) || m_isCanceled) { @@ -2798,7 +2808,7 @@ int SerialFlash_bulkPipeRead_Micron_4die(struct CAddressRange* AddrRange, unsign read_range.length = read_range.end - read_range.start; pageNum = read_range.length >> 9; - FlashCommand_SendCommand_SetupPacketForBulkRead(&read_range, modeRead, ReadCom, Chip_Info.AddrWidth,Chip_Info.ReadDummyLen, Index); + FlashCommand_SendCommand_SetupPacketForBulkRead(&read_range, modeRead, ReadCom, g_ChipInfo.AddrWidth,g_ChipInfo.ReadDummyLen, Index); for (i = 0; i < pageNum; ++i) { ret = BulkPipeRead(vData + (BufferLocation + i) * (1<<9), USB_TIMEOUT, Index); if ((ret != (1<<9)) || m_isCanceled) @@ -2831,7 +2841,7 @@ int SerialFlash_bulkPipeRead_Micron_4die(struct CAddressRange* AddrRange, unsign read_range.end=AddrRange->end-(0x1000000*EAR); read_range.start=AddrRange->start-(0x1000000*EAR); pageNum = read_range.length >> 9; - FlashCommand_SendCommand_SetupPacketForBulkRead(&read_range, modeRead, ReadCom,Chip_Info.AddrWidth,Chip_Info.ReadDummyLen, Index); + FlashCommand_SendCommand_SetupPacketForBulkRead(&read_range, modeRead, ReadCom,g_ChipInfo.AddrWidth,g_ChipInfo.ReadDummyLen, Index); for (i = 0; i < pageNum; ++i) { ret = BulkPipeRead(vData + i * ret, USB_TIMEOUT, Index); if ((ret != 512) || m_isCanceled) { @@ -2909,7 +2919,7 @@ int SerialFlash_bulkPipeRead_twoDie(struct CAddressRange* AddrRange, unsigned ch SerialFlash_doSelectDie(0,Index); } pageNum = read_range.length >> 9; - FlashCommand_SendCommand_SetupPacketForBulkRead(&read_range, modeRead, ReadCom,Chip_Info.AddrWidth,Chip_Info.ReadDummyLen, Index); + FlashCommand_SendCommand_SetupPacketForBulkRead(&read_range, modeRead, ReadCom,g_ChipInfo.AddrWidth,g_ChipInfo.ReadDummyLen, Index); for (i = 0; i < pageNum; ++i) { ret = BulkPipeRead(vData + (BufferLocation + i) * 512, USB_TIMEOUT, Index); if ((ret != 512) || m_isCanceled) @@ -2937,7 +2947,7 @@ int SerialFlash_bulkPipeRead_twoDie(struct CAddressRange* AddrRange, unsigned ch pageNum = range_die2.length >> 9; - FlashCommand_SendCommand_SetupPacketForBulkRead(&range_die2, modeRead, ReadCom,Chip_Info.AddrWidth,Chip_Info.ReadDummyLen, Index); + FlashCommand_SendCommand_SetupPacketForBulkRead(&range_die2, modeRead, ReadCom,g_ChipInfo.AddrWidth,g_ChipInfo.ReadDummyLen, Index); for (i = 0; i < pageNum; ++i) { ret = BulkPipeRead(vData + i * ret, USB_TIMEOUT, Index); @@ -2988,33 +2998,40 @@ int SerialFlash_is_protectbits_set(int Index) } bool SerialFlash_StartofOperation(int Index) { - if (strstr(Chip_Info.Class, SUPPORT_NUMONYX_N25Qxxx_Large_2Die) != NULL || strstr(Chip_Info.Class, SUPPORT_NUMONYX_N25Qxxx_Large_4Die) != NULL || strstr(Chip_Info.Class, SUPPORT_NUMONYX_N25Qxxx_Large) != NULL) { + if (strstr(g_ChipInfo.Class, SUPPORT_NUMONYX_N25Qxxx_Large_2Die) != NULL || strstr(g_ChipInfo.Class, SUPPORT_NUMONYX_N25Qxxx_Large_4Die) != NULL || strstr(g_ChipInfo.Class, SUPPORT_NUMONYX_N25Qxxx_Large) != NULL) { if (CN25Qxxx_Large_doWRVCR(0xFB, Index) == false) return false; if (CN25Qxxx_Large_doWRENVCR(0xFF, Index) == false) return false; return true; - } else if (strstr(Chip_Info.Class, SUPPORT_ST_M25Pxx) != NULL) { - if (strstr(Chip_Info.TypeName, "N25Q064") != NULL) { + } else if (strstr(g_ChipInfo.Class, SUPPORT_ST_M25Pxx) != NULL) { + if (strstr(g_ChipInfo.TypeName, "N25Q064") != NULL) { if (CN25Qxxx_Large_doWRVCR(0xFB, Index) == false) return false; if (CN25Qxxx_Large_doWRENVCR(0xDF, Index) == false) return false; } - if (strstr(Chip_Info.TypeName, "N25Q128") != NULL) { + if (strstr(g_ChipInfo.TypeName, "N25Q128") != NULL) { if (CN25Qxxx_Large_doWRVCR(0xFB, Index) == false) return false; if (CN25Qxxx_Large_doWRENVCR(0xF7, Index) == false) return false; } } - if (strstr(Chip_Info.Class, SUPPORT_MACRONIX_MX25Lxxx_Large) != NULL) { - if ((strstr(Chip_Info.TypeName, "MX66U1G45GXDJ54") != NULL) || (strstr(Chip_Info.TypeName, "MX66U2G45GXRI54") != NULL)) { + if (strstr(g_ChipInfo.Class, SUPPORT_MACRONIX_MX25Lxxx_Large) != NULL) { + if ((strstr(g_ChipInfo.TypeName, "MX66U1G45GXDJ54") != NULL) || (strstr(g_ChipInfo.TypeName, "MX66U2G45GXRI54") != NULL)) { MX25Lxxx_Large_doWRCR(0x70, Index); } } + if((strstr(g_ChipInfo.TypeName,"TC58CVG1S3HRAIG" ) != NULL) ||(strstr(g_ChipInfo.TypeName,"TC58CVG1S3HRAIJ") != NULL) + ||(strstr(g_ChipInfo.TypeName,"TC58CVG0S3HRAIJ") != NULL)) + { + if(!SF_Nand_HSBSet(Index)) + return false; + } + return true; } @@ -3022,3 +3039,1468 @@ bool SerialFlash_EndofOperation(int Index) { return true; } + +void crc16l(WORD *crc, unsigned char rawdata) // +{ + unsigned int i; + for(i=0x80; i!=0; i>>=1) + { + if((*crc&0x8000)!=0) + {*crc<<=1; *crc^=0x1021;} + else + *crc<<=1; + if((rawdata&i)!=0) + *crc^=0x1021; + } + +} + +void CalculateCrc(WORD *crc, unsigned char* start, unsigned int Length) +{ + unsigned int i; + + for (i=0; i>16)|((g_ChipInfo.JedecDeviceID&0xFF00))|((g_ChipInfo.JedecDeviceID&0xFF)<<16)); + nandInfo.ChipIDMask=g_ChipInfo.ChipIDMask; + nandInfo.RealPagesize=g_ChipInfo.PageSizeInByte; //when scan bb, the size not include spare area size + nandInfo.PagesPerBlock=g_ChipInfo.BlockSizeInByte/g_ChipInfo.PageSizeInByte; + nandInfo.Blocks=g_ChipInfo.ChipSizeInByte/g_ChipInfo.BlockSizeInByte; + nandInfo.BlockCount=0; + nandInfo.BlockIndex=0; + + nandInfo.EN_spareArea= g_bSpareAreaUseFile; + nandInfo.MA_pagesize=g_ChipInfo.PageSizeInByte; + nandInfo.BeCmd=g_NANDContext.EraseCmd.ChipErase; + nandInfo.RdCmd=g_NANDContext.ReadCmd.SingleRead; + nandInfo.WrCmd=g_NANDContext.ProgramCmd.SingleProgram;//m_serial.ProgramCode; + nandInfo.AddrLen=g_ChipInfo.AddrWidth; + nandInfo.nCA_Rd=g_ChipInfo.nCA_Rd; + nandInfo.nCA_Wr=g_ChipInfo.nCA_Wr; + nandInfo.Dummy=g_ChipInfo.ReadDummyLen; + nandInfo.MaxERR_bits=g_ChipInfo.DefaultErrorBits; + nandInfo.BBMark=g_ChipInfo.BBMark;//800H is reserved for initial bad block mark + nandInfo.BB_BYTE_TYPE=0x11; //~0xFF + nandInfo.BBM_TYPE=0x00; + nandInfo.BBK_TOTAL=0; + nandInfo.UNprotect_type=1;//m_serial.is_EnableUnprotect; + nandInfo.En_internalECC= 0;//(g_bNandInternalECC)?1:0; + nandInfo.EraseStartBlock=0;//1:default enable + nandInfo.EraseEndBlock=(g_NANDContext.realChipSize/g_NANDContext.realBlockSize); + nandInfo.EraseStatus=0; + nandInfo.saveSTA=0; + nandInfo.rfu0=0; + nandInfo.perPageSizeForErrBit=g_ChipInfo.DefaultDataUnitSize; + if(strstr(g_ChipInfo.TypeName, "GD5F4GM5UExxG") != NULL) + nandInfo.SPA_pagesize=g_ChipInfo.SpareSizeInByte>>16;//g_ChipInfo.SpareSizeInBytem_context->chip.realSpareAreaSize; + else + nandInfo.SPA_pagesize=g_NANDContext.realSpareAreaSize; + + nandInfo.VFMODE= ((1<<3)|(g_ChipInfo.DefaultErrorBits<<8)); + //[3]==1:new: [15:8]Max Error Bit allowed + //[2:0]==MODE 0:DS 1:DSDSDS..DS 2:DDDD...DSSSS...S 3:DDD...D 4: for internal ECC skip + nandInfo.VFCOFGL=nandInfo.SPA_pagesize; + //for mode 0,1,2,3: + //[31:16]: Data Unit size; + //[15:0]: Ecc Unit size; + nandInfo.VFCOFGH=nandInfo.MA_pagesize; + //for mode 4: + //[31:16]: User Data mask + //[15:0]: Internal ECC address mask + nandInfo.staPVpagesize=nandInfo.SPA_pagesize; + nandInfo.staPVpages=nandInfo.MA_pagesize; + nandInfo.staPVsize=nandInfo.staPVpagesize*nandInfo.staPVpages; + + if(isErase == true){ + if(g_bNandForceErase ==true) + nandInfo.EraseMode=1; //force erase + else + nandInfo.EraseMode=2;//skip BB + + nandInfo.StartBB=0;////set 1, start BB scan + nandInfo.saveSTA=0; + }else{ + nandInfo.EraseMode=0; //do not erase, just scan bad block + nandInfo.StartBB=1; + nandInfo.saveSTA=0; // no standalone + } + if(strstr(g_ChipInfo.Class,"W25N512GWxIN")) + nandInfo.ReadSatus_mode=2;//2:w25N512G + else + nandInfo.ReadSatus_mode=1;//1:other + + for(int i=0;i<34;i++) + nandInfo.rfu[i]=0; + + nandInfo.ReadSatus_mode=1;//1:other + memcpy(buf, &nandInfo.Hearder,sizeof(nandInfo)); + WORD crc=0xffff; + CalculateCrc(&crc,buf,sizeof(nandInfo)-2); + nandInfo.crc=crc; + // + memset(buf,0,sizeof(nandInfo)); + memcpy(buf, &nandInfo.Hearder,sizeof(nandInfo)); + + if(!DownloadICInfoForNand(0x200,USBIndex)) + return; + + BulkPipeWrite(buf,sizeof(buf),USB_TIMEOUT,USBIndex); + + #if 0 + printf(" nandInfo.Hearder=0xA1A1;\n "); + printf(" nandInfo.Version=0x01; \n "); + printf(" nandInfo.Type=0x01; \n"); + printf(" nandInfo.STsize=%d; \n",nandInfo.STsize); + printf(" nandInfo.ChipID=0x%x\n",nandInfo.ChipID); + printf(" nandInfo.ChipIDMask=0x%lx\n",g_ChipInfo.ChipIDMask); + printf(" nandInfo.RealPagesize=0x%x\n",nandInfo.RealPagesize); + printf(" nandInfo.PagesPerBlock=0x%x\n",nandInfo.PagesPerBlock); + printf(" nandInfo.Blocks=0x%x\n",nandInfo.Blocks); + printf(" nandInfo.EN_spareArea=0x%x\n",nandInfo.EN_spareArea); + printf(" nandInfo.SPA_pagesize=0x%x\n",nandInfo.SPA_pagesize); + printf(" nandInfo.MA_pagesize=0x%x\n",nandInfo.MA_pagesize); + printf(" nandInfo.BeCmd=0x%x\n",nandInfo.BeCmd); + printf(" nandInfo.RdCmd=0x%x\n",nandInfo.RdCmd); + printf(" nandInfo.WrCmd=0x%x\n",nandInfo.WrCmd); + printf(" nandInfo.AddrLen=0x%x\n",nandInfo.AddrLen); + printf(" nandInfo.nCA_Rd=0x%x\n",nandInfo.nCA_Rd); + printf(" nandInfo.nCA_Wr=0x%x\n",nandInfo.nCA_Wr); + printf(" nandInfo.Dummy=0x%x\n",nandInfo.Dummy); + printf(" nandInfo.MaxERR_bits=0x%x\n",nandInfo.MaxERR_bits); + printf(" nandInfo.BBMark=0x%x\n",nandInfo.BBMark); + printf(" nandInfo.BB_BYTE_TYPE=0x%x\n",nandInfo.BB_BYTE_TYPE); + printf(" nandInfo.BBM_TYPE=0x%x\n",nandInfo.BBM_TYPE); + printf(" nandInfo.BBK_TOTAL=0x%x\n",nandInfo.BBK_TOTAL); + printf(" nandInfo.StartBB=0x%x\n",nandInfo.StartBB); + printf(" nandInfo.UNprotect_type=0x%x\n",nandInfo.UNprotect_type); + printf(" nandInfo.En_internalECC=0x%x\n",nandInfo.En_internalECC); + printf(" nandInfo.EraseStartBlock=0x%x\n",nandInfo.EraseStartBlock); + printf(" nandInfo.EraseEndBlock=0x%x\n",nandInfo.EraseEndBlock); + printf(" nandInfo.EraseMode=0x%x\n",nandInfo.EraseMode); + printf(" nandInfo.EraseStatus=0x%x\n",nandInfo.EraseStatus); + printf(" nandInfo.saveSTA=0x%x\n",nandInfo.saveSTA); + printf(" nandInfo.VFMODE=0x%x\n",nandInfo.VFMODE); + printf(" nandInfo.VFCOFGL=0x%x\n",nandInfo.VFCOFGL); + printf(" nandInfo.VFCOFGH=0x%x\n",nandInfo.VFCOFGH); + printf(" nandInfo.staPVpagesize=0x%x\n",nandInfo.staPVpagesize); + printf(" nandInfo.staPVpages=0x%x\n",nandInfo.staPVpages); + printf(" nandInfo.staPVsize=0x%x\n",nandInfo.staPVsize); + printf(" nandInfo.perPageSizeForErrBit=0x%x\n",nandInfo.perPageSizeForErrBit); + printf(" nandInfo.ReadSatus_mode=0x%x\n",nandInfo.ReadSatus_mode); + printf(" nandInfo.crc=0x%x\n",nandInfo.crc); + #endif +} + +bool SPINAND_ScanBadBlock( unsigned short *BBT, unsigned short *BBT_Cnt, int USBIndex) +{ + if (!SerialFlash_StartofOperation(USBIndex)) + return false; + #if 1 + SELECT_SPI_NAND_INFO nandInfo; + DownloadICInfo( false, USBIndex); + #else + SELECT_SPI_NAND_INFO nandInfo; + nandInfo.Hearder=0xA1A1; + nandInfo.Version=0x01; + nandInfo.Type=0x01; + + nandInfo.STsize=sizeof(nandInfo); + nandInfo.ChipID=(((g_ChipInfo.JedecDeviceID&0xFF0000)>>16)|((g_ChipInfo.JedecDeviceID&0xFF00))|((g_ChipInfo.JedecDeviceID&0xFF)<<16)); + nandInfo.ChipIDMask=g_ChipInfo.ChipIDMask; + + nandInfo.RealPagesize=g_ChipInfo.PageSizeInByte; //when scan bb, the size not include spare area size + + nandInfo.PagesPerBlock=g_ChipInfo.BlockSizeInByte/g_ChipInfo.PageSizeInByte; + nandInfo.Blocks=g_ChipInfo.ChipSizeInByte/g_ChipInfo.BlockSizeInByte; + #if 0 + printf(" nandInfo.Hearder=0xA1A1;\n "); + printf(" nandInfo.Version=0x01; \n "); + printf(" nandInfo.Type=0x01; \n"); + printf(" nandInfo.STsize=%d; \n",nandInfo.STsize); + printf(" nandInfo.ChipID=0x%x\n",nandInfo.ChipID); + printf(" nandInfo.ChipIDMask=0x%lx\n",g_ChipInfo.ChipIDMask); + printf(" nandInfo.RealPagesize=0x%x\n",nandInfo.RealPagesize); + printf(" nandInfo.PagesPerBlock=0x%x\n",nandInfo.PagesPerBlock); + printf(" nandInfo.Blocks=0x%x\n",nandInfo.Blocks); + #endif + nandInfo.BlockCount=0; + nandInfo.BlockIndex=0; + + nandInfo.EN_spareArea= g_bSpareAreaUseFile; + if(strstr(g_ChipInfo.TypeName, "GD5F4GM5UExxG") != NULL) + nandInfo.SPA_pagesize=g_ChipInfo.SpareSizeInByte>>16;//g_ChipInfo.SpareSizeInBytem_context->chip.realSpareAreaSize; + else + nandInfo.SPA_pagesize=g_NANDContext.realSpareAreaSize; + nandInfo.MA_pagesize=g_ChipInfo.PageSizeInByte; + #if 0 + printf(" nandInfo.EN_spareArea=0x%x\n",nandInfo.EN_spareArea); + printf(" nandInfo.SPA_pagesize=0x%x\n",nandInfo.SPA_pagesize); + printf(" nandInfo.MA_pagesize=0x%x\n",nandInfo.MA_pagesize); + #endif + nandInfo.BeCmd=g_NANDContext.EraseCmd.ChipErase; + nandInfo.RdCmd=g_NANDContext.ReadCmd.SingleRead; + nandInfo.WrCmd=g_NANDContext.ProgramCmd.SingleProgram;//m_serial.ProgramCode; + nandInfo.AddrLen=g_ChipInfo.AddrWidth; + nandInfo.nCA_Rd=g_ChipInfo.nCA_Rd; + nandInfo.nCA_Wr=g_ChipInfo.nCA_Wr; + nandInfo.Dummy=g_ChipInfo.ReadDummyLen; + nandInfo.MaxERR_bits=g_ChipInfo.DefaultErrorBits; + #if 0 + printf(" nandInfo.BeCmd=0x%x\n",nandInfo.BeCmd); + printf(" nandInfo.RdCmd=0x%x\n",nandInfo.RdCmd); + printf(" nandInfo.WrCmd=0x%x\n",nandInfo.WrCmd); + printf(" nandInfo.AddrLen=0x%x\n",nandInfo.AddrLen); + printf(" nandInfo.nCA_Rd=0x%x\n",nandInfo.nCA_Rd); + printf(" nandInfo.nCA_Wr=0x%x\n",nandInfo.nCA_Wr); + printf(" nandInfo.Dummy=0x%x\n",nandInfo.Dummy); + printf(" nandInfo.MaxERR_bits=0x%x\n",nandInfo.MaxERR_bits); + #endif + nandInfo.BBMark=g_ChipInfo.BBMark;//800H is reserved for initial bad block mark + nandInfo.BB_BYTE_TYPE=0x11; //~0xFF + nandInfo.BBM_TYPE=0x00; + nandInfo.BBK_TOTAL=0; + #if 0 + printf(" nandInfo.BBMark=0x%x\n",nandInfo.BBMark); + printf(" nandInfo.BB_BYTE_TYPE=0x%x\n",nandInfo.BB_BYTE_TYPE); + printf(" nandInfo.BBM_TYPE=0x%x\n",nandInfo.BBM_TYPE); + printf(" nandInfo.BBK_TOTAL=0x%x\n",nandInfo.BBK_TOTAL); + #endif + nandInfo.StartBB=1; + nandInfo.UNprotect_type=1;//m_serial.is_EnableUnprotect; + nandInfo.En_internalECC= 0;//(g_bNandInternalECC)?1:0; + nandInfo.EraseStartBlock=0;//1:default enable + nandInfo.EraseEndBlock=(g_NANDContext.realChipSize/g_NANDContext.realBlockSize); + nandInfo.EraseMode=0; //do not erase + nandInfo.EraseStatus=0; + nandInfo.saveSTA=0; + #if 0 + printf(" nandInfo.StartBB=0x%x\n",nandInfo.StartBB); + printf(" nandInfo.UNprotect_type=0x%x\n",nandInfo.UNprotect_type); + printf(" nandInfo.En_internalECC=0x%x\n",nandInfo.En_internalECC); + printf(" nandInfo.EraseStartBlock=0x%x\n",nandInfo.EraseStartBlock); + printf(" nandInfo.EraseEndBlock=0x%x\n",nandInfo.EraseEndBlock); + printf(" nandInfo.EraseMode=0x%x\n",nandInfo.EraseMode); + printf(" nandInfo.EraseStatus=0x%x\n",nandInfo.EraseStatus); + printf(" nandInfo.saveSTA=0x%x\n",nandInfo.saveSTA); + #endif + nandInfo.rfu0=0; + nandInfo.perPageSizeForErrBit=g_ChipInfo.DefaultDataUnitSize; + + if(strstr(g_ChipInfo.Class,"W25N512GWxIN")) + nandInfo.ReadSatus_mode=2;//2:w25N512G + else + nandInfo.ReadSatus_mode=1;//1:other + #if 0 + nandInfo.VFMODE= ((1<<3)|(g_ChipInfo.DefaultErrorBits<<8)); + //[3]==1:new: [15:8]Max Error Bit allowed + //[2:0]==MODE 0:DS 1:DSDSDS..DS 2:DDDD...DSSSS...S 3:DDD...D 4: for internal ECC skip + nandInfo.VFCOFGL=nandInfo.SPA_pagesize; + //for mode 0,1,2,3: + //[31:16]: Data Unit size; + //[15:0]: Ecc Unit size; + nandInfo.VFCOFGH=nandInfo.MA_pagesize; + //for mode 4: + //[31:16]: User Data mask + //[15:0]: Internal ECC address mask + nandInfo.staPVpagesize=0xcdcd;//nandInfo.SPA_pagesize; + nandInfo.staPVpages=0xcdcdcdcd;//nandInfo.MA_pagesize; + nandInfo.staPVsize=0xcdcdcdcd;//nandInfo.staPVpagesize*nandInfo.staPVpages; + printf(" nandInfo.VFMODE=0x%x\n",nandInfo.VFMODE); + printf(" nandInfo.VFCOFGL=0x%x\n",nandInfo.VFCOFGL); + printf(" nandInfo.VFCOFGH=0x%x\n",nandInfo.VFCOFGH); + printf(" nandInfo.staPVpagesize=0x%x\n",nandInfo.staPVpagesize); + printf(" nandInfo.staPVpages=0x%x\n",nandInfo.staPVpages); + printf(" nandInfo.staPVsize=0x%x\n",nandInfo.staPVsize); + #endif + for(int i=0;i<34;i++) + nandInfo.rfu[i]=0; + + nandInfo.ReadSatus_mode=1;//1:other + #if 0 + printf(" nandInfo.perPageSizeForErrBit=0x%x\n",nandInfo.perPageSizeForErrBit); + printf(" nandInfo.ReadSatus_mode=0x%x\n",nandInfo.ReadSatus_mode); + #endif + unsigned char buf[sizeof(nandInfo)]={0}; + memcpy(buf, &nandInfo.Hearder,sizeof(nandInfo)); + WORD crc=0xffff; + CalculateCrc(&crc,buf,sizeof(nandInfo)-2); + nandInfo.crc=crc; + //printf(" nandInfo.crc=0x%x\n",nandInfo.crc); + memset(buf,0,sizeof(nandInfo)); + memcpy(buf, &nandInfo.Hearder,sizeof(nandInfo)); + //printf(" sizeof(nandInfo)=%ld\n", sizeof(nandInfo)); + #endif + Sleep(2000); + Nand_ReadICInfo(&nandInfo,BBT,BBT_Cnt,USBIndex); + return true; +} + +bool DownloadICInfoForNand(DWORD dwInfoLen, int USBIndex)//SF700 +{ + CNTRPIPE_RQ rq ; + + unsigned char vInfoLen[4]; //0x200 + dwInfoLen=dwInfoLen>>9; + vInfoLen[0] = ((unsigned char)(dwInfoLen)); + vInfoLen[1] = ((unsigned char)(dwInfoLen>>8)); + vInfoLen[2] = ((unsigned char)(dwInfoLen>>16)); + vInfoLen[3] = ((unsigned char)(dwInfoLen>>24)); + + rq.Function = URB_FUNCTION_VENDOR_ENDPOINT ; + rq.Direction = VENDOR_DIRECTION_OUT ; + rq.Request = DL_IC_INFO_NAND ; + rq.Value = 0 ; + rq.Index = 0 ; + rq.Length = 1; + + if(!OutCtrlRequest(&rq, vInfoLen, 1,USBIndex)) + return false; + + return true; +} + +bool ReadICInfoForNand(DWORD dwInfoLen, int USBIndex) +{ //SF700 + CNTRPIPE_RQ rq ; + + unsigned char vInfoLen[4]; //0x200 + + vInfoLen[0] = (dwInfoLen); + vInfoLen[1] = (dwInfoLen>>8); + vInfoLen[2] = (dwInfoLen>>16); + vInfoLen[3] = (dwInfoLen>>24); + + rq.Function = URB_FUNCTION_VENDOR_ENDPOINT ; + rq.Direction = VENDOR_DIRECTION_OUT ; + rq.Request = READ_IC_INFO_NAND ; + rq.Value = 0 ; + rq.Index = 0 ; + rq.Length = 4 ; + + if(!OutCtrlRequest(&rq, vInfoLen, sizeof(vInfoLen), USBIndex)) + return false; + return true; +} + + +bool Nand_ReadICInfo(SELECT_SPI_NAND_INFO *nandInfo, unsigned short *BBT, unsigned short *BBT_Cnt,int USBIndex) +{ +#define min(a, b) (a > b ? b : a) + + unsigned char vData[0x400]; + //SELECT_SPI_NAND_INFO nandInfo; + if(!ReadICInfoForNand(0x400,USBIndex)) + return false; + + for(int i=0;i<2;i++) + { + if(!BulkPipeRead(vData+i*0x200, USB_TIMEOUT, USBIndex)) + return false ; + } + memcpy((unsigned char*)&nandInfo->Hearder,vData, sizeof(SELECT_SPI_NAND_INFO)); + //printf("nandInfo.BBK_TOTAL=%d\n",nandInfo->BBK_TOTAL); + memcpy(BBT,vData+0x200,min((nandInfo->BBK_TOTAL*2),0x200)); + *BBT_Cnt = nandInfo->BBK_TOTAL; + //for(unsigned int i=0; i < min((nandInfo.BBK_TOTAL),0x100); i++) + // printf("BBT[%d]=%d\n",i, BBT[i]); + return true; +} + +bool Nand_waitForWEL(int USBIndex) +{ + size_t i = g_ChipInfo.Timeout*100; + unsigned char cSR; + unsigned char vOut[2]; + + vOut[0] = WREN; + if(!FlashCommand_SendCommand_OutOnlyInstruction(vOut,1,USBIndex)) + return false; + Sleep(1); + i = g_ChipInfo.Timeout*100; + do{ + vOut[0] = 0x0F;//.GetFeatures; + vOut[1] = 0xC0;//.push_back(m_context->serialFlash.SRStatus); + if(!FlashCommand_SendCommand_OneOutOneIn(vOut,2,&cSR,1,USBIndex)) + return false; + Sleep(100); + }while(((cSR & 0x02)== 0) && (i-- > 1)) ; + + return true; +} +bool Nand_waitForOIP(int USBIndex) +{ + size_t i = g_ChipInfo.Timeout*100; + unsigned char cSR; + unsigned char vOut[2]; + do{ + vOut[0] = 0x0F;//.GetFeatures; + vOut[1] = 0xC0;//.push_back(m_context->serialFlash.SRStatus); + if(!FlashCommand_SendCommand_OneOutOneIn(vOut,2,&cSR,1,USBIndex)) + return false; + Sleep(100); + }while((cSR & 0x01) && (i-- > 1)) ; + + if((i<=0)||((cSR&0x0C)!=0)) + return false; + + Sleep(2); + return true; +} + +bool Nand_WRSRProtection(unsigned char cSR,int USBIndex) +{ + if(!Nand_waitForWEL(USBIndex)) + return false; + unsigned char vOut[3]; + vOut[0] = 0x1F;//.push_back(m_context->serialFlash.SetFeatures); + vOut[1] = 0xA0;//.push_back(m_context->serialFlash.SRProtection); + vOut[2] = cSR;//.push_back(cSR); + if(!FlashCommand_SendCommand_OutOnlyInstruction(vOut,sizeof(vOut),USBIndex)) + return false; + Sleep(2); + return true; +} + +bool Nand_WRSRFeature1(unsigned char cSR,int USBIndex) +{ + if(!Nand_waitForWEL(USBIndex)) + return false; + unsigned char vOut[3]; + vOut[0] = 0x1F;//.push_back(m_context->serialFlash.SetFeatures); + vOut[1] = 0xB0;//.push_back(m_context->serialFlash.SRFeature1); + vOut[2] = cSR;//.push_back(cSR); + if(!FlashCommand_SendCommand_OutOnlyInstruction(vOut,sizeof(vOut),USBIndex)) + return false; + Sleep(2); + return true; +} +bool Nand_WRSRStatus(unsigned char cSR,int USBIndex) +{ + if(!Nand_waitForWEL(USBIndex)) + return false; + unsigned char vOut[3]; + vOut[0] = 0x1F;//. push_back(m_context->serialFlash.SetFeatures); + vOut[1] = 0xC0;//.push_back(m_context->serialFlash.SRStatus); + vOut[2] = cSR;//.push_back(cSR); + if(!FlashCommand_SendCommand_OutOnlyInstruction(vOut,sizeof(vOut), USBIndex)) + return false; + Sleep(2); + return true; +} +bool Nand_WRSRFeature2(unsigned char cSR,int USBIndex) +{ + if(!Nand_waitForWEL(USBIndex)) + return false; + unsigned char vOut[3]; + vOut[0] = 0x1F;//.push_back(m_context->serialFlash.SetFeatures); + vOut[1] = 0xD0;//.push_back(m_context->serialFlash.SRFeature2); + vOut[2] = cSR;//.push_back(cSR); + if(!FlashCommand_SendCommand_OutOnlyInstruction(vOut, sizeof(vOut), USBIndex)) + return false; + Sleep(2); + return true; +} + +bool Nand_RDSRProtection(unsigned char *cSR,int USBIndex) +{ + unsigned char vOut[2], vIn ; + vOut[0] = 0x0F;//.push_back(m_context->serialFlash.GetFeatures); + vOut[1] = 0xA0;//.push_back(m_context->serialFlash.SRProtection); + if(!FlashCommand_SendCommand_OneOutOneIn(vOut,sizeof(vOut), &vIn, 1, USBIndex)) + return false; + *cSR=vIn; + return true; +} + +bool Nand_RDSRFeature1(unsigned char *cSR,int USBIndex) +{ + unsigned char vOut[2], vIn ; + vOut[0] = 0x0F;//.push_back(m_context->serialFlash.GetFeatures); + vOut[1] = 0xB0;//.push_back(m_context->serialFlash.SRFeature1); + if(!FlashCommand_SendCommand_OneOutOneIn(vOut, sizeof(vOut), &vIn, 1, USBIndex)) + return false; + *cSR=vIn; + return true; +} +bool Nand_RDSRStatus1(unsigned char *cSR,int USBIndex) +{ + unsigned char vOut[2], vIn ; + vOut[0] = 0x0F;//.push_back(m_context->serialFlash.GetFeatures); + vOut[1] = 0xC0;//.push_back(m_context->serialFlash.SRStatus); + if(!FlashCommand_SendCommand_OneOutOneIn(vOut, sizeof(vOut), &vIn, 1, USBIndex)) + return false; + *cSR=vIn; + return true; +} +bool Nand_RDSRFeature2(unsigned char *cSR,int USBIndex) +{ + unsigned char vOut[2], vIn ; + vOut[0] = 0x0F;//.push_back(m_context->serialFlash.GetFeatures); + vOut[1] = 0xD0;//.push_back(m_context->serialFlash.SRFeature2); + if(!FlashCommand_SendCommand_OneOutOneIn(vOut, sizeof(vOut), &vIn, 1, USBIndex)) + return false; + *cSR=vIn; + return true; +} + + +bool Nand_Winbond_RDSR1(unsigned char *cSR,int USBIndex) +{ + unsigned char vOut[2], vIn ; + vOut[0] = 0x0F;//.push_back(m_context->serialFlash.GetFeatures); + vOut[1] = 0xA0;//.push_back(m_context->serialFlash.Winbond_SR1); + if(!FlashCommand_SendCommand_OneOutOneIn(vOut, sizeof(vOut), &vIn, 1, USBIndex)) + return false; + *cSR=vIn; + return true; +} +bool Nand_Winbond_RDSR2(unsigned char *cSR,int USBIndex) +{ + unsigned char vOut[2], vIn ; + vOut[0] = 0x0F;//.push_back(m_context->serialFlash.GetFeatures); + vOut[1] = 0xB0;//.push_back(m_context->serialFlash.Winbond_SR2); + if(!FlashCommand_SendCommand_OneOutOneIn(vOut, sizeof(vOut), &vIn, 1, USBIndex)) + return false; + *cSR=vIn; + return true; +} +bool Nand_Winbond_RDSR3(unsigned char *cSR,int USBIndex) +{ + unsigned char vOut[2], vIn ; + vOut[0] = 0x0F;//.push_back(m_context->serialFlash.GetFeatures); + vOut[1] = 0xC0;//.push_back(m_context->serialFlash.Winbond_SR3); + if(!FlashCommand_SendCommand_OneOutOneIn(vOut, sizeof(vOut), &vIn, 1, USBIndex)) + return false; + *cSR=vIn; + return true; +} + +bool Nand_Winbond_WRSR1(unsigned char cSR,int USBIndex) +{ + if(!Nand_waitForWEL(USBIndex)) + return false; + unsigned char vOut[3]; + vOut[0] = 0x1F;//.push_back(m_context->serialFlash.SetFeatures); + vOut[1] = 0xA0;//.push_back(m_context->serialFlash.Winbond_SR1); + vOut[2] = cSR;//.push_back(cSR); + if(!FlashCommand_SendCommand_OutOnlyInstruction(vOut, sizeof(vOut), USBIndex)) + return false; + return true; +} +bool Nand_Winbond_WRSR2(unsigned char cSR,int USBIndex) +{ + if(!Nand_waitForWEL(USBIndex)) + return false; + unsigned char vOut[3]; + vOut[0] = 0x1F;//.push_back(m_context->serialFlash.SetFeatures); + vOut[1] = 0xB0;//.push_back(m_context->serialFlash.Winbond_SR2); + vOut[2] = cSR;//.push_back(cSR); + if(!FlashCommand_SendCommand_OutOnlyInstruction(vOut, sizeof(vOut), USBIndex)) + return false; + return true; +} + +bool SF_Nand_HSBSet( int Index) +{ + unsigned char cSR=0; + Nand_RDSRFeature1(&cSR,Index); + Nand_WRSRFeature1(cSR&0xFD,Index);//HSB + Nand_RDSRFeature1(&cSR,Index); + + if((cSR&0x02)!=0x00) + return false; + return true; +} + +bool SPINAND_ProtectBlock(bool bProtect,int USBIndex) +{ + //Protect A0H BRWD/Reserved/BP2/BP1/BP0/INV/CMP/Reserve + bool result = false ; + unsigned char tmpSRVal=0; + unsigned char dstSRVal =0; + int numOfRetry = 100 ; + + result = Nand_RDSRProtection(&dstSRVal,USBIndex) ; + + // un-protect block ,set BRWD BP2 BP1 BP0 to 0 + dstSRVal &= (~0xFD) ; + + // protect block ,set BP2 BP1 BP2 to 1 + if(bProtect){ + dstSRVal += 0xFD ; // B8 : 1011 1000 + } + + if((g_ChipInfo.ProtectBlockMask & 0x02) ||((strstr(g_ChipInfo.TypeName,"S35ML01G3") != NULL) ||(strstr(g_ChipInfo.TypeName,"S35ML02G3")!= NULL) + ||(strstr(g_ChipInfo.TypeName, "S35ML04G3")!=NULL))) + { + dstSRVal |= 0x02; + result = Nand_WRSRProtection(dstSRVal,USBIndex) ; + } + do + { // WIP = TRUE; + result &= Nand_WRSRProtection(dstSRVal,USBIndex) ; + result &= Nand_RDSRProtection(&tmpSRVal,USBIndex) ; + + if(! result) + return false; + numOfRetry -- ; + }while( (tmpSRVal & 0x01) && numOfRetry > 0); + + + if((tmpSRVal ^ dstSRVal)& 0x0C ) + return false; + + return true; + +} + +bool Nand_BUFSet( int USBIndex) +{ + unsigned char cSR=0; + Nand_Winbond_RDSR2(&cSR,USBIndex); + cSR&=0xF9; + Nand_Winbond_WRSR2(cSR|0x08,USBIndex); + Nand_Winbond_RDSR2(&cSR,USBIndex); + if((cSR&0x08)!=0x08) + return false; + return true; +} + +bool Nand_CaculateErrorBit(unsigned char *pData, unsigned char *pFile, unsigned int ptr_size) +{ + unsigned int WholeFileLenth = ptr_size;//vData.size(); + //unsigned int UnitCount = 0; + if(g_bSpareAreaUseFile == true) + { + for(unsigned int PageCount=0 ; PageCount< WholeFileLenth/g_NANDContext.realPageSize ; PageCount++) + { + unsigned char aPageSizeReadBuf[g_NANDContext.realPageSize]; + unsigned char aPageSizeFileBuf[g_NANDContext.realPageSize]; + memset(aPageSizeReadBuf, 0xFF, g_NANDContext.realPageSize); + memset(aPageSizeFileBuf, 0xFF, g_NANDContext.realPageSize); + memcpy(aPageSizeReadBuf, pData+PageCount*g_NANDContext.realPageSize, g_NANDContext.realPageSize); + memcpy(aPageSizeFileBuf, pFile+PageCount*g_NANDContext.realPageSize, g_NANDContext.realPageSize); + + unsigned int DataUnitCount = (g_NANDContext.realPageSize/g_ChipInfo.DefaultDataUnitSize); + + for(unsigned int i=0;i>c)&0x01)!=((uc2>>c)&0x01)) + { + if(errorbit>c)&0x01)!=((uc2>>c)&0x01)) + { + if(errorbit>9, mcode_ProgramCode_4Adr,g_NANDContext.realPageSize, + BlockPages,mcode_Program,g_ChipInfo.AddrWidth, g_ChipInfo.ReadDummyLen,g_ChipInfo.nCA_Wr,USBIndex); + size_t WriteCounter=g_NANDContext.realBlockSize>>9 ; + for(size_t i = 0; i < WriteCounter; ++ i) + { + BulkPipeWrite(pBuf, 1<<9, USB_TIMEOUT,USBIndex); + pBuf += (1<<9); + } + free(pBuf); + return true; +} + + +unsigned int SF_GetLoop(const struct CAddressRange* AddrRange, unsigned int uiUnit) +{ + struct CAddressRange AddrLoop;//(*AddrRange); + AddrLoop.start = AddrRange->start; + AddrLoop.end= AddrRange->end; + AddrLoop.start= AddrRange->start-(AddrRange->start%uiUnit); + AddrLoop.end= AddrLoop.end + ((AddrLoop.end % uiUnit)? (uiUnit-(AddrLoop.end % uiUnit)):0); + AddrLoop.length = AddrLoop.end-AddrLoop.start; + unsigned int loop = AddrLoop.length/uiUnit; + return loop; +} + +bool SPINAND_EnableInternalECC(bool is_ENECC,int USBIndex) +{ + unsigned char ucData=0,ucTempData=0; + // if((g_ChipInfo.TypeName,"MX35LF1G24") != NULL)) + // return true; + if(!g_ChipInfo.ECCEnable) + return true; + if(!Nand_RDSRFeature1(&ucData,USBIndex)) + return false; + ucTempData=ucData; + + + if(is_ENECC) + { + if((ucTempData&0x10) == 0x10) + return true; + if(!Nand_WRSRFeature1(ucData|0x10,USBIndex)) + return false; + if(!Nand_RDSRFeature1(&ucTempData,USBIndex)) + return false; + if(ucTempData==(ucData|0x10)) + return true; + else + return false; + } + else + { + ucData&=0xEF; + if(!Nand_WRSRFeature1(ucData,USBIndex)) + return false; + if(!Nand_RDSRFeature1(&ucTempData,USBIndex)) + return false; + if((ucTempData&0x10)==0x10) + return false; + } + return true; +} + +bool SPINAND_DisableContinueRead(int USBIndex) +{ + if((strstr(g_ChipInfo.TypeName,"MT29F4G") != NULL) + ||(strstr(g_ChipInfo.TypeName,"F50L4G41XB") != NULL) + ||(strstr(g_ChipInfo.TypeName,"TC58CVG2S0HRAIJ") != NULL)) + { + unsigned char ucData=0,ucTempData=0; + + if(!Nand_RDSRFeature1(&ucData,USBIndex)) + return false; + if(!Nand_WRSRFeature1(ucData&0xFC,USBIndex)) + return false; + if(!Nand_RDSRFeature1(&ucTempData,USBIndex)) + return false; + if(ucTempData!=(ucData&0xFC)) + return false; + } + else if((strstr(g_ChipInfo.TypeName, "W25N512GWxIT") != NULL) + ||(strstr(g_ChipInfo.TypeName,"W25N512GWxIG") != NULL) + ||(strstr(g_ChipInfo.TypeName,"W25N512GVxxG") != NULL) + ||(strstr(g_ChipInfo.TypeName,"W25N512GVxxR") != NULL) + ||(strstr(g_ChipInfo.TypeName,"W25N01GWxxIG") != NULL) + ||(strstr(g_ChipInfo.TypeName,"W25N01GVxxIT") != NULL) + ||(strstr(g_ChipInfo.TypeName,"W25N01GVxxIG") != NULL) + ||(strstr(g_ChipInfo.TypeName,"W25N01JWxxIG") != NULL) + ||(strstr(g_ChipInfo.TypeName,"W25N01JWxxIT") != NULL) + ||(strstr(g_ChipInfo.TypeName,"W25N02JWxxIC") != NULL) + ||(strstr(g_ChipInfo.TypeName,"W25N02JWxxIF") != NULL) + ||(strstr(g_ChipInfo.TypeName,"W35N01JWxxxG") != NULL) + ||(strstr(g_ChipInfo.TypeName,"W35N01JWxxxT") != NULL) + ||(strstr(g_ChipInfo.TypeName,"W25N04KVxxIR") != NULL) + ||(strstr(g_ChipInfo.TypeName,"W25N04KVxxIU") != NULL) + ||(strstr(g_ChipInfo.TypeName,"W25N02KVxxIR") != NULL) + ||(strstr(g_ChipInfo.TypeName,"W25N01KVxxIR") != NULL) + ||(strstr(g_ChipInfo.TypeName,"W25N01KVxxIU") != NULL) + ||(strstr(g_ChipInfo.TypeName,"W25N04KWxxIR") != NULL) + ||(strstr(g_ChipInfo.TypeName,"W25N04KWxxIU") != NULL) + ||(strstr(g_ChipInfo.TypeName,"W35N02JW") != NULL)) + { + if(!SPINAND_EnableInternalECC(true,USBIndex)) + return false; + if(!Nand_BUFSet(USBIndex)) + return false; + } + return true; +} + +bool SPINAND_EnableQuadIO(bool bENQuad,bool boRW,int Index) +{ + if(!boRW) + { + return true; + } + if((strstr(g_ChipInfo.TypeName,"W25N512GWxIT") != NULL) + ||(strstr(g_ChipInfo.TypeName,"W25N512GWxIG") != NULL) + ||(strstr(g_ChipInfo.TypeName,"W25N512GVxxG") != NULL) + ||(strstr(g_ChipInfo.TypeName,"W25N512GVxxT") != NULL) + ||(strstr(g_ChipInfo.TypeName,"W25N512GVxxR") != NULL) + ||(strstr(g_ChipInfo.TypeName,"W25N512GWxIG") != NULL) + ||(strstr(g_ChipInfo.TypeName,"W25N01GWxxIG") != NULL) + ||(strstr(g_ChipInfo.TypeName,"W25N01GVxxIT") != NULL) + ||(strstr(g_ChipInfo.TypeName,"W25N01GVxxIG") != NULL) + ||(strstr(g_ChipInfo.TypeName,"W25N01JWxxIG") != NULL) + ||(strstr(g_ChipInfo.TypeName,"W25N01JWxxIT") != NULL) + ||(strstr(g_ChipInfo.TypeName,"W25N02JWxxIC") != NULL) + ||(strstr(g_ChipInfo.TypeName,"W25N02JWxxIF") != NULL) + ||(strstr(g_ChipInfo.TypeName,"W35N01JWxxxG") != NULL) + ||(strstr(g_ChipInfo.TypeName,"W35N01JWxxxT") != NULL) + ||(strstr(g_ChipInfo.TypeName,"S35ML02G3") != NULL)) + { + + return true; + } + unsigned char ucData=0,ucTempData=0; + + if(!Nand_RDSRFeature1(&ucData,Index)) + return false; + if(!bENQuad) //disable quad io + { + ucData&=0xFE; + if(!Nand_WRSRFeature1(ucData,Index)) + return false; + if(!Nand_RDSRFeature1(&ucTempData,Index)) + return false; + if(ucTempData!=ucData) + return false; + } + else + { + if(!Nand_WRSRFeature1(ucData|0x01,Index)) + return false; + if(!Nand_RDSRFeature1(&ucTempData,Index)) + return false; + if(ucTempData!=(ucData|0x01)) + return false; + } + return true; +} + +bool SPINAND_chipErase(int USBIndex) +{ + if(! SPINAND_ProtectBlock(false,USBIndex) ) + return false ; + + unsigned short vICInfo[0x200]; + unsigned short cnt=0; + unsigned char ucSR=0; + SELECT_SPI_NAND_INFO nandInfo; + SetSPIClockDefault(USBIndex); + DownloadICInfo(true,USBIndex); + SetSPIClock(USBIndex); + //Sleep(2000); + Nand_ReadICInfo(&nandInfo,vICInfo,&cnt,USBIndex); + + if(nandInfo.EraseStatus!=0) + { + return false ; + } + + if(!Nand_RDSRStatus1(&ucSR,USBIndex)) + return false; + return true ; +} + + +bool Nand_bulkPipeVerify(struct CAddressRange* AddrRange,unsigned char modeRead,unsigned char ReadCom, int USBIndex) +{ +// if(!&g_ChipInfo) +// return false; + + size_t BlockPages=g_NANDContext.realBlockSize/g_NANDContext.realPageSize; + unsigned char *pData = NULL;//[0x1000000]; + unsigned char *pFile = pBufferforLoadedFile; + size_t ReadCounter=0; + size_t divider=16; + + pData = (unsigned char*)malloc(g_NANDContext.realBlockSize); + memset(pData, 0xFF, g_NANDContext.realBlockSize); + DWORD StartBlock = AddrRange->start/g_NANDContext.realBlockSize; + DWORD StartPage = AddrRange->start/g_NANDContext.realPageSize; + + unsigned int dwAddr=0; + if(BlockPages==256) + dwAddr=((StartPage & 0x3F)|((StartBlock<<6)& 0x7FFC0 )); + else if(BlockPages==128) + dwAddr=((StartPage & 0x7F)|((StartBlock<<7)& 0x7FF80 )); + else + dwAddr=((StartPage & 0x3F)|((StartBlock<<6)& 0x3FFC0)) ; + + struct CAddressRange read_range;//(AddrRange); + read_range.start = AddrRange->start; + read_range.end = AddrRange->end; + read_range.length = AddrRange->length; + + size_t RealReadSize=read_range.length; + + FlashCommand_SendCommand_SetupPacketForBulkReadNAND(dwAddr,RealReadSize>>9, modeRead,g_NANDContext.realPageSize,BlockPages,ReadCom,g_ChipInfo.AddrWidth,g_ChipInfo.ReadDummyLen,g_ChipInfo.nCA_Rd,USBIndex); + + ReadCounter=(RealReadSize/(1< vData(RunUnitSize,0xFF); + pData = (unsigned char* )malloc(RunUnitSize); + memset(pData, 0xFF, RunUnitSize); + + if((AddrRange->start/RunUnitSize)!=(AddrRange->end/RunUnitSize)) + { + struct CAddressRange range_temp;//(*AddrRange); + range_temp.start=AddrRange->start; + range_temp.end=AddrRange->end; + range_temp.length=AddrRange->end-AddrRange->start; + + //size_t baseAddr=AddrRange->start-(AddrRange->start%RunUnitSize); + size_t loop=SF_GetLoop(AddrRange ,RunUnitSize); + + for(size_t j=0; jstart-(AddrRange->start%RunUnitSize)+(RunUnitSize*(j+1)); + + if(j==0) + range_temp.start=AddrRange->start; + else + range_temp.start=AddrRange->start-(AddrRange->start%RunUnitSize)+(RunUnitSize*j); + + DWORD StartBlock = range_temp.start/g_NANDContext.realBlockSize; + DWORD StartPage = range_temp.start/g_NANDContext.realPageSize; + + range_temp.length = range_temp.end-range_temp.start; + unsigned int dwAddr=0; + if(BlockPages==256) + dwAddr=((StartPage & 0x3F)|((StartBlock<<6)& 0x7FFC0 )); + else if(BlockPages==128) + dwAddr=((StartPage & 0x7F)|((StartBlock<<7)& 0x7FF80)) ; + else + dwAddr=((StartPage & 0x3F)|((StartBlock<<6)& 0x3FFC0)) ; + + size_t ReadCounter=range_temp.length >> divider ; + if((range_temp.length%(1<start/g_NANDContext.realBlockSize; + DWORD StartPage = AddrRange->start/g_NANDContext.realPageSize; + unsigned int dwAddr=0; + if(BlockPages==256) + dwAddr=((StartPage & 0x3F)|((StartBlock<<6)& 0x7FFC0)) ; + else if(BlockPages==128) + dwAddr=((StartPage & 0x7F)|((StartBlock<<7)& 0x7FF80)) ; + else + dwAddr=((StartPage & 0x3F)|((StartBlock<<6)& 0x3FFC0)) ; + + size_t ReadCounter=AddrRange->length >> divider ; + if((AddrRange->length%(1<length/512, modeRead,g_NANDContext.realPageSize,BlockPages,ReadCom,g_ChipInfo.AddrWidth,g_ChipInfo.ReadDummyLen,g_ChipInfo.nCA_Rd,USBIndex); + + + for(size_t i = 0; i < ReadCounter; i++) + { + if(!BulkPipeReadEx(&pData[(i<length-(i<length; i++) + { + if(pData[i] != 0xFF) + { + free(pData); + return false ; + } + } + + } + + free(pData); + return true; +} + +bool Nand_bulkPipeRead(const struct CAddressRange* AddrRange, unsigned char* pBuff,unsigned char modeRead,unsigned char ReadCom,int USBIndex) +{ + unsigned char *pData= NULL;// = new unsigned char[0x1000000]; + unsigned char *pTemp = pBuff; +// unsigned char BBTscan=0; + + size_t BlockPages= g_NANDContext.realBlockSize/g_NANDContext.realPageSize; + + size_t divider=16; + size_t RunUnitSize=0; + switch(g_NANDContext.realBlockSize) + { + default: + case 0x44000: + case 0x22000: + RunUnitSize = 0x880000; + break; + case 0x42000: + case 0x21000: + RunUnitSize=0x840000; + break; + case 0x20800: + RunUnitSize=0x820000; + break; + case 0x20400: + RunUnitSize=0x810000; + break; + } + //vector vData(RunUnitSize,0xFF); + pData = (unsigned char* )malloc(RunUnitSize); + memset(pData, 0xFF, RunUnitSize); + + if((AddrRange->start/RunUnitSize)!=(AddrRange->end/RunUnitSize)) + { + struct CAddressRange range_temp;//(*AddrRange); + range_temp.start=AddrRange->start; + range_temp.end=AddrRange->end; + range_temp.length=AddrRange->end-AddrRange->start; + + //size_t baseAddr=AddrRange->start-(AddrRange->start%RunUnitSize); + size_t loop=SF_GetLoop(AddrRange ,RunUnitSize); + + for(size_t j=0; jstart-(AddrRange->start%RunUnitSize)+(RunUnitSize*(j+1)); + + if(j==0) + range_temp.start=AddrRange->start; + else + range_temp.start=AddrRange->start-(AddrRange->start%RunUnitSize)+(RunUnitSize*j); + + DWORD StartBlock = range_temp.start/g_NANDContext.realBlockSize; + DWORD StartPage = range_temp.start/g_NANDContext.realPageSize; + + range_temp.length = range_temp.end-range_temp.start; + unsigned int dwAddr=0; + if(BlockPages==256) + dwAddr=((StartPage & 0x3F)|((StartBlock<<6)& 0x7FFC0 )); + else if(BlockPages==128) + dwAddr=((StartPage & 0x7F)|((StartBlock<<7)& 0x7FF80)) ; + else + dwAddr=((StartPage & 0x3F)|((StartBlock<<6)& 0x3FFC0)) ; + + size_t ReadCounter=range_temp.length >> divider ; + if((range_temp.length%(1<start/g_NANDContext.realBlockSize; + DWORD StartPage = AddrRange->start/g_NANDContext.realPageSize; + unsigned int dwAddr=0; + if(BlockPages==256) + dwAddr=((StartPage & 0x3F)|((StartBlock<<6)& 0x7FFC0)) ; + else if(BlockPages==128) + dwAddr=((StartPage & 0x7F)|((StartBlock<<7)& 0x7FF80)) ; + else + dwAddr=((StartPage & 0x3F)|((StartBlock<<6)& 0x3FFC0)) ; + + size_t ReadCounter=AddrRange->length >> divider ; + if((AddrRange->length%(1<length/512, modeRead,g_NANDContext.realPageSize,BlockPages,ReadCom,g_ChipInfo.AddrWidth,g_ChipInfo.ReadDummyLen,g_ChipInfo.nCA_Rd,USBIndex); + + + for(size_t i = 0; i < ReadCounter; i++) + { + if(!BulkPipeReadEx(&pData[(i<length-(i<length); + } + + free(pData); + return true; +} + +bool SPINAND_RangeVerify( const struct CAddressRange* AddrRange,int USBIndex) +{ + if(!SPINAND_DisableContinueRead(USBIndex)) + return false; +// if(!SPINAND_EnableQuadIO(true,true,USBIndex)) +// return false; + size_t loop=SF_GetLoop(AddrRange ,g_NANDContext.realBlockSize); + //printf("SPINAND_RangeVerify(), AddrRange->start=%ld, AddrRange->end=%ld, loop=%ld\n", AddrRange->start, AddrRange->end,loop); + bool bIsBadBlock = false; + bool result = true; + size_t StartBlock = AddrRange->start/g_NANDContext.realBlockSize; + struct CAddressRange tempRange; + for(unsigned short i=StartBlock; i<(loop+StartBlock); i++) + { + if(g_iNandBadBlockManagement == 0) + { + bIsBadBlock = false; + for(unsigned short j=0; j>divider, modeWrite,g_NANDContext.realPageSize, + BlockPages,WriteCom,g_ChipInfo.AddrWidth, g_ChipInfo.ReadDummyLen,g_ChipInfo.nCA_Wr,USBIndex); + + size_t WriteCounter=g_NANDContext.realBlockSize >> divider ; + if((g_NANDContext.realBlockSize %(1<chip.realBlockSize; + result = false; + cnt++; + } + #endif + + return result; +} + +bool SPINAND_RangeRead(const struct CAddressRange* Range,unsigned char *pBuff, int USBIndex) +{ + if(!SPINAND_DisableContinueRead(USBIndex)) + return false; + // if(!SPINAND_EnableQuadIO(true,true,USBIndex)) + // return false; + if(Nand_bulkPipeRead(Range, pBuff, BULK_QUAD_READ,mcode_ReadCode,USBIndex)) + return false; + // if(!SPINAND_EnableQuadIO(false,true,USBIndex)) + // return false; + return true; +} + +bool SPINAND_RangeProgram(const struct CAddressRange* Range,int USBIndex) +{ + return true; +} + +bool Nand_SpecialRangeErase(unsigned int BlockIndex, unsigned int BlockCnt,int USBIndex) +{ + SetSPIClockValue(0x02,USBIndex); + + unsigned short BBT[0x200]; + unsigned short BBTCnt = 0; + + SPINAND_ScanBadBlock(BBT, &BBTCnt, USBIndex); + + if(BBTCnt >= 0x200) + return false; + + unsigned int TotalBlockCnt = g_NANDContext.realChipSize/g_NANDContext.realBlockSize; + DWORD PageCnt = g_NANDContext.realBlockSize/g_NANDContext.realPageSize; + DWORD addr = 0; + bool skip = false; + unsigned char ucSR=0; + unsigned char v[4];// m_context->serialFlash.EraseCmd.ChipErase); + v[0] = mcode_ChipErase; + for(size_t i=BlockIndex; i<(BlockIndex+BlockCnt); i++) + { + skip = false; + for(unsigned int j=0; j> 16) & 0xff) ; //MSB + v[2] = (unsigned char)((addr >> 8) & 0xff) ; //M + v[3] = (unsigned char)(addr & 0xff) ; //LSB + FlashCommand_SendCommand_OutOnlyInstruction(v, sizeof(v), USBIndex); + + do + { + if(!Nand_RDSRStatus1(&ucSR,USBIndex)) + return false; + if((ucSR & (0x05)) == 0x05) // erase flag and busy flag are set + { + MarkNewBadBlock(addr, USBIndex); + if(BlockCnt < TotalBlockCnt) + BlockCnt++; + break; + } + }while(ucSR & 0x01); + + + } + SetSPIClock(USBIndex); + + return true ; +} + +bool SPINand_SpecialErase(unsigned int BlockIndex, unsigned int BlockCnt, int USBIndex) +{ + bool result = true; + if(!SPINAND_DisableContinueRead(USBIndex)) + return false; + if(! SPINAND_ProtectBlock(false,USBIndex) ) + return false ; + result = Nand_SpecialRangeErase(BlockIndex, BlockCnt, USBIndex); + return result; +} + diff --git a/SerialFlash.h b/SerialFlash.h index aece02e..a5f8152 100755 --- a/SerialFlash.h +++ b/SerialFlash.h @@ -107,5 +107,27 @@ size_t GetChipSize(void); size_t GetPageSize(void); bool SerialFlash_StartofOperation(int Index); bool SerialFlash_EndofOperation(int Index); +bool DownloadICInfoForNand(DWORD dwInfoLen, int USBIndex);//SF700 +bool Nand_ReadICInfo(SELECT_SPI_NAND_INFO *nandInfo, unsigned short *BBT, unsigned short *BBT_Cnt, int USBIndex); +bool SPINAND_ScanBadBlock( unsigned short *BBT, unsigned short *BBT_Cnt, int USBIndex); +bool SF_Nand_HSBSet( int Index); +bool SPINAND_chipErase(int USBIndex); +bool SPINAND_ProtectBlock(bool bProtect,int USBIndex); +void DownloadICInfo(bool isErase, int USBIndex); +bool SPINAND_RangeBlankCheck(const struct CAddressRange* Range,int USBIndex); +bool SPINAND_RangeProgram(const struct CAddressRange* Range,int USBIndex); +bool SPINAND_BlockProgram(const DWORD dwAddr, const unsigned char *pData, unsigned char modeWrite,unsigned char WriteCom,int USBIndex); +bool SPINAND_EnableInternalECC(bool is_ENECC,int USBIndex); +bool Nand_CaculateErrorBit(unsigned char *pData, unsigned char *pFile, unsigned int ptr_size); +bool SPINAND_RangeVerify( const struct CAddressRange* AddrRange,int USBIndex); +bool Nand_bulkPipeRead(const struct CAddressRange* AddrRange, unsigned char* pBuff,unsigned char modeRead,unsigned char ReadCom,int USBIndex); +bool SPINAND_RangeRead(const struct CAddressRange* Range,unsigned char *pBuff, int USBIndex); +bool SPINand_SpecialErase(unsigned int BlockIndex, unsigned int BlockCnt, int USBIndex); + + + + + + #endif //SERIALFLASHS diff --git a/dpcmd.c b/dpcmd.c index ec4d1cd..e4c60f1 100644 --- a/dpcmd.c +++ b/dpcmd.c @@ -10,10 +10,16 @@ #include #include #include +#ifdef __FreeBSD__ +#include +#endif #include #include #include #include +#include +#include + #define min(a, b) (a > b ? b : a) extern unsigned char* pBufferForLastReadData[16]; @@ -39,13 +45,14 @@ unsigned int g_uiDevNum = 0; unsigned int g_uiDeviceID = 0; unsigned int g_IO1Select = 0; unsigned int g_IO4Select = 1; -char strTypeName[1024] = "\0"; +char g_strTypeName[64] = "\0"; bool g_bEnableVpp = false; int g_StartupMode = STARTUP_APPLI_SF_1; bool g_bStatus = true; -CHIP_INFO Chip_Info; +CHIP_INFO g_ChipInfo; +struct CNANDContext g_NANDContext = {{0x111,0x121,0x122,0x141,0x144}, {0x111,0x111,0x111,0x141,0x144},0,0,0,0}; char* l_opt_arg; struct CAddressRange DownloadAddrRange; struct CAddressRange UploadAddrRange; @@ -74,14 +81,23 @@ char* g_parameter_vcc = "NO"; char* g_parameter_blink = "0"; char* g_parameter_fw = "\0"; char g_LogPath[512] = { 0 }; +char* g_parameter_special_program = "\0"; +char* g_parameter_special_auto = "\0"; +char* g_parameter_batch_with_forceerase = "\0"; +char* g_parameter_block_index = "\0"; +char* g_parameter_block_count = "\0"; +char* g_parameter_sparearea_use_file = "\0"; +char* g_parameter_skip_bad_block = "\0"; +char* g_parameter_file_offset = "\0"; +char* g_parameter_internal_ecc = "\0"; + /* to address by BUS:DEV; we'll parse the instructions from either the * environment or command line options and * usbdriver.c:FindUSBDevices() will acknowledge these settings */ extern unsigned g_usb_devnum; extern unsigned g_usb_busnum; -unsigned long g_ucOperation; -struct memory_id g_ChipID; +unsigned long long g_ucOperation; char g_board_type[8]; char g_FPGA_ver[8]; char g_FW_ver[10]; @@ -93,10 +109,18 @@ int m_isCanceled = 0; int m_bProtectAfterWritenErase = 0; int m_boEnReadQuadIO = 0; int m_boEnWriteQuadIO = 0; +int g_iNandBadBlockManagement = 0; //0:skip, 1:no management +int g_iNandBlockIndex = 0; +int g_iNandBlockCount = 0; + volatile bool g_is_operation_on_going = false; bool g_is_operation_successful[16] = { false }; bool g_bDisplayTimer = true; bool isSendFFsequence = false; +bool g_bSpareAreaUseFile = false; +bool g_bNandForceErase = false; +bool g_bNandInternalECC = true; +bool g_bIsNANDFlash = false; /* only print timing progress info if this many seconds ellapsed * before the last time we did */ //static float g_tv_display_delta_s = 0.5; @@ -116,6 +140,7 @@ static const char* msg_info_checking = "\nChecking, please wait ..."; static const char* msg_info_erasing = "\nErasing, please wait ..."; static const char* msg_info_programming = "\nProgramming, please wait ..."; static const char* msg_info_reading = "\nReading, please wait ..."; +static const char* msg_info_scanning = "\nScanning blocks, please wait ..."; static const char* msg_info_auto = "\nAuto Sequences, please wait ..."; static const char* msg_info_verifying = "\nVerifying, please wait ..."; static const char* msg_info_chipblank = "\nThe chip is blank"; @@ -133,53 +158,71 @@ static const char* msg_info_verifyfail = "\nError: Verify Failed"; static const char* msg_info_firmwareupdate = "\nUpdating firmware, please wait..."; static const char* msg_info_firmwareupdateOK = "\nUpdate firmware OK"; static const char* msg_info_firmwareupdatefail = "\nError: Update firmware Failed"; +static const char* msg_info_scanBBOK = "\nScan Bad Block OK"; +static const char* msg_info_scanBBfail = "\nError: Scan Bad Block Failed"; + char* const short_options = "?Ldber:p:u:z:sf:I:R:a:l:vx:T:S:N:B:t:g:c:PO:ik:1:4:U:E:"; struct option long_options[] = { { "help", 0, NULL, '?' }, - { "list", 0, NULL, 'L' }, - { "detect", 0, NULL, 'd' }, + { "nand-BlockCount ", 1, NULL, 'A' }, + { "blink", 1, NULL, 'B' }, { "check", 0, NULL, 'C' }, - { "blank", 0, NULL, 'b' }, - { "erase", 0, NULL, 'e' }, - { "read", 1, NULL, 'r' }, - { "prog", 1, NULL, 'p' }, - { "auto", 1, NULL, 'u' }, - { "batch", 1, NULL, 'z' }, - { "sum", 0, NULL, 's' }, - { "fsum", 1, NULL, 'f' }, + { "device", 1, NULL, 'D' }, + { "nand-SpareAreaUseFile", 1, NULL, 'E' }, + { "sp", 1, NULL, 'F' }, + { "devnum", 1, NULL, 'G' }, + { "busnum", 1, NULL, 'H' }, { "raw-instruction", 1, NULL, 'I' }, + { "force-erase", 0, NULL, 'J' }, + { "se", 0, NULL, 'K' }, + { "list", 0, NULL, 'L' }, + { "su", 1, NULL, 'M' }, + { "lock-length", 1, NULL, 'N' }, + { "log", 1, NULL, 'O' }, + { "vpp", 0, NULL, 'P' }, + { "nand-BlockIndex", 1, NULL, 'Q' }, { "raw-require-return", 1, NULL, 'R' }, - { "addr", 1, NULL, 'a' }, - { "length", 1, NULL, 'l' }, - { "verify", 0, NULL, 'v' }, - { "fill", 1, NULL, 'x' }, + { "lock-start", 1, NULL, 'S' }, { "type", 1, NULL, 'T' }, - { "lock-start", 1, NULL, 'S' }, - { "lock-length", 1, NULL, 'N' }, - { "blink", 1, NULL, 'B' }, - { "device", 1, NULL, 'D' }, - { "device-SN", 1, NULL, 'X' }, - // { "fix-device", 1, NULL, 'F' }, + { "update-fw", 1, NULL, 'U' }, { "list-device-id", 1, NULL, 'V' }, { "loadFile-with-verify", 1, NULL, 'W' }, - { "timeout", 1, NULL, 't' }, - { "target", 1, NULL, 'g' }, + { "device-SN", 1, NULL, 'X' }, + { "nand-batch-forceerase", 1, NULL, 'Y' }, + { "nand-skip-bad-block ", 1, NULL, 'Z' }, + + { "addr", 1, NULL, 'a' }, + { "blank", 0, NULL, 'b' }, { "vcc", 1, NULL, 'c' }, - { "vpp", 0, NULL, 'P' }, - { "log", 1, NULL, 'O' }, + { "detect", 0, NULL, 'd' }, + { "erase", 0, NULL, 'e' }, + { "fsum", 1, NULL, 'f' }, + { "target", 1, NULL, 'g' }, { "silent", 0, NULL, 'i' }, + { "nand-file-offset", 1, NULL, 'j' }, { "spi-clk", 1, NULL, 'k' }, + { "length", 1, NULL, 'l' }, + { "nand-internal-ecc ", 1, NULL, 'm' }, + { "nand-BlockCount", 1, NULL, 'n' }, + + { "prog", 1, NULL, 'p' }, + + { "read", 1, NULL, 'r' }, + { "sum", 0, NULL, 's' }, + { "timeout", 1, NULL, 't' }, + { "auto", 1, NULL, 'u' }, + { "verify", 0, NULL, 'v' }, + + { "fill", 1, NULL, 'x' }, + + { "batch", 1, NULL, 'z' }, + { "set-io1", 1, NULL, '1' }, { "set-io4", 1, NULL, '4' }, - { "update-fw", 1, NULL, 'U' }, - // { "display-delta", 1, NULL, 'E' }, - { "devnum", 1, NULL, 'G' }, - { "busnum", 1, NULL, 'H' }, - { 0, 0, 0, 0 }, - + { }, }; int OpenUSB(void); @@ -338,6 +381,17 @@ int Sequence() { // *** the calling order in the following block must be kept as is *** bool boResult = true; + if (strstr(g_ChipInfo.ICType, "SPI_NAND") != NULL) + { + g_bIsNANDFlash = true; + FillNANDContext(); + } + + if((g_ucOperation & ERASE) == 0 && (g_ucOperation & SPECIAL_ERASE)==0) + { + boResult = ScanBB(); + } + boResult &= BlankCheck(); if (boResult == false) { if (!(g_ucOperation & ERASE)) @@ -349,10 +403,18 @@ int Sequence() return EXCODE_FAIL_ERASE; } + boResult &= SpecialErase(); + if (boResult == false) + return EXCODE_FAIL_PROG; + boResult &= Program(); if (boResult == false) return EXCODE_FAIL_PROG; + //boResult &= SpecialProgram(); + //if (boResult == false) + // return EXCODE_FAIL_PROG; + boResult &= Read(); if (boResult == false) return EXCODE_FAIL_READ; @@ -366,9 +428,9 @@ int Sequence() if (g_ucOperation & CSUM) { if (g_uiLen == 0) { if (g_uiDevNum == 0) - return CRC32(pBufferForLastReadData[0], Chip_Info.ChipSizeInByte); + return CRC32(pBufferForLastReadData[0], g_ChipInfo.ChipSizeInByte); else - return CRC32(pBufferForLastReadData[g_uiDevNum - 1], Chip_Info.ChipSizeInByte); + return CRC32(pBufferForLastReadData[g_uiDevNum - 1], g_ChipInfo.ChipSizeInByte); } else { if (g_uiDevNum == 0) return CRC32(pBufferForLastReadData[0], g_uiLen); @@ -459,6 +521,32 @@ void WriteLog(int ErrorCode, bool Init) int GetConfigVer() { +#if 1 + char file_path[512]; + xmlDocPtr doc; + xmlNodePtr cur_node; + xmlChar *chip_attribute; + int Ver = 0; + + if (GetChipDbPath(file_path) == false) + { + return 1; + } + + doc = xmlParseFile(file_path); + cur_node = xmlDocGetRootElement(doc); // DediProgChipDatabase + while (cur_node != NULL) { + if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"DediProgChipDatabase"))) { + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"Ver"); + Ver = strtol((char*)chip_attribute, NULL, 10); + xmlFree(chip_attribute); + } + + cur_node = cur_node->next; + } + xmlFreeDoc(doc); + return Ver; +#else char file_line_buf[512]; char test[80]; char *pch, *tok; @@ -484,6 +572,7 @@ int GetConfigVer() } fclose(fp); return Ver; +#endif } int main(int argc, char* argv[]) @@ -494,6 +583,7 @@ int main(int argc, char* argv[]) #endif int c; + int temp = 0; int iExitCode = EXCODE_PASS; bool bDetect = false; bool bDevice = false; @@ -501,7 +591,17 @@ int main(int argc, char* argv[]) unsigned long r; char* env; - printf("\nDpCmd Linux 1.14.20.%02d Engine Version:\nLast Built on %s\n\n", GetConfigVer(), __DATE__); // 1. new feature.bug.configS + printf("\nDpCmd %s 1.14.21.%02d Engine Version:\nLast Built on %s\n\n", +#if defined(__APPLE__) + "macOS", +#elif defined(__FreeBSD__) + "FreeBSD", +#elif defined(__linux__) + "Linux", +#else + "Unknown", +#endif + GetConfigVer(), __DATE__); // 1. new feature.bug.configS g_ucOperation = 0; GetLogPath(g_LogPath); @@ -510,6 +610,8 @@ int main(int argc, char* argv[]) cli_classic_usage(false); return 0; } + if (ListTypes()) + return EXCODE_PASS; /* * Obtain the (optional) bus number and device number to @@ -546,21 +648,6 @@ int main(int argc, char* argv[]) g_usb_busnum = (unsigned char)r; } - // Filter by DP Device num, same as setting --device flag - // Only touches target device since it is before OpenUSB() - env = getenv("DPCMD_DEVNUM"); - if (env) { - r = strtoul(env, NULL, 10); - if (r == ULONG_MAX || r >= 256) { - fprintf(stderr, "E: invalid device number in" - " DPCMD_DEVNUM\n"); - return 1; - } - g_uiDevNum = (unsigned char)r; - bDevice = true; - } - - if (OpenUSB() == 0) iExitCode = EXCODE_FAIL_USB; @@ -747,6 +834,52 @@ int main(int argc, char* argv[]) } g_usb_busnum = (unsigned)r; break; + //SPI NAND + case 'E': + g_parameter_sparearea_use_file = optarg; + sscanf(g_parameter_sparearea_use_file, "%d", &temp); + g_bSpareAreaUseFile = ((temp==0)? false:true); + break; + case 'F': + g_parameter_special_program = optarg; + g_ucOperation |= SPECIAL_PROGRAM; + break; + case 'J': + g_bNandForceErase = true; + g_ucOperation |= ERASE; + break; + case 'K': + g_bNandForceErase = false; + g_ucOperation |= SPECIAL_ERASE; + break; + case 'M': + g_parameter_special_auto = optarg; + g_ucOperation |= SPECIAL_AUTO; + break; + case 'Q': + g_parameter_block_index = optarg; + sscanf(g_parameter_block_index, "%d", &g_iNandBlockIndex); + break; + case 'Y': + g_parameter_batch_with_forceerase = optarg; + g_ucOperation |= BATCH_WITH_FORCEERASE; + break; + case 'Z': + g_parameter_skip_bad_block = optarg; + sscanf(g_parameter_skip_bad_block, "%d", &g_iNandBadBlockManagement); + break; + case 'j': + g_parameter_file_offset = optarg; + break; + case 'm': + g_parameter_internal_ecc = optarg; + sscanf(g_parameter_internal_ecc, "%d", &temp); + g_bNandInternalECC = ((temp == 0)? true:false); + break; + case 'n': + g_parameter_block_count = optarg; + sscanf(g_parameter_block_count, "%d", &g_iNandBlockCount); + break; default: break; } @@ -774,11 +907,11 @@ int main(int argc, char* argv[]) } int dwUID = ReadUID(g_uiDevNum - 1); if (is_SF700_Or_SF600PG2(g_uiDevNum - 1)) { - if (g_bIsSF700[g_uiDevNum - 1] == true) { + if (g_bIsSF700[g_uiDevNum - 1] == true) { printf("\nDevice %d (SF7%05d):\tdetecting chip\n", g_uiDevNum, dwUID); } else if (g_bIsSF600PG2[g_uiDevNum - 1] == true) { printf("\nDevice %d (S6B%05d):\tdetecting chip\n", g_uiDevNum, dwUID); - } + } } else if ((g_bIsSF600[g_uiDevNum - 1] == true) && (dwUID / 600000) > 0) { printf("\nDevice %d (SF%06d):\tdetecting chip\n", g_uiDevNum, dwUID); } else if ((dwUID / 100000) > 0) { @@ -787,11 +920,11 @@ int main(int argc, char* argv[]) printf("\nDevice %d (DP%06d):\tdetecting chip\n", g_uiDevNum, dwUID); } WriteLog(iExitCode, true); - Chip_Info = GetFirstDetectionMatch(strTypeName, g_uiDevNum - 1); - if (Chip_Info.UniqueID != 0) { - if (strlen(strTypeName)) { - printf("By reading the chip ID, the chip applies to [ %s ]\n\n", strTypeName); - printf("%s chip size is %zd bytes.\n", Chip_Info.TypeName, Chip_Info.ChipSizeInByte); + g_ChipInfo = GetFirstDetectionMatch(g_strTypeName, g_uiDevNum - 1); + if (g_ChipInfo.UniqueID != 0) { + if (strlen(g_strTypeName)) { + printf("By reading the chip ID, the chip applies to [ %s ]\n\n", g_strTypeName); + printf("%s chip size is %zd bytes.\n", g_ChipInfo.TypeName, g_ChipInfo.ChipSizeInByte); } else { printf("%s", msg_err_identifychip); iExitCode = EXCODE_FAIL_IDENTIFY; @@ -819,11 +952,12 @@ int main(int argc, char* argv[]) printf("\nDevice %d (DP%06d):\tdetecting chip\n", i + 1, dwUID); } WriteLog(iExitCode, true); - Chip_Info = GetFirstDetectionMatch(strTypeName, i); - if (Chip_Info.UniqueID != 0) { - if (strlen(strTypeName)) { - printf("By reading the chip ID, the chip applies to [ %s ]\n", strTypeName); - printf("%s chip size is %zd bytes.\n", Chip_Info.TypeName, Chip_Info.ChipSizeInByte); + g_ChipInfo = GetFirstDetectionMatch(g_strTypeName, i); + printf("type = %s\n\r",g_ChipInfo.ICType); + if (g_ChipInfo.UniqueID != 0) { + if (strlen(g_ChipInfo.TypeName/* g_strTypeName*/)) { + printf("By reading the chip ID, the chip applies to [ %s ]\n", g_strTypeName); + printf("%s chip size is %zd bytes.\n", g_ChipInfo.TypeName, g_ChipInfo.ChipSizeInByte); } else { printf("%s", msg_err_identifychip); iExitCode = EXCODE_FAIL_IDENTIFY; @@ -837,13 +971,13 @@ int main(int argc, char* argv[]) } else if (g_uiDevNum != 0) { WriteLog(iExitCode, true); printf("%d,\tdetecting chip\n", g_uiDevNum); - Chip_Info = GetFirstDetectionMatch(strTypeName, g_uiDevNum - 1); + g_ChipInfo = GetFirstDetectionMatch(g_strTypeName, g_uiDevNum - 1); - if (Chip_Info.UniqueID != 0) { - //printf("strlen(strTypeName)=%ld\n",strlen(strTypeName)); - if (strlen(strTypeName)) { - printf(" \tBy reading the chip ID, the chip applies to [ %s ]\n\n", strTypeName); - printf(" \t%s chip size is %zd bytes.\n", Chip_Info.TypeName, Chip_Info.ChipSizeInByte); + if (g_ChipInfo.UniqueID != 0) { + //printf("strlen(g_strTypeName)=%ld\n",strlen(g_strTypeName)); + if (strlen(g_strTypeName)) { + printf(" \tBy reading the chip ID, the chip applies to [ %s ]\n\n", g_strTypeName); + printf(" \t%s chip size is %zd bytes.\n", g_ChipInfo.TypeName, g_ChipInfo.ChipSizeInByte); } else { printf("%s", msg_err_identifychip); iExitCode = EXCODE_FAIL_IDENTIFY; @@ -872,6 +1006,7 @@ int main(int argc, char* argv[]) } WriteLog(iExitCode, true); } + if (iExitCode != EXCODE_PASS) goto Exit; iExitCode = Handler(); @@ -974,6 +1109,7 @@ void cli_classic_usage(bool IsShowExample) "Remark: -x only works with -p"); printf("(space is not needed between the switches and parameters. E.g. dpcmd -ubio.bin)\n"); + printf("SPI NOR : Basic Switches(switches in this group are mutual exclusive):\n"); printf(" -? [ --help ] show this help message\n" " --list print supported chip list\n" " --check get programmer information\n" @@ -1008,7 +1144,7 @@ void cli_classic_usage(bool IsShowExample) " dpcmd --raw-instruction \"06|01 0C|05\" \n" " --raw-require-return \"0|0|1\" \n" "\n" - "Optional Switches that add fine-tune ability to Basic Switches:\n" + "SPI NOR : Optional Switches that add fine-tune ability to Basic Switches:\n" " -a [ --addr ] arg hexadecimal starting address hexadecimal(e.g.\n" " 0x1000),\n" " - works with --prog/read/sum/auto only\n" @@ -1050,7 +1186,7 @@ void cli_classic_usage(bool IsShowExample) // " - n: Prompt the device ID of programmer connected to USBn.\n" " --loadFile-with-verify arg -Load a bin/hex/s19 file and verify with the memory conten.\n" "\n" - "Miscellaneous options:\n" + "SPI NOR : Miscellaneous options:\n" " -t [ --timeout ] arg (=300) Timeout value in seconds\n" " -g [ --target ] arg (=1) Target Options\n" " Available values:\n" @@ -1091,11 +1227,140 @@ void cli_classic_usage(bool IsShowExample) " -E [ --display-delta ] arg (=0.5) wait this many seconds\n" " before refreshing the screen\n" "\n" + "SPI NAND : Basic Switches(switches in this group are mutual exclusive):\n" + " -h [ --help ] show this help message\n" + " --blink arg \n" + // " - 0 : Blink green LED 3 times from USB1 to USBn\n" + // " (Default)\n" + // " note: the sequence is assigned by OS during USB plug-in\n" + " - 1: Blink the programmer connected to USB1 3 times.\n" + " --list print supported chip list\n" + " -c [ --check ] check programmer information\n" + " -d [ --detect ] detect chip\n" + " -b [ --blank ] blank check\n" + " -e [ --erase ] erase entire chip\n" + " --force-erase enable hard copy erase\n" + " -r [ --read ] arg read chip contents and save to a bin/hex/s19 file\n" + " - use STDOUT for the console.\n" + " -p [ --prog ] arg program chip without erase\n" + " -z [ --batch ] arg\n" + " automatically run the following sequence:\n" + " - check if the chip is blank or not;\n" + " - erase the chip memory which skip bad block(if\n" + " not blank);\n" + " - program a whole file starting from address 0\n" + /* " --se erase entire chip and mark a new bad block, if\n" + " bad block is generated during erase\n" + " --sp arg program chip without erase\n" + " and mark a new bad block, if bad block is\n" + " generated during programming\n" + " - instructions must be enclosed in double\n" + " quotation marks(\"\")\n" + " - use \"|\" to load partition file and data file\n" + " Example:\n" + " dpcmd --sp \"xxx.dpmbn|aaa.bin\"\n" + " --su arg automatically run the following sequence:\n" + " - Erase only the blocks with data length and mark\n" + " a new bad block\n" + " - Program only the erased blocks with the file\n" + " data from address 0\n" + " or according to partition file\n" + " - instructions must be enclosed in double\n" + " quotation marks(\"\")\n" + " - use \"|\" to load partition file and data file\n" + " Example:\n" + " dpcmd --su \"xxx.dpmbn|aaa.bin\"\n" + " --nand-batch-forceerase arg automatically run the following sequence:\n" + " - check if the chip is blank or not;\n" + " - force erase the entire chip(if not blank);\n" + " - program a whole file starting from address 0\n"*/ + " -s [ --sum ] display chip content checksum\n" + " -f [ --fsum ] arg display the file checksum\n" + " - needs to work with a file\n" + " --raw-instruction arg issue raw serial flash instructions.\n" + " - use spaces(\" \") to delimit bytes.\n" + " - instructions must be enclosed in double\n" + " quotation marks(\"\")\n" + " - use \"|\" to send continuous command\n" + " Example:\n" + " ./dpcmd --raw-instruction 06\n" + " ./dpcmd --raw-instruction \"06|02 00 00 00 11 22 33\"\n" + " --raw-require-return arg decimal bytes of result to return in decimal\n" + " after issuing raw instructions.\n" + " - used along with --raw-instruction only.\n" + " Example:\n" + " dpcmd --raw-instruction \"03 FF 00 12\" --raw-require-return 1\n" + " dpcmd --raw-instruction \"06|05\" --raw-require-return \"0|2\"\n" + " --loadFile-with-verify arg Load a bin/hex/s19 file and compare with memory\n" + " content\n" + " Example:\n" + " ./dpcmd --loadFile-with-verify d:\\xxx.bin\n" + + "SPI NAND : Optional Switches that add fine-tune ability to Basic Switches:\n" + " -v [ --verify ] verify checksum file and chip\n" + " - works with --prog/batch only\n" + " --type arg Specify a type to override auto detection\n" + " - use --list arguement to look up supported type.\n" + // " --read-id read chip id\n" + // " - return chip id only\n" + + "SPI NAND : Miscellaneous options:\n" + " -t [ --timeout ] arg (=1000) Timeout value in seconds. Default value is\n" + " 1000s.\n" + " -g [ --target ] arg (=1) Target Options\n" + " Available values:\n" + " 1, Chip 1(Default)\n" + " 2, Chip 2\n" + " 3, Socket\n" + " 0, reference card\n" + " -i [ --silent ] suppress the display of real-time timer counting\n" + " - used when integrating with 3rd-party tools\n" + " (e.g. IDE)\n" + " --vcc arg specify vcc(SF600Plus-G2 / Others)\n" + " 0, 3.3V / 3.5V\n" + " 1, 2.5V / 1.2V\n" + " 2, 1.8V / 1.8V\n" + " 3, 1.2V / 1.2V\n" + " 1200 ~ 3800, 1.2V ~ 3.8V (minimum step\n" + " 100mV)\n" + " --spi-clk arg (=2) specify SPI clock:\n" + " 2, 12MHz (Default)\n" + " 0, 25MHz\n" + " 1, 6MHz\n" + " 3, 4MHz\n" + " 4, 2MHz\n" + " 5, 1MHz\n" + " 6, 800KHz\n" + " 7, 400KHz\n" + " -i [ --silent ] suppress the display of real-time timer counting\n" + " - used when integrating with 3rd-party tools\n" + " (e.g. IDE)\n" + " --set-io1 arg (=0) specify Level of IO1(SF100) or GPIO1(SF600/S\n" + " F600Plus):\n" + " 0, Low(Default)\n" + " 1, High\n" + " --set-io4 arg (=1) specify Level of IO4(SF100) or GPIO2(SF600/S\n" + " F600Plus):\n" + " 0, Low\n" + " 1, High(Default)\n" + " --nand-BlockIndex arg (=0) Decimal starting address Decimal(e.g. 512),\n" + " - defaults to 0, if omitted.\n" + " --nand-BlockCount arg (=0) Decimal starting address Decimal(e.g. 200),\n" + " - defaults to whole file if omitted.\n" + " --nand-SpareAreaUseFile arg (=0) specify if the Spare Area use file:\n" + " 0, Unuse(Default)\n" + " 1, True\n" + " --nand-skip-bad-block arg (=0) specify if the Bad Block(s) are skipped:\n" + " 0, Skip(Default)\n" + " 1, No management\n" + " --nand-file-offset arg (=0) specify the file offset number\n" + " --nand-internal-ecc arg (=0) specify if the Internal ECC enable:\n" + " 0, Enable(Default)\n" + " 1, Disable\n" "Environment variables:\n" " Specify DPCMD_USB_BUSNUM and DPCMD_USB_DEVNUM to ensure the tool touches only said device. Numbers can be found with tools such as lsusb and others.\n" " - DPCMD_USB_BUSNUM Number of USB bus where device is\n" " - DPCMD_USB_DEVNUM Number of device in USB bus\n" - "\n\n\n"); } @@ -1111,6 +1376,17 @@ void sin_handler(int sig) } } +void FillNANDContext(void) +{ + g_NANDContext.realSpareAreaSize = ( g_bNandInternalECC==true? (g_ChipInfo.SpareSizeInByte & 0xFFFF):((g_ChipInfo.SpareSizeInByte>>16) & 0xFFFF)); + g_NANDContext.realPageSize = g_NANDContext.realSpareAreaSize+g_ChipInfo.PageSizeInByte; + g_NANDContext.realBlockSize = g_ChipInfo.BlockSizeInByte/g_ChipInfo.PageSizeInByte*g_NANDContext.realPageSize; + g_NANDContext.realChipSize = g_NANDContext.realBlockSize*g_ChipInfo.ChipSizeInByte/g_ChipInfo.BlockSizeInByte; + memcpy(&g_NANDContext.EraseCmd,&g_ChipInfo.EraseCmd, sizeof(unsigned int)); + memcpy(&g_NANDContext.ReadCmd,&g_ChipInfo.ReadCmd, sizeof(unsigned int)); + memcpy(&g_NANDContext.ProgramCmd,&g_ChipInfo.ProgramCmd, sizeof(unsigned int)); +} + int Handler(void) { if (Is_usbworking(0) == true) { @@ -1123,7 +1399,6 @@ int Handler(void) AssignedDevice(); #endif - if ((g_ucOperation & BLINK) == BLINK) { BlinkProgrammer(); return EXCODE_PASS; @@ -1173,7 +1448,8 @@ bool InitProject(void) { //printf("bool InitProject(void)\n"); int dev_cnt = get_usb_dev_cnt(); - if (Is_usbworking(0)) { + if (Is_usbworking(0) == true) { +// if (Is_usbworking(g_uiDevNum-1)) { int targets[4] = { STARTUP_APPLI_CARD, STARTUP_APPLI_SF_1, @@ -1188,14 +1464,14 @@ bool InitProject(void) SetSPIIOMode(i); SetSPIClock(i); SetVcc(i); - SetVppVoltage(0,i); + SetVppVoltage(0,i); if (strlen(g_parameter_type) > 0) { - if (Dedi_Search_Chip_Db_ByTypeName(g_parameter_type, &Chip_Info)) { - printf("Chip Type %s is applied manually.\n", Chip_Info.TypeName); - printf("%s chip size is %zd bytes.\n\n", Chip_Info.TypeName, Chip_Info.ChipSizeInByte); - ProjectInitWithID(Chip_Info, i); - if (!strcmp(Chip_Info.Class, "N25Qxxx_Large")) + if (Dedi_Search_Chip_Db_ByTypeName(g_parameter_type, &g_ChipInfo)) { + printf("Chip Type %s is applied manually.\n", g_ChipInfo.TypeName); + printf("%s chip size is %zd bytes.\n\n", g_ChipInfo.TypeName, g_ChipInfo.ChipSizeInByte); + ProjectInitWithID(g_ChipInfo, i); + if (!strcmp(g_ChipInfo.Class, "N25Qxxx_Large")) isSendFFsequence = true; } else { printf("Chip Type Unknow is applied manually.\n"); @@ -1208,17 +1484,17 @@ bool InitProject(void) } } else if (g_uiDevNum <= dev_cnt) { g_StartupMode = targets[g_ucTarget]; - SetTargetFlash((unsigned char)targets[g_ucTarget], g_uiDevNum - 1); - SetSPIIOMode(g_uiDevNum - 1); + SetTargetFlash((unsigned char)targets[g_ucTarget], g_uiDevNum - 1); + SetSPIIOMode(g_uiDevNum - 1); SetSPIClock(g_uiDevNum - 1); SetVcc(g_uiDevNum - 1); - SetVppVoltage(0,g_uiDevNum - 1); + SetVppVoltage(0,g_uiDevNum - 1); if (strlen(g_parameter_type) > 0) { - if (Dedi_Search_Chip_Db_ByTypeName(g_parameter_type, &Chip_Info)) { - printf("Chip Type %s is applied manually.\n", Chip_Info.TypeName); - printf("%s chip size is %zd bytes.\n\n", Chip_Info.TypeName, Chip_Info.ChipSizeInByte); - ProjectInitWithID(Chip_Info, g_uiDevNum - 1); + if (Dedi_Search_Chip_Db_ByTypeName(g_parameter_type, &g_ChipInfo)) { + printf("Chip Type %s is applied manually.\n", g_ChipInfo.TypeName); + printf("%s chip size is %zd bytes.\n\n", g_ChipInfo.TypeName, g_ChipInfo.ChipSizeInByte); + ProjectInitWithID(g_ChipInfo, g_uiDevNum - 1); } else { printf("Chip Type Unknow is applied manually.\n"); return false; @@ -1228,7 +1504,7 @@ bool InitProject(void) ProjectInit(g_uiDevNum - 1); } } else - printf("Error: Did not find the programmer.\n"); + printf("Error: Did not find the programmer.\n"); return true; } @@ -1246,20 +1522,20 @@ void CloseProject(void) bool DetectChip(void) { int dev_cnt = get_usb_dev_cnt(); - Chip_Info = GetFirstDetectionMatch(strTypeName, 0); + g_ChipInfo = GetFirstDetectionMatch(g_strTypeName, ((g_uiDevNum>0)? (g_uiDevNum-1):0)); if (g_uiDevNum == 0) { for (int i = 0; i < dev_cnt; i++) { if (!Is_usbworking(i)) { printf("%s", msg_err_communication); return false; } - if (0 == Chip_Info.UniqueID) { + if (0 == g_ChipInfo.UniqueID) { printf("%s", msg_err_identifychip); return false; } - printf("By reading the chip ID, the chip applies to [ %s ]\n\n", strTypeName); - printf("%s parameters to be applied by default\n", Chip_Info.TypeName); - printf("%s chip size is %zd bytes.\n\n", Chip_Info.TypeName, Chip_Info.ChipSizeInByte); + printf("By reading the chip ID, the chip applies to [ %s ]\n\n", g_strTypeName); + printf("%s parameters to be applied by default\n", g_ChipInfo.TypeName); + printf("%s chip size is %zd bytes.\n\n", g_ChipInfo.TypeName, g_ChipInfo.ChipSizeInByte); RawInstructions(i); } @@ -1268,13 +1544,13 @@ bool DetectChip(void) printf("%s", msg_err_communication); return false; } - if (0 == Chip_Info.UniqueID) { + if (0 == g_ChipInfo.UniqueID) { printf("%s", msg_err_identifychip); return false; } - printf("By reading the chip ID, the chip applies to [ %s ]\n\n", Chip_Info.TypeName); - printf("%s parameters to be applied by default\n", Chip_Info.TypeName); - printf("%s chip size is %zd bytes.\n\n", Chip_Info.TypeName, Chip_Info.ChipSizeInByte); + printf("By reading the chip ID, the chip applies to [ %s ]\n\n", g_ChipInfo.TypeName); + printf("%s parameters to be applied by default\n", g_ChipInfo.TypeName); + printf("%s chip size is %zd bytes.\n\n", g_ChipInfo.TypeName, g_ChipInfo.ChipSizeInByte); RawInstructions(g_uiDevNum - 1); @@ -1567,6 +1843,15 @@ void do_BlankCheck(void) Wait(msg_info_chipblank, msg_info_chipnotblank); } +void do_NANDSpecialErase(void) +{ + printf("%s \n", msg_info_erasing); + Run(NAND_SPECIAL_ERASE, g_uiDevNum); + + Wait(msg_info_eraseOK, msg_info_erasefail); +} + + void do_Erase(void) { printf("%s \n", msg_info_erasing); @@ -1579,6 +1864,7 @@ void do_Program(void) { if (!do_loadFile()) return; + SaveProgContextChanges(); printf("%s\n", msg_info_programming); @@ -1809,6 +2095,130 @@ void do_RawInstructions(int Index) } } +void do_ScanBB() +{ + if(g_bIsNANDFlash == false) + return; + + printf("%s\n", msg_info_scanning); + Run(NAND_SCAN_BB, g_uiDevNum); + Wait( msg_info_scanBBOK, msg_info_scanBBfail) ; +} +#if 0 +bool do_loadFileWithPartitionTable() +{ + if(g_bIsNANDFlash == false) + { + return false; + } + + char* filename = NULL; + if (g_ucOperation & SPECIAL_PROGRAM) + filename = g_parameter_special_program; + else if (g_ucOperation & BATCH) { + switch (g_BatchIndex) { + case 1: + filename = g_parameter_batch; + break; + case 2: + default: + filename = g_parameter_auto; + break; + } + } else if (g_ucOperation & FSUM) + filename = g_parameter_fsum; + printf("%s", msg_info_loading); + printf("(%s)\n", filename); + + { + string s(m_vm["sp"].as()); + split(fileOut, s/*one_sequence*/,is_any_of("|"), token_compress_on); + } + + if(fileOut.size() == 0) + return false; + + if(fileOut.size() == 1) + return do_loadFile(); + + m_proj->analysisPartitionTable(m_vm["nand-SpareAreaUseFile"].as()!=0, fileOut.at(0)); + m_proj->get_context().file.nand_PartitionTableFilePath.assign(fileOut.at(1).begin(), fileOut.at(1).end()); + if(m_vm.count("device")) + m_proj->ChecknFitPartitionTable(bDeviceArray[m_vm["device"].as()]); + else if(m_vm.count("device-SN")) + m_proj->ChecknFitPartitionTable(DeviceNum); + else + m_proj->ChecknFitPartitionTable(0); + + return do_NANDloadFile(fileOut.at(1)); + return true; + +} + +void do_NANDSpecialProgram() +{ + SaveProgContextChanges(); + do_ScanBB(); + + if(!do_loadFileWithPartitionTable()) + { + m_status_result=false; + return; + } + + if( (IsAthenticated==FALSE) && (m_DetectedDeviceNum>1) ) + { + if( TrialCntProgram>0 ) + { + wcout << L"\nProgram trail count:#"<< 99 - TrialCntProgram << L" (Max trial count=99).\n"; + TrialCntProgram--; + } + else + { + wcout << L"\nProgram trial count runs out, please buy the production license.\n"; + return; + } + } + + cout << msg_info_programming; + do_SaveAllLog((CString)msg_info_programming.c_str()); + if(m_vm.count("device")) + { + if(bDeviceArray[m_vm["device"].as()]==0xff) + { + outMsg="The number of programmer is not defined!"; + OutputFormatedMsg(outMsg); + do_SaveAllLog((CString)outMsg.c_str()); + return; + } + //SiteChoosen=m_vm["device"].as()-1; + m_proj->RunSingle(CProject::NAND_SPECIAL_PROGRAM,m_vm["device"].as()-1); + } + else if(m_vm.count("device-SN")) + { + if(DeviceNum==0xffffffff) + { + OutputFormatedMsg("The number of programmer is not defined!"); + return; + } + //SiteChoosen=bReDeviceArray[DeviceNum]-1; + m_proj->RunSingle(CProject::NAND_SPECIAL_PROGRAM,bReDeviceArray[DeviceNum]-1); + } + else + m_proj->RunMulti(CProject::NAND_SPECIAL_PROGRAM); + + if( Wait( msg_info_progOK, msg_info_progfail ) ) + { + wcout << L"\nChecksum(whole file): " << m_proj->getImageFileInfo(DediVersion::IMAGEFILE_ATTRIBUTE_CRC); + wcout << L"\nChecksum(Written part of file): " << m_proj->getImageFileInfo(DediVersion::IMAGEFILE_ATTRIBUTE_CRC_OF_WRITTEN_PART); + } + if(m_proj->boFileSizeFailed) + { + wcout << L"\nError: File is invalid.\n" ; + } +} +#endif + void RawInstructions(int Index) { if (strlen(g_parameter_raw) > 0) { @@ -1825,10 +2235,36 @@ bool BlankCheck(void) return g_bStatus; } +bool SpecialErase() +{ + if (g_ucOperation & SPECIAL_ERASE) { + + g_bNandForceErase = false; + do_NANDSpecialErase(); + if(g_bStatus) + do_ScanBB(); + } + + + return g_bStatus; +} + bool Erase(void) { - if (g_ucOperation & ERASE) + if (g_ucOperation & ERASE) { do_Erase(); + if(g_bStatus) + do_ScanBB(); + } + + + return g_bStatus; +} + +bool SpecialProgram(void) +{ +// if (g_ucOperation & SPECIAL_PROGRAM) +// do_SpecialProgram(); return g_bStatus; } @@ -1897,7 +2333,7 @@ bool CalChecksum(void) else printf("\nDevice %d (DP%06d):", i + 1, dwUID); - printf("Checksum of the whole chip(address starting from: 0x%X, 0x%zX bytes in total): %08X\n", g_uiAddr, Chip_Info.ChipSizeInByte, CRC32(pBufferForLastReadData[i], Chip_Info.ChipSizeInByte)); + printf("Checksum of the whole chip(address starting from: 0x%X, 0x%zX bytes in total): %08X\n", g_uiAddr, g_ChipInfo.ChipSizeInByte, CRC32(pBufferForLastReadData[i], g_ChipInfo.ChipSizeInByte)); } else { if (is_SF700_Or_SF600PG2(i)) { if (g_bIsSF700[i] == true) @@ -1911,7 +2347,7 @@ bool CalChecksum(void) else printf("\nDevice %d (DP%06d):", i + 1, ReadUID(i)); - printf("Checksum(address starting from: 0x%X, 0x%zX bytes in total): %08X\n", g_uiAddr, g_uiLen, CRC32(pBufferForLastReadData[i], min(g_uiLen, Chip_Info.ChipSizeInByte))); + printf("Checksum(address starting from: 0x%X, 0x%zX bytes in total): %08X\n", g_uiAddr, g_uiLen, CRC32(pBufferForLastReadData[i], min(g_uiLen, g_ChipInfo.ChipSizeInByte))); } } } else if (g_uiDevNum != 0) { @@ -1929,7 +2365,7 @@ bool CalChecksum(void) else printf("\nDevice %d (DP%06d):", g_uiDevNum, ReadUID(g_uiDevNum - 1)); - printf("Checksum of the whole chip(address starting from: 0x%X, 0x%zX bytes in total): %08X\n", g_uiAddr, Chip_Info.ChipSizeInByte, CRC32(pBufferForLastReadData[g_uiDevNum - 1], Chip_Info.ChipSizeInByte)); + printf("Checksum of the whole chip(address starting from: 0x%X, 0x%zX bytes in total): %08X\n", g_uiAddr, g_ChipInfo.ChipSizeInByte, CRC32(pBufferForLastReadData[g_uiDevNum - 1], g_ChipInfo.ChipSizeInByte)); } else { if (is_SF700_Or_SF600PG2(g_uiDevNum - 1)) { if (g_bIsSF700[g_uiDevNum - 1] == true) @@ -1942,7 +2378,7 @@ bool CalChecksum(void) printf("\nDevice %d (SF%06d):", g_uiDevNum, ReadUID(g_uiDevNum - 1)); else printf("\nDevice %d (DP%06d):", g_uiDevNum, ReadUID(g_uiDevNum - 1)); - printf("Checksum(address starting from: 0x%X, 0x%zX bytes in total): %08X\n", g_uiAddr, g_uiLen, CRC32(pBufferForLastReadData[g_uiDevNum - 1], min(g_uiLen, Chip_Info.ChipSizeInByte))); + printf("Checksum(address starting from: 0x%X, 0x%zX bytes in total): %08X\n", g_uiAddr, g_uiLen, CRC32(pBufferForLastReadData[g_uiDevNum - 1], min(g_uiLen, g_ChipInfo.ChipSizeInByte))); } } else printf("The number of programmer is not defined!\n"); @@ -2039,10 +2475,9 @@ int FlashIdentifier(CHIP_INFO* Chip_Info, int search_all, int Index) UniqueID = 0; rc = 0; UniqueID = flash_ReadId(0x9f, 3, Index); - if (UniqueID != 0) { rc = Dedi_Search_Chip_Db(TypeName, 0x9f, UniqueID, Chip_Info, search_all); - strcpy(strTypeName, TypeName); + strcpy(g_strTypeName, TypeName); if (rc && (search_all == 0)) { if (c == 1) isSendFFsequence = true; @@ -2113,3 +2548,15 @@ int FlashIdentifier(CHIP_INFO* Chip_Info, int search_all, int Index) } return rc; } + +bool ScanBB(void) +{ + if(g_bIsNANDFlash == false) + return true; + if(g_iNandBadBlockManagement == 1) + return true; + + do_ScanBB(); + return g_bStatus; +} + diff --git a/dpcmd.h b/dpcmd.h index dafe9ad..9b8b8f0 100755 --- a/dpcmd.h +++ b/dpcmd.h @@ -21,27 +21,6 @@ enum ErrorCode { EXCODE_FAIL_OTHERS, }; -enum { // value dedicated by the spec - STARTUP_APPLI_SF_1 = 0, - STARTUP_APPLI_CARD = 1, - STARTUP_APPLI_SF_2 = 2, - STARTUP_APPLI_SF_SKT = 3, - - STARTUP_SPECIFY_LATER = 0xFE, - STARTUP_PREVIOUS = 0xFF -}; - -enum { - clk_24M = 0x00, - clk_8M = 0x01, - clk_12M = 0x02, - clk_3M = 0x03, - clk_2180K = 0x04, - clk_1500K = 0x05, - clk_750K = 0x06, - clk_375K = 0x07, -}; - int Sequence(); void cli_classic_usage(bool IsShowExample); bool InitProject(void); @@ -84,5 +63,11 @@ bool Wait(const char* strOK, const char* strFail); void ExitProgram(void); int FirmwareUpdate(); void sin_handler(int sig); +void FillNANDContext(void); +bool ScanBB(void); +void do_ScanBB(void); +void do_NANDSpecialErase(void); +bool SpecialErase(void); + #endif diff --git a/parse.c b/parse.c index d119979..f073fcb 100755 --- a/parse.c +++ b/parse.c @@ -4,7 +4,13 @@ #include #include #include +#include +#include +#ifdef __FreeBSD__ +#include +#endif +#define pathbufsize 1024 #define testbufsize 256 #define linebufsize 512 #define filebufsize 1024 * 1024 @@ -13,7 +19,643 @@ //using namespace pugi; //xml_document doc; +#if 1 + bool GetChipDbPath(char *Path) +{ + FILE* fp = NULL; + + if(Path == NULL) + return false; + + memset(Path, 0, linebufsize); + if (readlink("/proc/self/exe", Path, 512) != -1) { + dirname(Path); + strcat(Path, "/ChipInfoDb.dedicfg"); + if ((fp = fopen(Path, "rt")) == NULL) { + // ChipInfoDb.dedicfg not in program directory + dirname(Path); + dirname(Path); + strcat(Path, "/share/DediProg/ChipInfoDb.dedicfg"); + // printf("%s\n",Path); + if ((fp = fopen(Path, "rt")) == NULL) + { + fprintf(stderr, "Error opening file: %s\n", Path); + return false; + } + } + if(fp) + fclose(fp); + //printf("\r\n%s\r\n", Path); + return true; + } + return false; +} + + +int Dedi_Search_Chip_Db(char* chTypeName, long RDIDCommand, + long UniqueID, + CHIP_INFO* Chip_Info, + int search_all) +{ + int found_flag = 0; + char file_path[linebufsize]; + int detectICNum = 0; + char strTypeName[32][100]; + CHIP_INFO Chip_Info_temp; + xmlDocPtr doc; + xmlNodePtr cur_node; + xmlChar *chip_attribute; + + for (int i = 0; i < 32; i++) + memset(strTypeName[i], '\0', 100); + + memset(chTypeName, '\0', 1024); + + memset(Chip_Info->TypeName, '\0', sizeof(Chip_Info->TypeName)); //strlen(Chip_Info->TypeName)=0 + + if (GetChipDbPath(file_path) == false) + { + return 1; + } + + doc = xmlParseFile(file_path); + cur_node = xmlDocGetRootElement(doc); // DediProgChipDatabase + cur_node = cur_node->children->next; //Portofolio + cur_node = cur_node->children->next; //Chip + //printf("UniqueID=0x%08X\n", UniqueID); + while (cur_node != NULL) { + if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"Chip"))) { + + if (found_flag == 1) { + found_flag = 0; + + if (strlen(Chip_Info->TypeName) == 0) + *Chip_Info = Chip_Info_temp; //first chip info + detectICNum++; + memset(&Chip_Info_temp, 0, sizeof(CHIP_INFO)); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"TypeName"); + if(chip_attribute){ + + strcpy(Chip_Info_temp.TypeName, (char*)chip_attribute); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ICType"); + if(chip_attribute){ + + strcpy(Chip_Info_temp.ICType, (char*)chip_attribute); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"Class"); + if(chip_attribute){ + strcpy(Chip_Info_temp.Class, (char*)chip_attribute); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"Manufacturer"); + if(chip_attribute){ + strcpy(Chip_Info_temp.Manufacturer, (char*)chip_attribute); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"UniqueID"); + if(chip_attribute){ + Chip_Info_temp.UniqueID = strtol((char*)chip_attribute, NULL, 16);; + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"Voltage"); + if(chip_attribute){ + strcpy(Chip_Info_temp.Voltage, (char*)chip_attribute); + if (strstr((char *)chip_attribute, "3.3V") != NULL) + Chip_Info_temp.VoltageInMv = 3300; + else if (strstr((char *)chip_attribute, "2.5V") != NULL) + Chip_Info_temp.VoltageInMv = 2500; + else if (strstr((char *)chip_attribute, "1.8V") != NULL) + Chip_Info_temp.VoltageInMv = 1800; + else + Chip_Info_temp.VoltageInMv = 3300; + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"JedecDeviceID"); + if(chip_attribute){ + Chip_Info_temp.JedecDeviceID = strtol((char*)chip_attribute, NULL, 16); + if ((UniqueID == Chip_Info_temp.JedecDeviceID)) { + found_flag = 1; + + strcpy(strTypeName[detectICNum], Chip_Info_temp.TypeName); + strcat(chTypeName, " "); + strcat(chTypeName, strTypeName[detectICNum]); + } + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ChipSizeInKByte"); + if(chip_attribute){ + Chip_Info_temp.ChipSizeInByte = strtol((char*)chip_attribute, NULL, 10) * 1024; + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"SectorSizeInByte"); + if(chip_attribute){ + Chip_Info_temp.SectorSizeInByte = strtol((char*)chip_attribute, NULL, 10); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"BlockSizeInByte"); + if(chip_attribute){ + Chip_Info_temp.BlockSizeInByte = strtol((char*)chip_attribute, NULL, 10); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"PageSizeInByte"); + if(chip_attribute){ + Chip_Info_temp.PageSizeInByte = strtol((char*)chip_attribute, NULL, 10); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"AddrWidth"); + if(chip_attribute){ + Chip_Info_temp.AddrWidth = strtol((char*)chip_attribute, NULL, 10); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ReadDummyLen"); + if(chip_attribute){ + Chip_Info_temp.ReadDummyLen = strtol((char*)chip_attribute, NULL, 10); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ReadDummyLen"); + if(chip_attribute){ + Chip_Info_temp.ReadDummyLen = strtol((char*)chip_attribute, NULL, 10); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"IDNumber"); + if(chip_attribute){ + Chip_Info_temp.IDNumber = strtol((char*)chip_attribute, NULL, 10); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"VppSupport"); + if(chip_attribute){ + Chip_Info_temp.VppSupport = strtol((char*)chip_attribute, NULL, 10); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"RDIDCommand"); + if(chip_attribute){ + Chip_Info_temp.RDIDCommand = strtol((char*)chip_attribute, NULL, 16); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"Timeout"); + if(chip_attribute){ + Chip_Info_temp.Timeout = strtol((char*)chip_attribute, NULL, 16); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"MXIC_WPmode"); + if(chip_attribute){ + if (strstr((char*)chip_attribute, "true") != NULL) + Chip_Info_temp.MXIC_WPmode = true; + else + Chip_Info_temp.MXIC_WPmode = false; + } + //SPI NAND + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"SpareSizeInByte"); + if(chip_attribute){ + Chip_Info_temp.SpareSizeInByte = (strtol((char*)chip_attribute, NULL, 16)/*&0xFFFF*/); + //printf("SpareSizeInByte=%ld\n",Chip_Info_temp.SpareSizeInByte); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"nCA_Rd"); + if(chip_attribute){ + Chip_Info_temp.nCA_Rd = strtol((char*)chip_attribute, NULL, 10); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"nCA_Wr"); + if(chip_attribute){ + Chip_Info_temp.nCA_Wr = strtol((char*)chip_attribute, NULL, 10); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ReadDummyLen"); + if(chip_attribute){ + Chip_Info_temp.ReadDummyLen = strtol((char*)chip_attribute, NULL, 10); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"DefaultDataUnitSize"); + if(chip_attribute){ + Chip_Info_temp.DefaultDataUnitSize = strtol((char*)chip_attribute, NULL, 10); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"DefaultErrorBits"); + if(chip_attribute){ + Chip_Info_temp.DefaultErrorBits = strtol((char*)chip_attribute, NULL, 10); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"BBMark"); + if(chip_attribute){ + Chip_Info_temp.BBMark = strtol((char*)chip_attribute, NULL, 10); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"SupportedProduct"); + if(chip_attribute){ + Chip_Info_temp.SupportedProduct = strtol((char*)chip_attribute, NULL, 16); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ECCParityGroup"); + if(chip_attribute){ + Chip_Info_temp.ECCParityGroup = strtol((char*)chip_attribute, NULL, 10); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ECCProtectStartAddr"); + if(chip_attribute){ + Chip_Info_temp.ECCProtectStartAddr = strtol((char*)chip_attribute, NULL, 16); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ECCProtectDis"); + if(chip_attribute){ + Chip_Info_temp.ECCProtectDis = strtol((char*)chip_attribute, NULL, 16); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ECCProtectLength"); + if(chip_attribute){ + Chip_Info_temp.ECCProtectLength = strtol((char*)chip_attribute, NULL, 10); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ECCEnable"); + if(chip_attribute){ + if (strstr((char*)chip_attribute, "true") != NULL) + Chip_Info_temp.ECCEnable = true; + else + Chip_Info_temp.ECCEnable = false; + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"QPIEnable"); + if(chip_attribute){ + if (strstr((char*)chip_attribute, "true") != NULL) + Chip_Info_temp.QPIEnable = true; + else + Chip_Info_temp.QPIEnable = false; + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ChipEraseTime"); + if(chip_attribute){ + Chip_Info_temp.ChipEraseTime = strtol((char*)chip_attribute, NULL, 16); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"EraseCmd"); + if(chip_attribute){ + Chip_Info_temp.EraseCmd = strtol((char*)chip_attribute, NULL, 16); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ProgramCmd"); + if(chip_attribute){ + Chip_Info_temp.ProgramCmd = strtol((char*)chip_attribute, NULL, 16); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ReadCmd"); + if(chip_attribute){ + Chip_Info_temp.ReadCmd = strtol((char*)chip_attribute, NULL, 16); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ProtectBlockMask"); + if(chip_attribute){ + Chip_Info_temp.ProtectBlockMask = strtol((char*)chip_attribute, NULL, 16); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"UnlockCmd"); + if(chip_attribute){ + Chip_Info_temp.UnlockCmd = strtol((char*)chip_attribute, NULL, 16); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"RDSRCnt"); + if(chip_attribute){ + Chip_Info_temp.RDSRCnt = strtol((char*)chip_attribute, NULL, 16); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"WRSRCnt"); + if(chip_attribute){ + Chip_Info_temp.WRSRCnt = strtol((char*)chip_attribute, NULL, 16); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"WRSRCmd"); + if(chip_attribute){ + Chip_Info_temp.WRSRCmd = strtol((char*)chip_attribute, NULL, 16); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"WRCRCmd"); + if(chip_attribute){ + Chip_Info_temp.WRCRCmd = strtol((char*)chip_attribute, NULL, 16); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"RDSRCmd"); + if(chip_attribute){ + Chip_Info_temp.RDSRCmd = strtol((char*)chip_attribute, NULL, 16); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"RDCRCmd"); + if(chip_attribute){ + Chip_Info_temp.RDCRCmd = strtol((char*)chip_attribute, NULL, 16); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"QEbitAddr"); + if(chip_attribute){ + Chip_Info_temp.QEbitAddr = strtol((char*)chip_attribute, NULL, 16); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ChipIDMask"); + if(chip_attribute){ + Chip_Info_temp.ChipIDMask = strtol((char*)chip_attribute, NULL, 16); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"SupportLUT"); + if(chip_attribute){ + if (strstr((char*)chip_attribute, "true") != NULL) + Chip_Info_temp.SupportLUT = true; + else + Chip_Info_temp.SupportLUT = false; + } + + xmlFree(chip_attribute); + } + cur_node = cur_node->next; + } + + xmlFreeDoc(doc); + if(detectICNum) + found_flag=1; + Chip_Info->MaxErasableSegmentInByte = max(Chip_Info->SectorSizeInByte, Chip_Info->BlockSizeInByte); + /*Read into the buffer contents within thr file stream*/ + return found_flag; +} + +int Dedi_Search_Chip_Db_ByTypeName(char* TypeName, CHIP_INFO* Chip_Info) +{ + int found_flag = 0; + char file_path[linebufsize]; + CHIP_INFO Chip_Info_temp; + xmlDocPtr doc; + xmlNodePtr cur_node; + xmlChar *chip_attribute; + + if (GetChipDbPath(file_path) == false) + { + return 1; + } + + + doc = xmlParseFile(file_path); + cur_node = xmlDocGetRootElement(doc); // DediProgChipDatabase + cur_node = cur_node->children->next; //Portofolio + cur_node = cur_node->children->next; //C + // data_temp = file_buf; + /*Read into the buffer contents within thr file stream*/ + while (cur_node != NULL) { + if (found_flag == 1) { + if (strlen(Chip_Info->TypeName) == 0) + *Chip_Info = Chip_Info_temp; //first chip info + + break; + } + + if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"Chip"))) { + + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"TypeName"); + + if(chip_attribute){ + + if (!xmlStrcmp(chip_attribute, (const xmlChar *)TypeName)) { + found_flag = 1; + //printf("chip name=%s\n",chip_attribute); + } else + found_flag = 0; + memset(&Chip_Info_temp, 0, sizeof(CHIP_INFO)); + strcpy(Chip_Info_temp.TypeName, (char*)chip_attribute); + + } + } + if(found_flag == 0) + { + cur_node = cur_node->next; + continue; + }else { + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"Class"); + if(chip_attribute){ + strcpy(Chip_Info_temp.Class, (char*)chip_attribute); + //printf("Class: %s\n", chip_attribute); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"Manufacturer"); + if(chip_attribute){ + strcpy(Chip_Info_temp.Manufacturer, (char*)chip_attribute); + //printf("Manufacturer: %s\n", chip_attribute); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"UniqueID"); + if(chip_attribute){ + Chip_Info_temp.UniqueID = strtol((char*)chip_attribute, NULL, 16);; + //printf("UniqueID: %s\n", chip_attribute); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"Voltage"); + if(chip_attribute){ + //printf("Voltage: %s\n", chip_attribute); + if (strstr((char *)chip_attribute, "3.3V") == 0) + Chip_Info_temp.VoltageInMv = 3300; + else if (strstr((char *)chip_attribute, "2.5V") == 0) + Chip_Info_temp.VoltageInMv = 2500; + else if (strstr((char *)chip_attribute, "1.8V") == 0) + Chip_Info_temp.VoltageInMv = 1800; + else + Chip_Info_temp.VoltageInMv = 3300; + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"JedecDeviceID"); + if(chip_attribute){ + Chip_Info_temp.JedecDeviceID = strtol((char*)chip_attribute, NULL, 16); + //printf("JedecDeviceID: %s\n", chip_attribute); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ChipSizeInKByte"); + if(chip_attribute){ + Chip_Info_temp.ChipSizeInByte = strtol((char*)chip_attribute, NULL, 10) * 1024; + //printf("ChipSizeInKByte: %s\n", chip_attribute); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"SectorSizeInByte"); + if(chip_attribute){ + Chip_Info_temp.SectorSizeInByte = strtol((char*)chip_attribute, NULL, 10); + //printf("SectorSizeInKByte: %s\n", chip_attribute); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"BlockSizeInByte"); + if(chip_attribute){ + Chip_Info_temp.BlockSizeInByte = strtol((char*)chip_attribute, NULL, 10); + //printf("BlockSizeInByte: %s\n", chip_attribute); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"PageSizeInByte"); + if(chip_attribute){ + Chip_Info_temp.PageSizeInByte = strtol((char*)chip_attribute, NULL, 10); + //printf("PageSizeInByte: %s\n", chip_attribute); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"AddrWidth"); + if(chip_attribute){ + Chip_Info_temp.AddrWidth = strtol((char*)chip_attribute, NULL, 10); + //printf("AddrWidth: %s\n", chip_attribute); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ReadDummyLen"); + if(chip_attribute){ + Chip_Info_temp.ReadDummyLen = strtol((char*)chip_attribute, NULL, 10); + //printf("ReadDummyLen: %s\n", chip_attribute); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ReadDummyLen"); + if(chip_attribute){ + Chip_Info_temp.ReadDummyLen = strtol((char*)chip_attribute, NULL, 10); + //printf("ReadDummyLen: %s\n", chip_attribute); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"IDNumber"); + if(chip_attribute){ + Chip_Info_temp.IDNumber = strtol((char*)chip_attribute, NULL, 10); + //printf("IDNumber: %s\n", chip_attribute); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"VppSupport"); + if(chip_attribute){ + Chip_Info_temp.VppSupport = strtol((char*)chip_attribute, NULL, 10); + //printf("VppSupport: %s\n", chip_attribute); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"RDIDCommand"); + if(chip_attribute){ + Chip_Info_temp.RDIDCommand = strtol((char*)chip_attribute, NULL, 16); + //printf("RDIDCommand: %s\n", chip_attribute); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"Timeout"); + if(chip_attribute){ + Chip_Info_temp.Timeout = strtol((char*)chip_attribute, NULL, 16); + //printf("Timeout: %s\n", chip_attribute); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"MXIC_WPmode"); + if(chip_attribute){ + if (strstr((char*)chip_attribute, "true") != NULL) + Chip_Info_temp.MXIC_WPmode = true; + else + Chip_Info_temp.MXIC_WPmode = false; + //printf("MXIC_WPmode: %s\n", chip_attribute); + } + //SPI NAND + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"SpareSizeInByte"); + if(chip_attribute){ + Chip_Info_temp.SpareSizeInByte = strtol((char*)chip_attribute, NULL, 16); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"nCA_Rd"); + if(chip_attribute){ + Chip_Info_temp.nCA_Rd = strtol((char*)chip_attribute, NULL, 10); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"nCA_Wr"); + if(chip_attribute){ + Chip_Info_temp.nCA_Wr = strtol((char*)chip_attribute, NULL, 10); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ReadDummyLen"); + if(chip_attribute){ + Chip_Info_temp.ReadDummyLen = strtol((char*)chip_attribute, NULL, 10); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"DefaultDataUnitSize"); + if(chip_attribute){ + Chip_Info_temp.DefaultDataUnitSize = strtol((char*)chip_attribute, NULL, 10); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"DefaultErrorBits"); + if(chip_attribute){ + Chip_Info_temp.DefaultErrorBits = strtol((char*)chip_attribute, NULL, 10); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"BBMark"); + if(chip_attribute){ + Chip_Info_temp.BBMark = strtol((char*)chip_attribute, NULL, 10); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"SupportedProduct"); + if(chip_attribute){ + Chip_Info_temp.SupportedProduct = strtol((char*)chip_attribute, NULL, 16); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ECCParityGroup"); + if(chip_attribute){ + Chip_Info_temp.ECCParityGroup = strtol((char*)chip_attribute, NULL, 10); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ECCProtectStartAddr"); + if(chip_attribute){ + Chip_Info_temp.ECCProtectStartAddr = strtol((char*)chip_attribute, NULL, 16); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ECCProtectDis"); + if(chip_attribute){ + Chip_Info_temp.ECCProtectDis = strtol((char*)chip_attribute, NULL, 16); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ECCProtectLength"); + if(chip_attribute){ + Chip_Info_temp.ECCProtectLength = strtol((char*)chip_attribute, NULL, 10); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ECCEnable"); + if(chip_attribute){ + if (strstr((char*)chip_attribute, "true") != NULL) + Chip_Info_temp.ECCEnable = true; + else + Chip_Info_temp.ECCEnable = false; + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"QPIEnable"); + if(chip_attribute){ + if (strstr((char*)chip_attribute, "true") != NULL) + Chip_Info_temp.QPIEnable = true; + else + Chip_Info_temp.QPIEnable = false; + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ChipEraseTime"); + if(chip_attribute){ + Chip_Info_temp.ChipEraseTime = strtol((char*)chip_attribute, NULL, 16); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"EraseCmd"); + if(chip_attribute){ + Chip_Info_temp.EraseCmd = strtol((char*)chip_attribute, NULL, 16); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ProgramCmd"); + if(chip_attribute){ + Chip_Info_temp.ProgramCmd = strtol((char*)chip_attribute, NULL, 16); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ReadCmd"); + if(chip_attribute){ + Chip_Info_temp.ReadCmd = strtol((char*)chip_attribute, NULL, 16); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ProtectBlockMask"); + if(chip_attribute){ + Chip_Info_temp.ProtectBlockMask = strtol((char*)chip_attribute, NULL, 16); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"UnlockCmd"); + if(chip_attribute){ + Chip_Info_temp.UnlockCmd = strtol((char*)chip_attribute, NULL, 16); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"RDSRCnt"); + if(chip_attribute){ + Chip_Info_temp.RDSRCnt = strtol((char*)chip_attribute, NULL, 16); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"WRSRCnt"); + if(chip_attribute){ + Chip_Info_temp.WRSRCnt = strtol((char*)chip_attribute, NULL, 16); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"WRSRCmd"); + if(chip_attribute){ + Chip_Info_temp.WRSRCmd = strtol((char*)chip_attribute, NULL, 16); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"WRCRCmd"); + if(chip_attribute){ + Chip_Info_temp.WRCRCmd = strtol((char*)chip_attribute, NULL, 16); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"RDSRCmd"); + if(chip_attribute){ + Chip_Info_temp.RDSRCmd = strtol((char*)chip_attribute, NULL, 16); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"RDCRCmd"); + if(chip_attribute){ + Chip_Info_temp.RDCRCmd = strtol((char*)chip_attribute, NULL, 16); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"QEbitAddr"); + if(chip_attribute){ + Chip_Info_temp.QEbitAddr = strtol((char*)chip_attribute, NULL, 16); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"SupportLUT"); + if(chip_attribute){ + if (strstr((char*)chip_attribute, "true") != NULL) + Chip_Info_temp.SupportLUT = true; + else + Chip_Info_temp.SupportLUT = false; + } + } + xmlFree(chip_attribute); + } + + xmlFreeDoc(doc); + Chip_Info->MaxErasableSegmentInByte = max(Chip_Info->SectorSizeInByte, Chip_Info->BlockSizeInByte); + + if (found_flag == 0) { + Chip_Info->TypeName[0] = 0; + Chip_Info->UniqueID = 0; + } + return found_flag; /*Executed without errors*/ +} + + +bool Dedi_List_AllChip(void) +{ + char file_path[linebufsize]; + char Type[256] = { 0 }; + xmlDocPtr doc; + xmlNodePtr cur_node; + xmlChar *chip_attribute; + + if (GetChipDbPath(file_path) == false) + { + return 1; + } + + doc = xmlParseFile(file_path); + cur_node = xmlDocGetRootElement(doc); // DediProgChipDatabase + cur_node = cur_node->children->next; //Portofolio + cur_node = cur_node->children->next; //C + // data_temp = file_buf; + /*Read into the buffer contents within thr file stream*/ + while (cur_node != NULL) { + if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"Chip"))) { + + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"TypeName"); + if(chip_attribute){ + strcpy(Type, (char*)chip_attribute); + //printf("TypeName: %s\n", chip_attribute); + } + chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"Manufacturer"); + if(chip_attribute){ + printf("%s\t\tby %s\n", Type, (char*)chip_attribute); + } + xmlFree(chip_attribute); + } + cur_node = cur_node->next; + } + + xmlFreeDoc(doc); + + return true; + +} + #else FILE* openChipInfoDb(void) { FILE* fp = NULL; @@ -584,6 +1226,7 @@ bool Dedi_List_AllChip(void) } /*End main*/ +#endif /***********************PARSE.TXT (CONTENT)**********************/ /* "Move each word to the next line" */ /***********************PARSE.EXE (OUTPUT)***********************/ diff --git a/project.c b/project.c index 79dbbc3..148d0bc 100755 --- a/project.c +++ b/project.c @@ -20,8 +20,10 @@ unsigned long g_ulFileSize = 0; unsigned int g_uiFileChecksum = 0; unsigned char g_BatchIndex = 2; unsigned int CompleteCnt = 0; +unsigned short g_usFileBlockCount = 0; // bool m_bOperationResult[16]; bool bAuto[16] = { false }; +struct BadBlockTable g_BBT[16]; extern unsigned int g_ucFill; extern int m_boEnReadQuadIO; extern int m_boEnWriteQuadIO; @@ -42,7 +44,7 @@ extern unsigned char mcode_Program; extern unsigned char mcode_ProgramCode_4Adr; extern unsigned char mcode_Read; extern unsigned char mcode_ReadCode; -extern CHIP_INFO Chip_Info; +extern CHIP_INFO g_ChipInfo; extern int g_StartupMode; extern int g_CurrentSeriase; extern struct CAddressRange DownloadAddrRange; @@ -56,7 +58,15 @@ extern unsigned int g_uiAddr; extern size_t g_uiLen; extern bool g_bEnableVpp; extern unsigned int g_uiDevNum; -extern char strTypeName[1024]; +extern char g_strTypeName[64]; +extern bool g_bIsNANDFlash; +extern bool g_bSpareAreaUseFile; +extern struct CNANDContext g_NANDContext; +extern bool g_bNandInternalECC; +extern bool g_iNandBadBlockManagement; +extern int g_iNandBlockIndex; +extern int g_iNandBlockCount; +extern char* g_parameter_file_offset; #if 0 extern int FlashIdentifier(CHIP_INFO* Chip_Info, int search_all, int Index); #else @@ -121,7 +131,7 @@ static unsigned int crc32_tab[] = { void TurnONVpp(int Index) { if (g_bEnableVpp == true) - dediprog_set_vpp_voltage(Chip_Info.VppSupport, Index); + dediprog_set_vpp_voltage(g_ChipInfo.VppSupport, Index); } void TurnOFFVpp(int Index) @@ -152,6 +162,103 @@ unsigned int CRC32(unsigned char* v, unsigned long size) return dwCrc32; // & 0xFFFF; } +int ReadBINFileForNAND(const char* filename) +{ + FILE* pFile;//, *pFileFroWrite; + DWORD lSize, file_size; + size_t result; + size_t read_size = 0, temp_size; + unsigned char *pTemp; + unsigned char ucTemp[g_NANDContext.realPageSize]; + DWORD temp = 0; + unsigned short tepmCount = 0; + temp =strtol((char*)g_parameter_file_offset, NULL, 10); + + pFile = fopen(filename, "rb"); + //pFileFroWrite = fopen("read.bin", "wb"); + if (pFile == NULL) { + printf("Open %s failed\n", filename); + fputs("File error\n", stderr); + return 0; + } + g_usFileBlockCount = 0; + // obtain file size: + fseek(pFile, 0, SEEK_END); + file_size = ftell(pFile) - temp; + lSize = g_NANDContext.realChipSize; + tepmCount = (g_NANDContext.realChipSize/g_NANDContext.realBlockSize)+(((g_NANDContext.realChipSize%g_NANDContext.realBlockSize)==0)? 0:1); + if(file_size > lSize) + { + printf("%s file size is bigger than chip size\n", filename); + fclose(pFile); + return false; + } + if(temp == 0) + rewind(pFile); + else + fseek(pFile, temp, SEEK_SET); + // allocate memory to contain the whole file: + if (pBufferforLoadedFile != NULL) + free(pBufferforLoadedFile); + + pBufferforLoadedFile = (unsigned char*)malloc(lSize); + + if (pBufferforLoadedFile == NULL) { + fputs("Memory error\n", stderr); + fclose(pFile); + return 0; + } + + pTemp = pBufferforLoadedFile; + + memset(pBufferforLoadedFile, 0xFF, lSize); + + if(g_bSpareAreaUseFile == true) + { + read_size = g_NANDContext.realPageSize; + g_usFileBlockCount = (file_size/g_NANDContext.realBlockSize)+(((file_size%g_NANDContext.realBlockSize)==0)? 0:1); + } + else + { + read_size = g_ChipInfo.PageSizeInByte; + g_usFileBlockCount = (file_size/g_ChipInfo.BlockSizeInByte)+(((file_size%g_ChipInfo.BlockSizeInByte)==0)? 0:1); + } + + if(g_iNandBlockCount != 0) + { + if(g_iNandBlockCount > tepmCount ) + g_usFileBlockCount = tepmCount; + else + g_usFileBlockCount = g_iNandBlockCount; + } + + g_ulFileSize = file_size; + + do + { + memset(ucTemp, 0xFF, sizeof(ucTemp)); + temp_size = min(read_size,file_size); + result = fread(ucTemp, 1, temp_size, pFile); + if(result != temp_size) + break; + + memcpy(pTemp, ucTemp, temp_size); + pTemp += (g_NANDContext.realPageSize); + file_size -= temp_size; + }while(file_size>0); + + + DownloadAddrRange.start = (g_iNandBlockIndex * g_NANDContext.realBlockSize); + DownloadAddrRange.end = (DownloadAddrRange.start + (g_usFileBlockCount * g_NANDContext.realBlockSize)); + DownloadAddrRange.length = DownloadAddrRange.end-DownloadAddrRange.start; + //fwrite(pBufferforLoadedFile , 1, lSize, pFileFroWrite); + + fclose(pFile); + //fclose(pFileFroWrite); + return 1; + +} + int ReadBINFile(const char* filename, unsigned char* buf, unsigned long* size) { FILE* pFile; @@ -250,6 +357,8 @@ int GetFileFormatFromExt(const char* csPath) bool ReadFile(const char* csPath, unsigned char* buffer, unsigned long* FileSize, unsigned char PaddingByte) { + if(g_bIsNANDFlash == true) + return ReadBINFileForNAND(csPath); switch (GetFileFormatFromExt(csPath)) { case HEX: return HexFileToBin(csPath, buffer, FileSize, PaddingByte); @@ -290,12 +399,12 @@ bool IdentifyChipBeforeOperation(int Index) binfo.UniqueID = 0; int Found = 0; - if (strstr(Chip_Info.Class, SUPPORT_FREESCALE_MCF) != NULL || strstr(Chip_Info.Class, SUPPORT_SILICONBLUE_iCE65) != NULL) + if (strstr(g_ChipInfo.Class, SUPPORT_FREESCALE_MCF) != NULL || strstr(g_ChipInfo.Class, SUPPORT_SILICONBLUE_iCE65) != NULL) return true; Found = FlashIdentifier(&binfo, 0, Index); - if (Found && (binfo.UniqueID == Chip_Info.UniqueID || binfo.UniqueID == Chip_Info.JedecDeviceID)) + if (Found && (binfo.UniqueID == g_ChipInfo.UniqueID || binfo.UniqueID == g_ChipInfo.JedecDeviceID)) result = true; return result; } @@ -319,7 +428,7 @@ bool ValidateProgramParameters(int Index) PrepareProgramParameters(Index); /// special treatment for AT45DBxxxD - if (strstr(Chip_Info.Class, SUPPORT_ATMEL_45DBxxxB) != NULL) { + if (strstr(g_ChipInfo.Class, SUPPORT_ATMEL_45DBxxxB) != NULL) { size_t pagesize = 264; size_t mask = (1 << 9) - 1; return (mask & DownloadAddrRange.start) <= (mask & pagesize); @@ -327,14 +436,14 @@ bool ValidateProgramParameters(int Index) /// if file size exceeds memory size, it's an error /// if user-specified length exceeds, just ignore - if (DownloadAddrRange.start > Chip_Info.ChipSizeInByte - 1) + if (DownloadAddrRange.start > g_ChipInfo.ChipSizeInByte - 1) return false; size_t size = DownloadAddrRange.length; if (size > g_ulFileSize && g_ucFill == 0xFF) return false; - if (DownloadAddrRange.end > Chip_Info.ChipSizeInByte) + if (DownloadAddrRange.end > g_ChipInfo.ChipSizeInByte) return false; return true; } @@ -362,6 +471,42 @@ bool ProgramChip(int Index) return result; } +bool ProgramNANDChip(int Index) +{ + bool bIsBadBlock=false; + DWORD usFileOffset = 0; + bool result = true; + //threadScanBB(Index); + //printf("\nProgramming, please wait ...\n"); + TurnONVcc(Index); + if(!SPINAND_ProtectBlock(false,Index)) + return false; + if(!SPINAND_EnableInternalECC(g_bNandInternalECC,Index)) + return false; + + for(unsigned short i=0; i addr.start) - addr.length = Chip_Info.ChipSizeInByte - addr.start; + if (0 == addr.length && g_ChipInfo.ChipSizeInByte > addr.start) + addr.length = g_ChipInfo.ChipSizeInByte - addr.start; addr.end = addr.length + addr.start; - if (addr.start >= Chip_Info.ChipSizeInByte) { + if (addr.start >= g_ChipInfo.ChipSizeInByte) { result = false; } else if (0 == addr.start && (0 == addr.length)) { result = threadReadChip(Index); @@ -578,12 +746,18 @@ bool threadProgram(int Index) int pthread_mutex_destroy(pthread_mutex_t * mutex); + if(result && g_bIsNANDFlash == true) + { + result = ProgramNANDChip(Index); + goto exit; + } + if (result && ProgramChip(Index)) { result = true; } else { result = false; } - + exit: g_is_operation_successful[Index] = result; return result; } @@ -610,13 +784,22 @@ bool threadCompareFileAndChip(int Index) result = false; if (result) { - ReadChip(DownloadAddrRange, Index); - - size_t offset = min(DownloadAddrRange.length, g_ulFileSize); - unsigned int crcFile = CRC32(pBufferforLoadedFile, offset); - unsigned int crcChip = CRC32(pBufferForLastReadData[Index], offset); + if(g_bIsNANDFlash == true){ + + DownloadAddrRange.start = (g_iNandBlockIndex * g_NANDContext.realBlockSize); + DownloadAddrRange.end = (DownloadAddrRange.start + (g_usFileBlockCount * g_NANDContext.realBlockSize)); + DownloadAddrRange.length = DownloadAddrRange.end-DownloadAddrRange.start; + //printf("ReadBINFileForNAND(), DownloadAddrRange.start=%ld, DownloadAddrRange.end=%ld, DownloadAddrRange.length=%ld\n", DownloadAddrRange.start, DownloadAddrRange.end,DownloadAddrRange.length); + result = SPINAND_RangeVerify(&DownloadAddrRange,Index); + } + else{ + ReadChip(DownloadAddrRange, Index); + size_t offset = min(DownloadAddrRange.length, g_ulFileSize); + unsigned int crcFile = CRC32(pBufferforLoadedFile, offset); + unsigned int crcChip = CRC32(pBufferForLastReadData[Index], offset); - result = (crcChip == crcFile); + result = (crcChip == crcFile); + } } g_is_operation_successful[Index] = result; @@ -624,6 +807,38 @@ bool threadCompareFileAndChip(int Index) return result; } +bool threadScanBB(int Index) +{ + bool result = true; + if (strstr(g_ChipInfo.ICType, "SPI_NAND") == NULL) + return result; + + printf("\nScanning blocks...\n\n"); + g_BBT[Index].cnt=0; + SetIOMode(false, Index); + SetSPIClockDefault(Index); + SPINAND_ScanBadBlock(g_BBT[Index].bbt,&g_BBT[Index].cnt,Index); + if(g_BBT[Index].cnt > 0) + { + if(g_BBT[Index].cnt==1) + printf("There is 1 bad block: %d\n", g_BBT[Index].bbt[0]); + else + { + printf("There are %d bad blocks: ", g_BBT[Index].cnt); + for(unsigned short i=0; i 0) { offsetOfRealStartAddrOffset = LockAddrrange.start - effectiveRange.start; memcpy(pBufferforLoadedFile + offsetOfRealStartAddrOffset, pBufferForLastReadData[Index] + offsetOfRealStartAddrOffset, LockAddrrange.length); - Leng = GenerateDiff(addrs, vc, DownloadAddrRange.length, pBufferforLoadedFile, g_ulFileSize, DownloadAddrRange.start, Chip_Info.MaxErasableSegmentInByte); + Leng = GenerateDiff(addrs, vc, DownloadAddrRange.length, pBufferforLoadedFile, g_ulFileSize, DownloadAddrRange.start, g_ChipInfo.MaxErasableSegmentInByte); } else { offsetOfRealStartAddrOffset = DownloadAddrRange.start - effectiveRange.start; -Leng = GenerateDiff(addrs, vc + offsetOfRealStartAddrOffset, DownloadAddrRange.length, pBufferforLoadedFile, g_ulFileSize, DownloadAddrRange.start, Chip_Info.MaxErasableSegmentInByte); +Leng = GenerateDiff(addrs, vc + offsetOfRealStartAddrOffset, DownloadAddrRange.length, pBufferforLoadedFile, g_ulFileSize, DownloadAddrRange.start, g_ChipInfo.MaxErasableSegmentInByte); } if (Leng == 0) // speed optimisation @@ -714,14 +929,14 @@ Leng = GenerateDiff(addrs, vc + offsetOfRealStartAddrOffset, DownloadAddrRange.l else { uintptr_t* condensed_addr = (size_t*)malloc(min(DownloadAddrRange.length, g_ulFileSize)); size_t condensed_size; - condensed_size = Condense(condensed_addr, vc, addrs, Leng, effectiveRange.start, Chip_Info.MaxErasableSegmentInByte); + condensed_size = Condense(condensed_addr, vc, addrs, Leng, effectiveRange.start, g_ChipInfo.MaxErasableSegmentInByte); - if (strstr(Chip_Info.Class, SUPPORT_WINBOND_W25Mxx_Large) != NULL) + if (strstr(g_ChipInfo.Class, SUPPORT_WINBOND_W25Mxx_Large) != NULL) SerialFlash_batchErase_W25Mxx_Large(condensed_addr, condensed_size, Index); else SerialFlash_batchErase(condensed_addr, condensed_size, Index); - if (strstr(Chip_Info.Class, SUPPORT_MACRONIX_MX25Lxxx) != NULL) { + if (strstr(g_ChipInfo.Class, SUPPORT_MACRONIX_MX25Lxxx) != NULL) { TurnOFFVcc(Index); Sleep(100); TurnONVcc(Index); @@ -734,7 +949,7 @@ Leng = GenerateDiff(addrs, vc + offsetOfRealStartAddrOffset, DownloadAddrRange.l size_t idx_in_vc = addrs[i] - effectiveRange.start; struct CAddressRange addr_range; addr_range.start = addrs[i]; - addr_range.end = addrs[i] + Chip_Info.MaxErasableSegmentInByte; + addr_range.end = addrs[i] + g_ChipInfo.MaxErasableSegmentInByte; addr_range.length = addr_range.end - addr_range.start; if (SerialFlash_rangeProgram(&addr_range, vc + idx_in_vc, Index) == 0) { @@ -763,7 +978,7 @@ bool RangeUpdateThruSectorErase(int Index) bool RangeUpdateThruChipErase(int Index) { - unsigned char* vc = (unsigned char*)malloc(Chip_Info.ChipSizeInByte); + unsigned char* vc = (unsigned char*)malloc(g_ChipInfo.ChipSizeInByte); unsigned int i = 0; bool boIsBlank = true; struct CAddressRange addr; @@ -773,9 +988,9 @@ bool RangeUpdateThruChipErase(int Index) if (!threadReadChip(Index)) return false; - memcpy(vc, pBufferForLastReadData, Chip_Info.ChipSizeInByte); + memcpy(vc, pBufferForLastReadData, g_ChipInfo.ChipSizeInByte); - for (i = 0; i < Chip_Info.ChipSizeInByte; i++) { + for (i = 0; i < g_ChipInfo.ChipSizeInByte; i++) { if (vc[i] != 0xFF) { boIsBlank = false; break; @@ -785,20 +1000,20 @@ bool RangeUpdateThruChipErase(int Index) if (threadEraseWholeChip(Index) == false) return false; - if (strstr(Chip_Info.Class, SUPPORT_MACRONIX_MX25Lxxx) != NULL || strstr(Chip_Info.Class, SUPPORT_ATMEL_45DBxxxD) != NULL) { + if (strstr(g_ChipInfo.Class, SUPPORT_MACRONIX_MX25Lxxx) != NULL || strstr(g_ChipInfo.Class, SUPPORT_ATMEL_45DBxxxD) != NULL) { TurnOFFVcc(Index); Sleep(100); TurnONVcc(Index); } } - memset(vc + DownloadAddrRange.start, g_ucFill, min(DownloadAddrRange.length, Chip_Info.ChipSizeInByte)); + memset(vc + DownloadAddrRange.start, g_ucFill, min(DownloadAddrRange.length, g_ChipInfo.ChipSizeInByte)); memcpy(vc + DownloadAddrRange.start, pBufferforLoadedFile, min(g_ulFileSize, DownloadAddrRange.length)); SetIOMode(true, Index); addr.start = 0; - addr.end = Chip_Info.ChipSizeInByte; - addr.length = Chip_Info.ChipSizeInByte; + addr.end = g_ChipInfo.ChipSizeInByte; + addr.length = g_ChipInfo.ChipSizeInByte; return SerialFlash_rangeProgram(&addr, vc, Index); @@ -806,7 +1021,7 @@ bool RangeUpdateThruChipErase(int Index) bool RangeUpdate(int Index) { - bool fast_load = (Chip_Info.ChipSizeInByte > (1 << 16)); + bool fast_load = (g_ChipInfo.ChipSizeInByte > (1 << 16)); return ((mcode_SegmentErase != 0) && fast_load) ? RangeUpdateThruSectorErase(Index) @@ -822,6 +1037,41 @@ bool ReplaceChipContentThruChipErase(int Index) return threadProgram(Index); } +bool threadPredefinedNandBatchSequences(int Index) +{ + bool result = true; + + if(pBufferforLoadedFile == NULL || g_usFileBlockCount == 0 || g_ulFileSize == 0) result = false; + if(result) + { + if(!threadScanBB(Index)) + result=false; + } + if( result ) + { + switch(g_BatchIndex) + { + case 1: + if(!threadBlankCheck(Index))//not blank + { + if(!threadEraseWholeChip(Index)) + result=false; + } + if(result == true) + result=threadScanBB(Index); + if(result == true) + result = threadProgram( Index); + break; + case 2: //special auto + break; + default: + result = false; + break; + } + } + return result; +} + bool threadPredefinedBatchSequences(int Index) { bool result = true; @@ -846,6 +1096,21 @@ bool threadPredefinedBatchSequences(int Index) return result; } +bool threadSpecialEraseWholeChip(int SiteIndex) +{ + bool result = true; + if(SiteIndex == -1 || SiteIndex >= 128) + return false; + + if(bAuto[SiteIndex] ==false) + result = SPINand_SpecialErase(0, g_NANDContext.realChipSize/g_NANDContext.realBlockSize, SiteIndex); + else + result = SPINand_SpecialErase(g_iNandBlockIndex, g_iNandBlockCount, SiteIndex); + + g_is_operation_successful[SiteIndex] = result; + return result; +} + void threadRun(void* Type) { THREAD_STRUCT* thread_data = (THREAD_STRUCT*)Type; @@ -857,17 +1122,17 @@ void threadRun(void* Type) int dwUID = ReadUID(Index); if (g_uiAddr == 0 && g_uiLen == 0) { - if(is_SF700_Or_SF600PG2(Index)){ - if (g_bIsSF700[Index] == true) - printf("\nDevice %d (SF7%05X):", Index + 1, dwUID); - else if (g_bIsSF600PG2[Index] == true) - printf("\nDevice %d (S6%05X):", Index + 1, dwUID); - } + if(is_SF700_Or_SF600PG2(Index)){ + if (g_bIsSF700[Index] == true) + printf("\nDevice %d (SF7%05d):", Index + 1, dwUID); + else if (g_bIsSF600PG2[Index] == true) + printf("\nDevice %d (S6B%05d):", Index + 1, dwUID); + } else { - if ((dwUID / 600000) == 0) - printf("\nDevice %d (DP%06d):", Index + 1, dwUID); - else - printf("\nDevice %d (SF%06d):", Index + 1, dwUID); + if ((dwUID / 600000) == 0) + printf("\nDevice %d (DP%06d):", Index + 1, dwUID); + else + printf("\nDevice %d (SF%06d):", Index + 1, dwUID); } } @@ -905,7 +1170,6 @@ void threadRun(void* Type) break; case PROGRAM_CHIP: - TurnONVpp(Index); threadProgram(Index); TurnOFFVpp(Index); @@ -926,10 +1190,20 @@ void threadRun(void* Type) case AUTO: TurnONVpp(Index); bAuto[Index] = true; - threadPredefinedBatchSequences(Index); + if(g_bIsNANDFlash) + threadPredefinedNandBatchSequences(Index); + else + threadPredefinedBatchSequences(Index); TurnOFFVpp(Index); break; + + case NAND_SCAN_BB: + TurnONVpp(Index); + threadScanBB(Index); + break; + case NAND_SPECIAL_ERASE: + threadSpecialEraseWholeChip(Index); default: break; } @@ -1137,24 +1411,37 @@ CHIP_INFO GetFirstDetectionMatch(char* TypeName, int Index) { CHIP_INFO binfo; binfo.UniqueID = 0; - unsigned int g_Vcc_temp = 0; - //char TypeName[1024]; - - // memset(TypeName, '\0', 1024); + // unsigned int g_Vcc_temp = 0; int Found = 0; int i = 0; int Loop = 3; if (strcmp(g_parameter_vcc, "NO") != 0) //g_parameter_vcc!=NO + { Loop = 1; + } - if (strlen(TypeName) != 0) - g_Vcc_temp = g_Vcc; +// if (strlen(TypeName) != 0) +// g_Vcc_temp = g_Vcc; for (i = 0; i < Loop; i++) { if (Found == 1) { - if (strlen(TypeName) != 0) - g_Vcc = g_Vcc_temp; + if (strcmp(g_parameter_vcc, "NO") == 0) + { + switch(binfo.VoltageInMv) + { + case 1800: + g_Vcc = vcc1_8V; + break; + case 2500: + g_Vcc = vcc2_5V; + break; + case 3300: + g_Vcc = vcc3_5V; + break; + } + + } break; } if (Loop != 1) @@ -1197,7 +1484,10 @@ CHIP_INFO GetFirstDetectionMatch(char* TypeName, int Index) if (Found == 0) { binfo.UniqueID = 0; binfo.TypeName[0] = '\0'; + TypeName[0] = '\0'; } + else + memcpy(TypeName,binfo.TypeName, sizeof(binfo.TypeName)); return binfo; //*TypeName; } @@ -1220,31 +1510,42 @@ void SetProgReadCommand(int Index) mcode_WREN = WREN; mcode_RDSR = RDSR; mcode_WRSR = WRSR; + mcode_WRDI = 0x04; mcode_ChipErase = CHIP_ERASE; - mcode_Program = PAGE_PROGRAM; - mcode_Read = BULK_FAST_READ; - mcode_SegmentErase = SE; - mcode_WRDI = 0x04; - mcode_ProgramCode_4Adr = 0xFF; - mcode_ReadCode = 0xFF; - - if (strcmp(Chip_Info.Class, SUPPORT_SST_25xFxx) == 0) { + mcode_SegmentErase = SE; + + if(strstr(g_ChipInfo.Class,"_Large") == NULL) + { + mcode_Program = PAGE_PROGRAM; + mcode_Read = BULK_FAST_READ; + mcode_ProgramCode_4Adr = 0xFF; + mcode_ReadCode = 0xFF; + } + else + { + mcode_Program = PP_4ADR_256BYTE; + mcode_Read = BULK_4BYTE_FAST_READ; + mcode_ProgramCode_4Adr = (g_ChipInfo.ProgramCmd & 0x000000FF);// single program cmd + mcode_ReadCode = (g_ChipInfo.ReadCmd & 0x000000FF); // single read cmd + } + + if (strcmp(g_ChipInfo.Class, SUPPORT_SST_25xFxx) == 0) { mcode_RDSR = RDSR; mcode_WRSR = WRSR; mcode_ChipErase = 0x60; mcode_Read = BULK_NORM_READ; - if (strstr(Chip_Info.TypeName, "B") != NULL || strstr(Chip_Info.TypeName, "W") != NULL) + if (strstr(g_ChipInfo.TypeName, "B") != NULL || strstr(g_ChipInfo.TypeName, "W") != NULL) mcode_Program = AAI_2_BYTE; else mcode_Program = AAI_1_BYTE; - } else if (strstr(Chip_Info.Class, SUPPORT_SST_25xFxxA) != NULL) { + } else if (strstr(g_ChipInfo.Class, SUPPORT_SST_25xFxxA) != NULL) { mcode_RDSR = RDSR; mcode_WRSR = WRSR; mcode_ChipErase = 0x60; mcode_Read = BULK_NORM_READ; mcode_Program = AAI_1_BYTE; - } else if (strstr(Chip_Info.Class, SUPPORT_SST_25xFxxB) != NULL) { + } else if (strstr(g_ChipInfo.Class, SUPPORT_SST_25xFxxB) != NULL) { mcode_RDSR = RDSR; mcode_WRSR = WRSR; mcode_ChipErase = 0x60; @@ -1252,7 +1553,7 @@ void SetProgReadCommand(int Index) mcode_Program = AAI_2_BYTE; mcode_SegmentErase = 0xD8; mcode_WRDI = WRDI; - } else if (strstr(Chip_Info.Class, SUPPORT_SST_25xFxxC) != NULL) { + } else if (strstr(g_ChipInfo.Class, SUPPORT_SST_25xFxxC) != NULL) { mcode_RDSR = RDSR; mcode_WRSR = WRSR; mcode_ChipErase = 0x60; @@ -1260,52 +1561,52 @@ void SetProgReadCommand(int Index) mcode_Program = PAGE_PROGRAM; mcode_SegmentErase = 0xD8; mcode_WREN = WREN; - } else if (strstr(Chip_Info.Class, SUPPORT_ATMEL_AT25FSxxx) != NULL) { + } else if (strstr(g_ChipInfo.Class, SUPPORT_ATMEL_AT25FSxxx) != NULL) { mcode_RDSR = RDSR; mcode_WRSR = WRSR; mcode_ChipErase = CHIP_ERASE; mcode_Read = BULK_NORM_READ; mcode_Program = PP_128BYTE; mcode_SegmentErase = 0xD8; - } else if (strstr(Chip_Info.Class, SUPPORT_ATMEL_AT25Fxxx) != NULL) { + } else if (strstr(g_ChipInfo.Class, SUPPORT_ATMEL_AT25Fxxx) != NULL) { mcode_RDSR = RDSR; mcode_WRSR = WRSR; mcode_ChipErase = CHIP_ERASE; mcode_Read = BULK_NORM_READ; mcode_Program = PP_128BYTE; mcode_SegmentErase = 0x52; - } else if (strstr(Chip_Info.Class, SUPPORT_ATMEL_AT26xxx) != NULL) { + } else if (strstr(g_ChipInfo.Class, SUPPORT_ATMEL_AT26xxx) != NULL) { mcode_RDSR = RDSR; mcode_WRSR = WRSR; mcode_ChipErase = CHIP_ERASE; mcode_Read = BULK_FAST_READ; mcode_SegmentErase = 0xD8; - if (AT26DF041 == Chip_Info.UniqueID) { + if (AT26DF041 == g_ChipInfo.UniqueID) { mcode_Program = PP_AT26DF041; - } else if (AT26DF004 == Chip_Info.UniqueID) { + } else if (AT26DF004 == g_ChipInfo.UniqueID) { mcode_Program = AAI_1_BYTE; } else { mcode_Program = PAGE_PROGRAM; } - } else if (strstr(Chip_Info.Class, SUPPORT_ESMT_F25Lxx) != NULL) { + } else if (strstr(g_ChipInfo.Class, SUPPORT_ESMT_F25Lxx) != NULL) { const unsigned int F25L04UA = 0x8C8C8C; mcode_RDSR = RDSR; mcode_WRSR = WRSR; mcode_ChipErase = CHIP_ERASE; mcode_Read = BULK_FAST_READ; mcode_SegmentErase = 0xD8; - if (F25L04UA == Chip_Info.UniqueID) + if (F25L04UA == g_ChipInfo.UniqueID) mcode_Program = AAI_1_BYTE; else mcode_Program = AAI_2_BYTE; // PAGE_PROGRAM; - } else if (strstr(Chip_Info.Class, SUPPORT_NUMONYX_Alverstone) != NULL) { + } else if (strstr(g_ChipInfo.Class, SUPPORT_NUMONYX_Alverstone) != NULL) { mcode_RDSR = RDSR; mcode_WRSR = WRSR; mcode_ChipErase = CHIP_ERASE; mcode_Read = BULK_NORM_READ; mcode_Program = MODE_NUMONYX_PCM; mcode_SegmentErase = 0xD8; - } else if (strstr(Chip_Info.Class, SUPPORT_EON_EN25QHxx_Large) != NULL || strstr(Chip_Info.Class, SUPPORT_MACRONIX_MX25Lxxx_Large) != NULL) { + } else if (strstr(g_ChipInfo.Class, SUPPORT_EON_EN25QHxx_Large) != NULL || strstr(g_ChipInfo.Class, SUPPORT_MACRONIX_MX25Lxxx_Large) != NULL) { mcode_RDSR = RDSR; mcode_WRSR = WRSR; mcode_ChipErase = CHIP_ERASE; @@ -1314,7 +1615,7 @@ void SetProgReadCommand(int Index) mcode_SegmentErase = 0xD8; mcode_ProgramCode_4Adr = 0x02; mcode_ReadCode = 0x0B; - } else if (strstr(Chip_Info.Class, SUPPORT_SPANSION_S25FLxx_Large) != NULL) { + } else if (strstr(g_ChipInfo.Class, SUPPORT_SPANSION_S25FLxx_Large) != NULL) { mcode_RDSR = RDSR; mcode_WRSR = WRSR; mcode_ChipErase = CHIP_ERASE; @@ -1323,34 +1624,34 @@ void SetProgReadCommand(int Index) mcode_SegmentErase = 0xD8; mcode_ProgramCode_4Adr = 0x12; mcode_ReadCode = 0x0C; - }else if (strstr(Chip_Info.Class, SUPPORT_SPANSION_S25FLxxS_Large) != NULL) { + }else if (strstr(g_ChipInfo.Class, SUPPORT_SPANSION_S25FLxxS_Large) != NULL) { mcode_RDSR = RDSR; mcode_WRSR = WRSR; mcode_ChipErase = CHIP_ERASE; - if(strstr(Chip_Info.TypeName, "S25FS256T") != NULL) + if(strstr(g_ChipInfo.TypeName, "S25FS256T") != NULL) mcode_Read = BULK_NORM_READ; else - mcode_Read = BULK_4BYTE_FAST_READ; + mcode_Read = BULK_4BYTE_FAST_READ; if(g_bIsSF600[Index] == true || g_bIsSF700[Index] == true || g_bIsSF600PG2[Index] == true) mcode_Program = PP_PROGRAM_ANYSIZE_PAGESIZE; else mcode_Program = PP_4ADR_256BYTE; mcode_SegmentErase = 0xD8; mcode_ProgramCode_4Adr = 0x12; - if (strstr(Chip_Info.TypeName, "S25HL01GT") != NULL - || strstr(Chip_Info.TypeName, "S25HL512T") != NULL - || strstr(Chip_Info.TypeName, "S25HL256T") != NULL - || strstr(Chip_Info.TypeName, "S25FS256T") != NULL - || strstr(Chip_Info.TypeName, "S35HL256T") != NULL) + if (strstr(g_ChipInfo.TypeName, "S25HL01GT") != NULL + || strstr(g_ChipInfo.TypeName, "S25HL512T") != NULL + || strstr(g_ChipInfo.TypeName, "S25HL256T") != NULL + || strstr(g_ChipInfo.TypeName, "S25FS256T") != NULL + || strstr(g_ChipInfo.TypeName, "S35HL256T") != NULL) mcode_ReadCode = 0x0B; else mcode_ReadCode = 0x0C; - } else if (strstr(Chip_Info.Class, SUPPORT_NUMONYX_N25Qxxx_Large_2Die) != NULL ) { + } else if (strstr(g_ChipInfo.Class, SUPPORT_NUMONYX_N25Qxxx_Large_2Die) != NULL ) { mcode_RDSR = RDSR; mcode_WRSR = WRSR; mcode_ChipErase = 0xC4; mcode_Program = PP_4ADDR_256BYTE_MICROM; - if (strstr(Chip_Info.TypeName, "N25Q512") != NULL) + if (strstr(g_ChipInfo.TypeName, "N25Q512") != NULL) mcode_SegmentErase = 0xD4; else mcode_SegmentErase = 0xD8; @@ -1364,7 +1665,7 @@ void SetProgReadCommand(int Index) mcode_Read = BULK_4BYTE_FAST_READ_MICRON; } - } else if (strstr(Chip_Info.Class, SUPPORT_NUMONYX_N25Qxxx_Large_4Die) != NULL) { + } else if (strstr(g_ChipInfo.Class, SUPPORT_NUMONYX_N25Qxxx_Large_4Die) != NULL) { mcode_RDSR = RDSR; mcode_WRSR = WRSR; mcode_ChipErase = 0xC4; @@ -1374,27 +1675,27 @@ void SetProgReadCommand(int Index) mcode_ReadCode = 0x03; mcode_Read = BULK_NORM_READ; - } else if (strstr(Chip_Info.Class, SUPPORT_NUMONYX_N25Qxxx_Large) != NULL) { + } else if (strstr(g_ChipInfo.Class, SUPPORT_NUMONYX_N25Qxxx_Large) != NULL) { mcode_RDSR = RDSR; mcode_WRSR = WRSR; mcode_ChipErase = CHIP_ERASE; mcode_Read = BULK_4BYTE_FAST_READ_MICRON; mcode_Program = PP_4ADDR_256BYTE_MICROM; - if (strstr(Chip_Info.TypeName, "N25Q512") != NULL) + if (strstr(g_ChipInfo.TypeName, "N25Q512") != NULL) mcode_SegmentErase = 0xD4; else mcode_SegmentErase = 0xD8; mcode_ProgramCode_4Adr = 0x02; mcode_ReadCode = 0x0B; - } else if (strstr(Chip_Info.Class, SUPPORT_MACRONIX_MX25Lxxx_PP32) != NULL) { + } else if (strstr(g_ChipInfo.Class, SUPPORT_MACRONIX_MX25Lxxx_PP32) != NULL) { mcode_RDSR = RDSR; mcode_WRSR = WRSR; mcode_ChipErase = CHIP_ERASE; mcode_Read = BULK_FAST_READ; mcode_Program = PP_32BYTE; mcode_SegmentErase = 0xD8; - } else if (strstr(Chip_Info.Class, SUPPORT_WINBOND_W25Pxx_Large) != NULL) { + } else if (strstr(g_ChipInfo.Class, SUPPORT_WINBOND_W25Pxx_Large) != NULL) { mcode_RDSR = RDSR; mcode_WRSR = WRSR; mcode_ChipErase = CHIP_ERASE; @@ -1403,11 +1704,11 @@ void SetProgReadCommand(int Index) mcode_SegmentErase = SE; mcode_ProgramCode_4Adr = 0x02; mcode_ReadCode = 0x0C; - } else if (strstr(Chip_Info.Class, SUPPORT_WINBOND_W25Mxx_Large) != NULL) { + } else if (strstr(g_ChipInfo.Class, SUPPORT_WINBOND_W25Mxx_Large) != NULL) { mcode_RDSR = RDSR; mcode_WRSR = WRSR; mcode_ChipErase = CHIP_ERASE; - if (strstr(g_board_type, "SF100") != NULL) // is sf100 + if (strstr(g_board_type, "SF100") != NULL) // is sf100 mcode_Program = PP_4ADDR_256BYTE_12; else mcode_Program = PP_4ADR_256BYTE; @@ -1415,7 +1716,7 @@ void SetProgReadCommand(int Index) mcode_SegmentErase = 0xDC; mcode_ProgramCode_4Adr = 0x12; mcode_ReadCode = 0x0C; - }else if (strstr(Chip_Info.Class, SUPPORT_WINBOND_W25Pxx) != NULL) { + }else if (strstr(g_ChipInfo.Class, SUPPORT_WINBOND_W25Pxx) != NULL) { mcode_RDSR = RDSR; mcode_WRSR = WRSR; mcode_ChipErase = CHIP_ERASE; @@ -1424,19 +1725,19 @@ void SetProgReadCommand(int Index) mcode_SegmentErase = SE; mcode_ProgramCode_4Adr = 0x02; mcode_ReadCode = 0x0B; - } else if (strstr(Chip_Info.Class, SUPPORT_ST_M25Pxx_Large) != NULL) { + } else if (strstr(g_ChipInfo.Class, SUPPORT_ST_M25Pxx_Large) != NULL) { mcode_RDSR = RDSR; mcode_WRSR = WRSR; mcode_ChipErase = CHIP_ERASE; mcode_Program = PP_4ADR_256BYTE; mcode_Read = BULK_4BYTE_FAST_READ; mcode_SegmentErase = SE; - if (strstr(Chip_Info.TypeName, "GD25LB256E") != NULL) + if (strstr(g_ChipInfo.TypeName, "GD25LB256E") != NULL) mcode_ProgramCode_4Adr = 0x12; else mcode_ProgramCode_4Adr = 0x02; mcode_ReadCode = 0x0C; - } else if (strstr(Chip_Info.Class, SUPPORT_WINBOND_W25Qxx_Large) != NULL) { + } else if (strstr(g_ChipInfo.Class, SUPPORT_WINBOND_W25Qxx_Large) != NULL) { mcode_RDSR = RDSR; mcode_WRSR = WRSR; mcode_ChipErase = CHIP_ERASE; @@ -1445,7 +1746,7 @@ void SetProgReadCommand(int Index) mcode_SegmentErase = SE; mcode_ProgramCode_4Adr = 0x02; mcode_ReadCode = 0x0B; - } else if (strstr(Chip_Info.Class, SUPPORT_ATMEL_45DBxxxB) != NULL) { + } else if (strstr(g_ChipInfo.Class, SUPPORT_ATMEL_45DBxxxB) != NULL) { mcode_RDSR = 0xD7; mcode_WRSR = 0; mcode_Read = BULK_AT45xx_READ; @@ -1453,9 +1754,9 @@ void SetProgReadCommand(int Index) mcode_SegmentErase = 0; CHIP_INFO mem_id; SetPageSize(&mem_id, 0); - Chip_Info.ChipSizeInByte = GetChipSize(); - Chip_Info.PageSizeInByte = GetPageSize(); - } else if (strstr(Chip_Info.Class, SUPPORT_ATMEL_45DBxxxD) != NULL) { + g_ChipInfo.ChipSizeInByte = GetChipSize(); + g_ChipInfo.PageSizeInByte = GetPageSize(); + } else if (strstr(g_ChipInfo.Class, SUPPORT_ATMEL_45DBxxxD) != NULL) { mcode_RDSR = 0xD7; mcode_WRSR = 0; mcode_Read = BULK_AT45xx_READ; @@ -1463,20 +1764,26 @@ void SetProgReadCommand(int Index) mcode_SegmentErase = 0; CHIP_INFO mem_id; SetPageSize(&mem_id, 0); - Chip_Info.ChipSizeInByte = GetChipSize(); - Chip_Info.PageSizeInByte = GetPageSize(); + g_ChipInfo.ChipSizeInByte = GetChipSize(); + g_ChipInfo.PageSizeInByte = GetPageSize(); } + else if(strstr(g_ChipInfo.Class, SUPPORT_GIGADEVICE_GD5F1GQ4xCx) != NULL){ + mcode_Program = PAGE_PROGRAM; + mcode_Read = BULK_NORM_READ; + mcode_ProgramCode_4Adr = 0x02; + mcode_ReadCode = 0x0B; + } } bool ProjectInitWithID(CHIP_INFO chipinfo, int Index) // by designated ID { DownloadAddrRange.start = 0; - DownloadAddrRange.end = Chip_Info.ChipSizeInByte; + DownloadAddrRange.end = g_ChipInfo.ChipSizeInByte; InitLED(Index); // SetTargetFlash(g_StartupMode,Index); //for SF600 Freescale issue SetProgReadCommand(Index); if (strcmp(g_parameter_vcc, "NO") == 0) { - switch (Chip_Info.VoltageInMv) { + switch (g_ChipInfo.VoltageInMv) { case 1800: g_Vcc = vcc1_8V; break; @@ -1494,9 +1801,205 @@ bool ProjectInitWithID(CHIP_INFO chipinfo, int Index) // by designated ID bool ProjectInit(int Index) // by designated ID { - Chip_Info = GetFirstDetectionMatch(strTypeName, Index); - if (Chip_Info.UniqueID == 0) { + g_ChipInfo = GetFirstDetectionMatch(g_strTypeName, Index); + if (g_ChipInfo.UniqueID == 0) { return false; } - return ProjectInitWithID(Chip_Info, Index); + return ProjectInitWithID(g_ChipInfo, Index); } + +#if 0 + bool analysisPartitionTable(bool SpareUseFile, char *strTblPath) + { + wstring wstr; + Context::CFileContext::NAND_PTN_TBL ptn_tbl; + + wstr.assign(strTblPath.begin(), strTblPath.end()); + m_context.file.nand_PartitionTablePath = wstr; + + boost::filesystem::wpath p(wstr); + wstring fmt(p.extension()); + boost::to_upper(fmt); + + if(fmt == L".CSV") + ptn_tbl = Context::CFileContext::PTN_CSV; + else if(fmt == L".MBN") + ptn_tbl = Context::CFileContext::PTN_MBN; + if(fmt == L".DEF") + ptn_tbl = Context::CFileContext::PTN_DEF; + if(fmt == L".DPMBN") + ptn_tbl = Context::CFileContext::PTN_DPMBN; + + + switch(ptn_tbl) + { + case Context::CFileContext::PTN_CSV://excel + { + CFile file; + CStringArray saData; + int nLen=0; + CString sFileName, str; + sFileName = m_context.file.nand_PartitionTablePath.c_str(); + CStdioFile readFile; + CString strLine; + vector vecstrLine; + CFileException fileException; + if(readFile.Open(sFileName, CFile::modeRead|CFile::shareDenyNone, &fileException)) + { + m_context.file.nand_BlockIndex.resize(0); + m_context.file.nand_EndBlock.resize(0); + m_context.file.nand_BlockCount.resize(0); + m_context.file.nand_MaxBlockCount.resize(0); + m_context.file.nand_SpareAreaUseFile.resize(0); + + + while (readFile.ReadString(strLine)) + { + vecstrLine.push_back(strLine); + CString token; + int position =0; + + m_context.file.nand_BlockIndex.push_back(_ttoi(vecstrLine[nLen].Tokenize(_T(";"),position))); + m_context.file.nand_EndBlock.push_back(_ttoi(vecstrLine[nLen].Tokenize(_T(";"),position))); + m_context.file.nand_BlockCount.push_back(_ttoi(vecstrLine[nLen].Tokenize(_T(";"),position))); + m_context.file.nand_MaxBlockCount.push_back(m_context.file.nand_BlockCount.back()); + m_context.file.nand_SpareAreaUseFile.push_back(SpareUseFile); + nLen++; + } + m_context.file.nand_ptnTable_ImageCount=nLen; + } + else + { + return false; + } + readFile.Close(); + } + break; + case Context::CFileContext::PTN_DEF://def + { + std::vector buffer; + bool bWrongFormat=false; + std::ifstream in(m_context.file.nand_PartitionTablePath.c_str(), std::ios::in|std::ios::binary) ; + in.seekg(0, in.end); + unsigned int FileLen = in.tellg(); + if((FileLen%16)!=0) + return false; + + char * buf = new char [FileLen]; + in.seekg(0, in.beg); + in.read(buf,FileLen); + + buffer.resize((FileLen)/sizeof(DWORD)); + memcpy((DWORD*)&buffer[0],&buf[0],FileLen); + + delete [] buf; + in.close(); + + if((buffer[0]==0x554f5247)&&(buffer[1]==0x45442050)&&(buffer[2]==0x454e4946)&&(buffer[3]==0x00000032))//group define2 + { + buffer.erase(buffer.begin(),buffer.begin()+4); + m_context.file.nand_BlockIndex.resize(0); + m_context.file.nand_EndBlock.resize(0); + m_context.file.nand_BlockCount.resize(0); + m_context.file.nand_MaxBlockCount.resize(0); + m_context.file.nand_SpareAreaUseFile.resize(0); + for(unsigned int i=0;i<((buffer.size()-4)/4);i++) + { + if(buffer[i*4+1]!=0xffffffff) + m_context.file.nand_BlockIndex.push_back(buffer[i*4+1]); + else + return false; + if(buffer[i*4+2]!=0xffffffff) + m_context.file.nand_EndBlock.push_back(buffer[i*4+2]); + else + return false; + if(buffer[i*4+3]!=0xffffffff) + { + m_context.file.nand_BlockCount.push_back(buffer[i*4+3]); + m_context.file.nand_MaxBlockCount.push_back(m_context.file.nand_BlockCount.back()); + } + else + return false; + m_context.file.nand_ptnTable_ImageCount=(buffer.size()-4)/4; + m_context.file.nand_SpareAreaUseFile.push_back(SpareUseFile); + } + if(((buffer[buffer.size()-3])!=0xffffffff) + &&((buffer[buffer.size()-2])!=0xffffffff) + &&((buffer[buffer.size()-1])!=0xffffffff)) + { + m_context.file.nand_BlockIndex.push_back(buffer[buffer.size()-3]); + m_context.file.nand_EndBlock.push_back(buffer[buffer.size()-2]); + m_context.file.nand_BlockCount.push_back(buffer[buffer.size()-1]); + m_context.file.nand_MaxBlockCount.push_back(m_context.file.nand_BlockCount.back()); + m_context.file.nand_ptnTable_ImageCount+=1; + m_context.file.nand_SpareAreaUseFile.push_back(SpareUseFile); + } + } + } + break; + case Context::CFileContext::PTN_MBN://mbn + case Context::CFileContext::PTN_DPMBN://dpmbn + { + std::vector buffer; + std::ifstream in(m_context.file.nand_PartitionTablePath.c_str(), std::ios::in|std::ios::binary) ; + in.seekg(0, in.end); + unsigned int FileLen = in.tellg(); + if((FileLen%16)!=0) + return false; + + char * buf = new char [FileLen]; + in.seekg(0, in.beg); + in.read(buf,FileLen); + buffer.resize(FileLen/sizeof(DWORD)); + memcpy((DWORD*)&buffer[0],&buf[0],FileLen); + delete [] buf; + in.close(); + + m_context.file.nand_BlockIndex.resize(0); + m_context.file.nand_EndBlock.resize(0); + m_context.file.nand_BlockCount.resize(0); + m_context.file.nand_MaxBlockCount.resize(0); + m_context.file.nand_FileOffset.clear(); + m_context.file.nand_SpareAreaUseFile.resize(0); + + if(!((buffer[buffer.size()-1]==0xffffffff) + ||(buffer[buffer.size()-2]==0xffffffff) + ||(buffer[buffer.size()-3]==0xffffffff))) + return false; + unsigned int i=0; + for( i=0;i<(buffer.size()-4)/4;i++) + { + if(buffer[i*4] == 0xffffffff && buffer[i*4+1] == 0xffffffff && buffer[i*4+2] == 0xffffffff && buffer[i*4+3] == 0xffffffff) + break; + if(buffer[i*4]!=0xffffffff) + m_context.file.nand_BlockIndex.push_back(buffer[i*4]); + else + return false; + + if(buffer[i*4+1]!=0xffffffff) + m_context.file.nand_EndBlock.push_back(buffer[i*4+1]); + else + return false; + if(buffer[i*4+2]!=0xffffffff) + { + m_context.file.nand_BlockCount.push_back(buffer[i*4+2]); + m_context.file.nand_MaxBlockCount.push_back(m_context.file.nand_BlockCount.back()); + } + else + return false; + + if(ptn_tbl == Context::CFileContext::PTN_DPMBN) + m_context.file.nand_FileOffset.push_back( + i==0? 0:m_context.file.nand_BlockIndex[i]-m_context.file.nand_BlockIndex[0]); + m_context.file.nand_SpareAreaUseFile.push_back(SpareUseFile); + } + m_context.file.nand_ptnTable_ImageCount=i;//(buffer.size()-4)/4; + } + break; + } + get_context().file.nand_UsePartitionFile = true; + m_context.file.nand_FileOverBBcnt.resize(m_context.file.nand_ptnTable_ImageCount); + m_context.file.nand_FileOverBBcnt_BC.resize(m_context.file.nand_ptnTable_ImageCount); + return true; + } +#endif diff --git a/project.h b/project.h index 1b2a020..a89bc28 100755 --- a/project.h +++ b/project.h @@ -27,6 +27,11 @@ typedef enum { // 07.03.2009 UPDATE_FIRMWARE, AUTO_UPDATE_FIRMWARE, + BLINK_SITE, + NAND_SCAN_BB, + NAND_SPECIAL_PROGRAM, + NAND_SPECIAL_ERASE, + NAND_SPECIAL_AUTO, } OPERATION_TYPE; @@ -70,6 +75,10 @@ bool threadReadRangeChip(struct CAddressRange range, int Index); bool threadConfiguredReadChip(int Index); bool threadCompareFileAndChip(int Index); bool threadReadChip(int Index); +bool threadScanBB(int Index); +bool threadPredefinedNandBatchSequences(int Index); + + int ReadBINFile(const char* filename, unsigned char* buf, unsigned long* size); int WriteBINFile(const char* filename, unsigned char* buf, unsigned long size); bool LoadFile(char* filename); diff --git a/usbdriver.c b/usbdriver.c index 62bc35c..dd0d003 100755 --- a/usbdriver.c +++ b/usbdriver.c @@ -1,7 +1,11 @@ #include "usbdriver.h" #include "FlashCommand.h" #include "project.h" +#ifdef __FreeBSD__ +#include +#else #include +#endif #include unsigned int m_nbDeviceDetected = 0; @@ -12,7 +16,7 @@ extern volatile bool g_bIsSF600PG2[16]; extern int g_CurrentSeriase; extern char g_board_type[8]; extern int g_firmversion; -extern CHIP_INFO Chip_Info; +extern CHIP_INFO g_ChipInfo; extern unsigned int g_uiDevNum; extern bool isSendFFsequence; @@ -622,3 +626,17 @@ long flash_ReadId(unsigned int read_id_code, unsigned int out_data_size, int Ind // printf("\n(Simon)Flash ID 0x%x (0x%x, %d)\n",rc, read_id_code, out_data_size); return rc; } + +int BulkPipeReadEx(unsigned char* pBuff, unsigned int cnRead, unsigned int timeOut, int Index) +{ + int ret, actual_length; + if (Index == -1) + Index = DevIndex; + + //unsigned long cnTemp = cnRead; + ret = libusb_bulk_transfer(dediprog_handle[Index], 2 | LIBUSB_ENDPOINT_IN, pBuff, cnRead, &actual_length, DEFAULT_TIMEOUT); + if (ret != 0) //libusb_bulk_transfer return false + return 0; + return cnRead; +} + diff --git a/usbdriver.h b/usbdriver.h index e5862d4..43c7547 100755 --- a/usbdriver.h +++ b/usbdriver.h @@ -3,7 +3,11 @@ #ifndef DEDI_USB_DRIVER #define DEDI_USB_DRIVER +#ifdef __FreeBSD__ +#include +#else #include +#endif #include #include #include @@ -68,5 +72,7 @@ int dediprog_set_vpp_voltage(int volt, int Index); long flash_ReadId(unsigned int read_id_code, unsigned int out_data_size, int Index); int BulkPipeWrite(unsigned char* pBuff, unsigned int size, unsigned int timeOut, int Index); +int BulkPipeReadEx(unsigned char* pBuff, unsigned int cnRead, unsigned int timeOut, int Index); + #endif //DEDI_USB_DRIVER