diff --git a/60-dediprog.rules b/60-dediprog.rules new file mode 100644 index 0000000..f9249bb --- /dev/null +++ b/60-dediprog.rules @@ -0,0 +1 @@ +ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="dada", MODE="666", GROUP="plugdev" diff --git a/ChipInfoDb.dedicfg b/ChipInfoDb.dedicfg new file mode 100644 index 0000000..eec9b34 --- /dev/null +++ b/ChipInfoDb.dedicfg @@ -0,0 +1,16847 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ChipInfoDb.h b/ChipInfoDb.h new file mode 100644 index 0000000..1ed084d --- /dev/null +++ b/ChipInfoDb.h @@ -0,0 +1,37 @@ +#pragma once +#ifndef ChipInfo_H + +#define ChipInfo_H + +#define NUMBER_OF_SUPPORTING_CHIPS 3 + +struct m_code_api +{ + int (*m_code_api_doRDSR)(unsigned char *cSR, int Index); + int (*m_code_api_doWRSR)(unsigned char cSR,int Index); + int (*m_code_api_doChipErase)(int Index); + int (*m_code_api_doProgram)(void); + int (*m_code_api_doRead)(char *name); + int (*m_code_api_doSegmentErase)(void); +}; + + + +int ChipInfoDbFindItem(CHIP_INFO ChipInfoDb[], int NumberOfItems, long JedecDeviceIDToFind); + +void ChipInfoDump(long JedecDeviceIDToFind); + +long ChipInfoDumpChipSizeInKByte(long Jedec); +int Dedi_Search_Chip_Db_ByTypeName(char* TypeName, CHIP_INFO *Chip_Info, int search_all); +void Dedi_Search_AllChip( CHIP_INFO *Chip_Info, int search_all); + + +#endif + + + + + + + + diff --git a/FileIO.cpp b/FileIO.cpp new file mode 100644 index 0000000..b5cc467 --- /dev/null +++ b/FileIO.cpp @@ -0,0 +1,189 @@ + +#include "stdafx.h" +#include "FileIO.h" +#include "IntelHexFile.h" +#include "MotorolaFile.h" + +#include +#include +#include + +#include +#include +#include + +CFileIO::FILE_FORMAT CFileIO::GetFileFormatFromExt(const wstring& csPath) +{ + //int pos = csPath.ReverseFind('.') ; + + //if(pos < 0) + // return UNKNOWN ; + + //CString fmt = csPath.Right(csPath.GetLength() - pos - 1) ; + //fmt.MakeUpper() ; + + boost::filesystem::wpath p(csPath); + + wstring fmt(p.extension()); + boost::to_upper(fmt); + + if(fmt == L".HEX") + return HEX ; + else if(fmt == L".S19" || fmt==L".MOT") + return S19 ; + else + return BIN ; +} + +// read file +bool CFileIO::Read(const wstring& csPath, std::vector& buffer,unsigned char PaddingByte) +{ + switch(GetFileFormatFromExt(csPath)) + { + case HEX : + return ReadHEXFile(csPath, buffer,PaddingByte) ; + case S19 : + return ReadS19File(csPath, buffer,PaddingByte) ; + default : + return ReadBINFile(csPath, buffer) ; + } +} + +// write file +bool CFileIO::Write(const std::vector& buffer, const wstring& csPath) +{ + switch(GetFileFormatFromExt(csPath)) + { + case HEX : + return WriteHEXFile(buffer, csPath) ; + case S19 : + return WriteS19File(buffer, csPath) ; + default : + return WriteBINFile(buffer, csPath) ; + } +} + +// read bin +bool CFileIO::ReadBINFile(const wstring& csPath, std::vector& buffer) +{ + //ANSI only + std::ifstream in(csPath.c_str(), std::ios::binary) ; + if(in == 0L) + return false ; + + // get file buffer + std::stringstream ss ; + ss << in.rdbuf() ; + in.close() ; + + // get length + std::string strBuff(ss.str()) ; + buffer.resize(strBuff.length()) ; + std::copy(strBuff.c_str(), strBuff.c_str() + strBuff.length(), buffer.begin()) ; + + return !buffer.empty() ; + +} + +// write bin +bool CFileIO::WriteBINFile(const std::vector& buffer, const wstring& csPath) +{ + //ANSI only + std::ofstream out(csPath.c_str(), std::ios::binary) ; + if(out == 0L) + return false ; + + std::copy(buffer.begin(), buffer.end(), std::ostream_iterator(out,"")) ; + + out.close() ; + + return true ; +} + +// read hex +bool CFileIO::ReadHEXFile(const wstring& csPath, std::vector& buffer,unsigned char PaddingByte) +{ + //ANSI only + char szPath[MAX_PATH] = {0}; + + WideCharToMultiByte( + CP_ACP, + WC_COMPOSITECHECK | WC_DEFAULTCHAR, + csPath.c_str(), + csPath.size(), + szPath, + MAX_PATH, + 0, + 0 + ); + buffer.clear(); + + return (HexFileToBin(szPath, buffer,PaddingByte)) ; +} + +//write hex +bool CFileIO::WriteHEXFile(const std::vector& buffer, const wstring& csPath) +{ + //FIXME + //ANSI only + //ANSI only + //char szPath[MAX_PATH] = {0}; + + //WideCharToMultiByte( + // CP_ACP, + // WC_COMPOSITECHECK | WC_DEFAULTCHAR, + // csPath.GetString(), + // csPath.GetLength(), + // szPath, + // MAX_PATH, + // 0, + // 0 + // ); + + //return (BinToHexFile(szPath, buffer)) ; + return (BinToHexFile(csPath, buffer)) ; + +} + +// read s19 +bool CFileIO::ReadS19File(const wstring& csPath, std::vector& buffer,unsigned char PaddingByte) +{ + //ANSI only + char szPath[MAX_PATH] = {0}; + + WideCharToMultiByte( + CP_ACP, + WC_COMPOSITECHECK | WC_DEFAULTCHAR, + csPath.c_str(), + csPath.size(), + szPath, + MAX_PATH, + 0, + 0 + ); + buffer.clear(); + return (S19FileToBin(szPath, buffer,PaddingByte)) ; + +} + +// write s19 +bool CFileIO::WriteS19File(const std::vector& buffer, const wstring& csPath) +{ + //FIXME + //ANSI only + //ANSI only + char szPath[MAX_PATH] = {0}; + + WideCharToMultiByte( + CP_ACP, + WC_COMPOSITECHECK | WC_DEFAULTCHAR, + csPath.c_str(), + csPath.size(), + szPath, + MAX_PATH, + 0, + 0 + ); + + return (BinToS19File(szPath, buffer)) ; +} diff --git a/FileIO.h b/FileIO.h new file mode 100644 index 0000000..d7cad04 --- /dev/null +++ b/FileIO.h @@ -0,0 +1,43 @@ + +// file operation +// read file to buffer +// supported file format : bin,hex,s19,ram ... + +#ifndef _ST_FILE_H +#define _ST_FILE_H + +#include +#include + +using std::wstring; + +class CFileIO +{ + + + enum FILE_FORMAT{ + BIN , + HEX, + S19, + } ; + + + FILE_FORMAT GetFileFormatFromExt(const wstring& csPath) ; + + bool ReadBINFile(const wstring& csPath, std::vector& buffer) ; + bool ReadHEXFile(const wstring& csPath, std::vector& buffer,unsigned char PaddingByte) ; + bool ReadS19File(const wstring& csPath, std::vector& buffer,unsigned char PaddingByte) ; + + bool WriteBINFile(const std::vector& buffer, const wstring& csPath) ; + bool WriteHEXFile(const std::vector& buffer, const wstring& csPath) ; + bool WriteS19File(const std::vector& buffer, const wstring& csPath) ; + +public : + bool Read(const wstring& csPath, std::vector& buffer, unsigned char PaddingByte) ; + + bool Write(const std::vector& buffer,const wstring& csPath) ; + +}; + + +#endif //_ST_FILE_H \ No newline at end of file diff --git a/FlashCommand.c b/FlashCommand.c new file mode 100644 index 0000000..e03d78d --- /dev/null +++ b/FlashCommand.c @@ -0,0 +1,243 @@ +/// CFlashCommand Implementations +//#include "stdafx.h" +#include "Macro.h" +#include "usbdriver.h" +#include "FlashCommand.h" +#define SerialFlash_FALSE -1 +#define SerialFlash_TRUE 1 +extern bool Is_NewUSBCommand(int Index); + +int FlashCommand_TransceiveOut(unsigned char *v, int len ,int has_result_in,int Index) +{ + CNTRPIPE_RQ rq ; + int i; + + rq.Function = URB_FUNCTION_VENDOR_ENDPOINT ; + rq.Direction = VENDOR_DIRECTION_OUT ; + rq.Request = TRANSCEIVE ; + if(Is_NewUSBCommand(Index)) + { + rq.Value = ((has_result_in==1)? RESULT_IN : NO_RESULT_IN ); + rq.Index = RFU ; + } + else + { + rq.Value = RFU ; + rq.Index = ((has_result_in==1)? RESULT_IN : NO_RESULT_IN ); + } + rq.Length = len; +#if 0 + printf("len = %d",len); + for (i=0 ; iend - AddrRange->start) >> divider ; + + vInstruction[0] = (unsigned char)(pageNum & 0xff) ; // lowest byte of length : page number + vInstruction[1] = (unsigned char)( (pageNum >> 8) & 0xff) ; // highest byte of length: page number + vInstruction[2] = (unsigned char)( (pageNum >> 16) & 0xff) ; // reserved + vInstruction[3] = modeWrite; // PAGE_PROGRAM, PAGE_WRITE, AAI_1_BYTE, AAI_2_BYTE, PP_128BYTE, PP_AT26DF041 + vInstruction[4] = WriteCom; + + if(Is_NewUSBCommand(Index)) + { + vInstruction[5] = 0; + vInstruction[6] = (AddrRange->start & 0xff); + vInstruction[7] = ((AddrRange->start >> 8) & 0xff); + vInstruction[8] = ((AddrRange->start >> 16) & 0xff); + vInstruction[9] = ((AddrRange->start >> 24) & 0xff); + rq.Value = 0; + rq.Index = 0; + rq.Length = (unsigned long)(10) ; + } + else + { + rq.Value = (unsigned short)(AddrRange->start & 0xffff) ; //16 bits LSB + rq.Index = (unsigned short)((AddrRange->start >> 16) & 0xffff) ; //16 bits MSB + rq.Length = (unsigned long)(5) ; + } + + // send rq via control pipe + return OutCtrlRequest(&rq, vInstruction, rq.Length,Index); +} + + +int FlashCommand_SendCommand_SetupPacketForAT45DBBulkWrite(struct CAddressRange *AddrRange, unsigned char modeWrite,unsigned char WriteCom,int Index) +{ + /* modeWrite: + 1: page-size = 256 + 2: page-size = 264 + 3: page-size = 512 + 4: page-size = 528 + 5: page-size = 1024 + 6: page-size = 1056 + */ + size_t pageSize[7] = { 0, 256, 264, 512, 528, 1024, 1056}; + + size_t pageNum = ((AddrRange->end- AddrRange->start) + pageSize[modeWrite] - 1) / pageSize[modeWrite] ; +// printf("modeWrite=%d\r\n",modeWrite); +// printf("pageNum=%d\t \r\n",pageNum); + + unsigned char vInstruction[10] ; + vInstruction[0] = (unsigned char)(pageNum & 0xff) ; // lowest byte of length : page number + vInstruction[1] = (unsigned char)( (pageNum >> 8) & 0xff) ; // highest byte of length: page number + vInstruction[2] = (unsigned char)( (pageNum >> 16) & 0xff) ; // reserved + vInstruction[3] = modeWrite; + vInstruction[4] = WriteCom; + CNTRPIPE_RQ rq ; + rq.Function = URB_FUNCTION_VENDOR_ENDPOINT ; + rq.Direction = VENDOR_DIRECTION_OUT ; + rq.Request = ATMEL45_WRITE ; + + if(Is_NewUSBCommand(Index)) + { + vInstruction[5] = 0; + vInstruction[6] = (AddrRange->start & 0xff); + vInstruction[7] = ((AddrRange->start >> 8) & 0xff); + vInstruction[8] = ((AddrRange->start >> 16) & 0xff); + vInstruction[9] = ((AddrRange->start >> 24) & 0xff); + rq.Value = 0; + rq.Index = 0; + rq.Length = (unsigned long)(10) ; + } + else + { + rq.Value = (unsigned short)(AddrRange->start & 0xffff) ; //16 bits LSB + rq.Index = (unsigned short)((AddrRange->start >> 16) & 0xffff) ; //16 bits MSB + rq.Length = (unsigned long)(5) ; + } + + // send rq via control pipe + return OutCtrlRequest(&rq, vInstruction, rq.Length, Index); +} + +int FlashCommand_SendCommand_SetupPacketForBulkRead(struct CAddressRange *AddrRange, unsigned char modeRead,unsigned char ReadCom,int Index) +{ + unsigned char vInstruction[10] ; + CNTRPIPE_RQ rq ; + rq.Function = URB_FUNCTION_VENDOR_ENDPOINT ; + rq.Direction = VENDOR_DIRECTION_OUT ; + rq.Request = DTC_READ ; + + // length in terms of 256 bytes + size_t pageNum = AddrRange->length >> 9 ; + + vInstruction[0] = (unsigned char)(pageNum & 0xff) ; // lowest byte of length : page number + vInstruction[1] = (unsigned char)( (pageNum >> 8) & 0xff) ; // highest byte of length: page number + vInstruction[2] = (unsigned char)( (pageNum >> 16) & 0xff) ; // reserved + vInstruction[3] = modeRead; // BULK_NORM_READ, BULK_FAST_READ + vInstruction[4] = ReadCom; + + if(Is_NewUSBCommand(Index)) + { + vInstruction[5] = 0; + vInstruction[6] = (AddrRange->start & 0xff); + vInstruction[7] = ((AddrRange->start >> 8) & 0xff); + vInstruction[8] = ((AddrRange->start >> 16) & 0xff); + vInstruction[9] = ((AddrRange->start >> 24) & 0xff); + rq.Value = 0; + rq.Index = 0; + rq.Length = (unsigned long)(10) ; + } + else + { + rq.Value = (unsigned short)(AddrRange->start & 0xffff) ; //16 bits LSB + rq.Index = (unsigned short)((AddrRange->start >> 16) & 0xffff) ; //16 bits MSB + rq.Length = (unsigned long)(5) ; + } + + // send rq via control pipe + return OutCtrlRequest(&rq, vInstruction,rq.Length,Index); +} + diff --git a/FlashCommand.h b/FlashCommand.h new file mode 100644 index 0000000..0e8b769 --- /dev/null +++ b/FlashCommand.h @@ -0,0 +1,27 @@ +#pragma once + +#ifndef FLASHCOMMANDS + +#define FLASHCOMMANDS + +#define FlashCommand_TRUE 1 +#define FlashCommand_FALSE 0 + + +int FlashCommand_TransceiveOut(unsigned char *v, int len,int has_result_in,int Index); + +int FlashCommand_TransceiveIn(unsigned char *v, int len,int Index); + +int FlashCommand_SendCommand_OutOnlyInstruction(unsigned char *v, int len, int Index); + +int FlashCommand_SendCommand_OutInstructionWithCS(unsigned char *v,int len, int Index); + +int FlashCommand_SendCommand_OneOutOneIn(unsigned char *vOut, int out_len, unsigned char *vIn, int in_len, int Index ); + +int FlashCommand_SendCommand_SetupPacketForBulkWrite(struct CAddressRange *AddrRange, unsigned char modeWrite,unsigned char WriteCom,int Index); + +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,int Index); + +#endif //FLASHCOMMANDS \ No newline at end of file diff --git a/IntelHexFile.c b/IntelHexFile.c new file mode 100644 index 0000000..728faec --- /dev/null +++ b/IntelHexFile.c @@ -0,0 +1,429 @@ +#include +#include +#include +#include +#include "Macro.h" +#include "IntelHexFile.h" +extern unsigned char* pBufferforLoadedFile; +extern unsigned long g_ulFileSize; +/* +* the choice for the total length (16) of a line, but the specification +* can support an another value +*/ +bool BinToHexFile(const char* filePath, unsigned char* vBuffer, unsigned long FileSize) +{ +// +anderson_variable 06/10/11 /////////////////////////////////////// +// unsigned char unch = 0x12; +//int j=0; +//int str1_cnt=0; +//int str2_cnt=0; + +//CString str; +//CString str1 = L""; +//CString str2 = L""; +//CString str_tmp = L""; +// -anderson_variable 06/10/11 /////////////////////////////////////// + FILE *FileOut ; /* input files */ + FileOut = fopen(filePath,"wt") ; + if(FileOut==NULL) + return false; + + size_t i; + t_one_line one_record ; + one_record.intel_adr = 0; + one_record.intel_type = INTEL_DATA_TYPE; + + char buf[256] = {0} ; + + int iULBA = (unsigned int)((FileSize >> 16) & 0xFFFF); + unsigned int idx = 0; + + do //for(unsigned int idx = 0; idx < iULBA; ++idx) + { + //Extended Linear Address Record (32-bit format only) + memset(buf, 0, sizeof(buf)) ; + fprintf(FileOut, ":02000004%04X%02X\n", idx, (unsigned char)(0x100 - 0x06 - (idx & 0xFF) - ((idx>>8) & 0xFF))); + + size_t len = iULBA ? 0x10000 : (FileSize & 0xFFFF); + while(len > 0) + { + one_record.intel_lg_data = ( LL_MAX_LINE > len ) ? len : LL_MAX_LINE ; + memcpy(one_record.intel_data,vBuffer + one_record.intel_adr + (idx<<16),one_record.intel_lg_data); +// copy(vBuffer + one_record.intel_adr + (idx<<16), +// vBuffer + one_record.intel_adr + (idx<<16) + one_record.intel_lg_data, +// one_record.intel_data) ; + + len -= one_record.intel_lg_data ; + + one_record.intel_lrc = one_record.intel_lg_data; + one_record.intel_lrc += ((one_record.intel_adr >> 8) & 0xff); + one_record.intel_lrc += (one_record.intel_adr &0xff); + one_record.intel_lrc += one_record.intel_type; + + memset(buf, 0, sizeof(buf)) ; + fprintf(FileOut, ":%02X%04X%02X", one_record.intel_lg_data, one_record.intel_adr, one_record.intel_type) ; + + for(i = 0; i < one_record.intel_lg_data ; ++ i) + { + memset(buf, 0, sizeof(buf)) ; + fprintf(FileOut, "%02X", (one_record.intel_data[i] & 0xff)) ; + one_record.intel_lrc += one_record.intel_data[i] ; + } + + memset(buf, 0, sizeof(buf)) ; + fprintf(FileOut, "%02X\n", ((0x100 - one_record.intel_lrc) & 0xff)); + one_record.intel_adr += one_record.intel_lg_data ; + } + idx++; + } while( iULBA--); + fprintf(FileOut, ":00000001FF\n"); + + fclose (FileOut); + + return true ; +} + +bool HexFileToBin(const char* filePath, unsigned char* vOutData,unsigned long* FileSize,unsigned char PaddingByte) +{ + FILE *Filin ; /* input files */ + + /* size in bytes */ + const long MEMORY_SIZE = 16*1024*1024 ; + const long ADDRESS_MASK = 0x00FFFFFF ; + const int MAX_LINE_SIZE = 256 ; + const int NO_ADDRESS_TYPE_SELECTED = 0 ; + const int LINEAR_ADDRESS = 1 ; + const int SEGMENTED_ADDRESS = 2 ; + + unsigned int Seg_Lin_Select = NO_ADDRESS_TYPE_SELECTED; + + const int CKS_8 = 0 ; + const int CKS_16LE = 1 ; + const int CKS_16BE = 2 ; + + int PadByte = PaddingByte; + + /* line inputted from file */ + char Line[MAX_LINE_SIZE]; + + /* flag that a file was read */ + bool Enable_Checksum_Error = false ; + bool Status_Checksum_Error = false ; + + /* cmd-line parameter # */ + unsigned char *p; + unsigned int i; + + /* Application specific */ + + unsigned int Nb_Bytes; + unsigned int First_Word, Address, Segment, Upper_Address; + unsigned int Lowest_Address, Highest_Address, Starting_Address; + unsigned int Phys_Addr, hType; + unsigned int temp; + + bool Starting_Address_Setted = false; + + int temp2; + + unsigned char Data_Str[MAX_LINE_SIZE]; + unsigned char Checksum = 0; + + unsigned short int wCKS; + unsigned short int w; + unsigned int Cks_Type = CKS_8; + unsigned int Cks_Start, Cks_End, Cks_Addr, Cks_Value; + bool Cks_range_set = false; + bool Cks_Addr_set = false; + + /* Just a normal file name */ + Filin = fopen(filePath,"r") ; + if(Filin == 0L) + return false ; + + /* allocate a buffer */ + unsigned char* Memory_Block = (unsigned char*)malloc(MEMORY_SIZE) ; + + /* To begin, assume the lowest address is at the end of the memory. + subsequent addresses will lower this number. At the end of the input + file, this value will be the lowest address. */ + Lowest_Address = MEMORY_SIZE - 1; + Highest_Address = 0; + + int readCnt = 0 ; + int checkCnt = 0 ; + bool boEndofFile=false; + + /* To begin, assume the lowest address is at the end of the memory. + subsequent addresses will lower this number. At the end of the input + file, this value will be the lowest address. */ + Segment = 0; + Upper_Address = 0; + Lowest_Address = MEMORY_SIZE - 1; + Highest_Address = 0; + + /* Now read the file & process the lines. */ + do /* repeat until EOF(Filin) */ + { + /* Read a line from input file. */ + fgets(Line,MAX_LINE_SIZE,Filin); + + /* Remove carriage return/line feed at the end of line. */ + i = strlen(Line)-1; + + if(':' != Line[0] && boEndofFile ==false) + { + free(Memory_Block); + return false;//0x0a != Line[0] && NULL != Line[0]) return false; + } + + if (Line[i] == '\n') Line[i] = '\0'; + + /* Scan the first two bytes and nb of bytes. + The two bytes are read in First_Word since it's use depend on the + record type: if it's an extended address record or a data record. + */ + sscanf (Line, ":%2x%4x%2x%s",&Nb_Bytes,&First_Word,&hType,Data_Str); + + Checksum = Nb_Bytes + (First_Word >> 8) + (First_Word & 0xFF) + hType; + + p = Data_Str; + + /* If we're reading the last record, ignore it. */ + switch (hType) + { + /* Data record */ + case 0: + Address = First_Word; + + if (Seg_Lin_Select == SEGMENTED_ADDRESS) + Phys_Addr = (Segment << 4) + Address; + else + /* LINEAR_ADDRESS or NO_ADDRESS_TYPE_SELECTED + Upper_Address = 0 as specified in the Intel spec. until an extended address + record is read. */ + Phys_Addr = ((Upper_Address << 16) & ADDRESS_MASK) + Address; + + /* Check that the physical address stays in the buffer's range. */ + if ((Phys_Addr + Nb_Bytes) <= MEMORY_SIZE -1) + { + /* Set the lowest address as base pointer. */ + if (Phys_Addr < Lowest_Address) + Lowest_Address = Phys_Addr; + + /* Same for the top address. */ + temp = Phys_Addr + Nb_Bytes -1; + + if (temp > Highest_Address) + Highest_Address = temp; + + /* Read the Data bytes. */ + /* Bytes are written in the Memory block even if checksum is wrong. */ + if(Nb_Bytes==0) + { + free(Memory_Block); + return false; + } + for (i= Nb_Bytes; i > 0; i--) + { + sscanf ((const char *)(p), "%2x",&temp2); + p += 2; + Memory_Block[Phys_Addr++] = temp2; + Checksum = (Checksum + temp2) & 0xFF; + }; + + /* Read the Checksum value. */ + sscanf ((const char *)(p), "%2x",&temp2); + + /* Verify Checksum value. */ + Checksum = (Checksum + temp2) & 0xFF; + + if ((Checksum != 0) && Enable_Checksum_Error) + { + Status_Checksum_Error = true; + } + } + else + { + if (Seg_Lin_Select == SEGMENTED_ADDRESS) + fprintf(stderr,"Data record skipped at %4X:%4X\n",Segment,Address); + else + fprintf(stderr,"Data record skipped at %8X\n",Phys_Addr); + } + + break; + + /* End of file record */ + case 1: + /* Simply ignore checksum errors in this line. */ + boEndofFile=true; + break; + + /* Extended segment address record */ + case 2: + /* First_Word contains the offset. It's supposed to be 0000 so + we ignore it. */ + + /* First extended segment address record ? */ + if (Seg_Lin_Select == NO_ADDRESS_TYPE_SELECTED) + Seg_Lin_Select = SEGMENTED_ADDRESS; + + /* Then ignore subsequent extended linear address records */ + if (Seg_Lin_Select == SEGMENTED_ADDRESS) + { + sscanf ((const char *)(p), "%4x%2x",&Segment,&temp2); + + /* Update the current address. */ + Phys_Addr = (Segment << 4) & ADDRESS_MASK; + + /* Verify Checksum value. */ + Checksum = (Checksum + (Segment >> 8) + (Segment & 0xFF) + temp2) & 0xFF; + + if ((Checksum != 0) && Enable_Checksum_Error) + Status_Checksum_Error = true; + } + break; + + /* Start segment address record */ + case 3: + /* Nothing to be done since it's for specifying the starting address for + execution of the binary code */ + break; + + /* Extended linear address record */ + case 4: + /* First_Word contains the offset. It's supposed to be 0000 so + we ignore it. */ + + /* First extended linear address record ? */ + if (Seg_Lin_Select == NO_ADDRESS_TYPE_SELECTED) + Seg_Lin_Select = LINEAR_ADDRESS; + + /* Then ignore subsequent extended segment address records */ + if (Seg_Lin_Select == LINEAR_ADDRESS) + { + sscanf ((const char *)(p), "%4x%2x",&Upper_Address,&temp2); + + /* Update the current address. */ + Phys_Addr = Upper_Address << 4; + + /* Verify Checksum value. */ + Checksum = (Checksum + (Upper_Address >> 8) + (Upper_Address & 0xFF) + temp2) + & 0xFF; + + if ((Checksum != 0) && Enable_Checksum_Error) + Status_Checksum_Error = true; + } + break; + + /* Start linear address record */ + case 5: + /* Nothing to be done since it's for specifying the starting address for + execution of the binary code */ + break; + default: + break; // 20040617+ Added to remove GNU compiler warning about label at end of compound statement + } + } while (!feof (Filin)); + /*-----------------------------------------------------------------------------*/ + +// fprintf(stdout,"Lowest address = %08X\n",Lowest_Address); +// fprintf(stdout,"Highest address = %08X\n",Highest_Address); +// fprintf(stdout,"Pad Byte = %X\n", PadByte); + + wCKS = 0; + if( !Cks_range_set ) + { + Cks_Start = Lowest_Address; + Cks_End = Highest_Address; + } + switch (Cks_Type) + { + case 0: + + for (i=Cks_Start; i<=Cks_End; i++) + { + wCKS += Memory_Block[i]; + } + + //fprintf(stdout,"8-bit Checksum = %02X\n",wCKS & 0xff); + if( Cks_Addr_set ) + { + wCKS = Cks_Value - (wCKS - Memory_Block[Cks_Addr]); + Memory_Block[Cks_Addr] = (unsigned char)(wCKS & 0xff); + //fprintf(stdout,"Addr %08X set to %02X\n",Cks_Addr, wCKS & 0xff); + } + break; + + case 2: + + for (i=Cks_Start; i<=Cks_End; i+=2) + { + w = Memory_Block[i+1] | ((unsigned short)Memory_Block[i] << 8); + wCKS += w; + } + + //fprintf(stdout,"16-bit Checksum = %04X\n",wCKS); + if( Cks_Addr_set ) + { + w = Memory_Block[Cks_Addr+1] | ((unsigned short)Memory_Block[Cks_Addr] << 8); + wCKS = Cks_Value - (wCKS - w); + Memory_Block[Cks_Addr] = (unsigned char)(wCKS >> 8); + Memory_Block[Cks_Addr+1] = (unsigned char)(wCKS & 0xff); + //fprintf(stdout,"Addr %08X set to %04X\n",Cks_Addr, wCKS); + } + break; + + case 1: + + for (i=Cks_Start; i<=Cks_End; i+=2) + { + w = Memory_Block[i] | ((unsigned short)Memory_Block[i+1] << 8); + wCKS += w; + } + + //fprintf(stdout,"16-bit Checksum = %04X\n",wCKS); + if( Cks_Addr_set ) + { + w = Memory_Block[Cks_Addr] | ((unsigned short)Memory_Block[Cks_Addr+1] << 8); + wCKS = Cks_Value - (wCKS - w); + Memory_Block[Cks_Addr+1] = (unsigned char)(wCKS >> 8); + Memory_Block[Cks_Addr] = (unsigned char)(wCKS & 0xff); + //fprintf(stdout,"Addr %08X set to %04X\n",Cks_Addr, wCKS); + } + + default: + ; + } + + /* This starting address is for the binary file, + + ex.: if the first record is :nn010000ddddd... + the data supposed to be stored at 0100 will start at 0000 in the binary file. + + Specifying this starting address will put FF bytes in the binary file so that + the data supposed to be stored at 0100 will start at the same address in the + binary file. + */ + + if(Starting_Address_Setted) + { + Lowest_Address = Starting_Address; + } + + if(pBufferforLoadedFile != NULL) + free(pBufferforLoadedFile); +// pBufferforLoadedFile=(unsigned char*)malloc(Highest_Address -Lowest_Address+ 1); + pBufferforLoadedFile=(unsigned char*)malloc(Highest_Address+ 1); + + if( Lowest_Address < Highest_Address) + { +// memcpy(pBufferforLoadedFile,Memory_Block + Lowest_Address, Highest_Address -Lowest_Address+ 1 ) ; +// g_ulFileSize=(Highest_Address -Lowest_Address+ 1); ; + memcpy(pBufferforLoadedFile,Memory_Block, Highest_Address+ 1 ) ; + g_ulFileSize=(Highest_Address+ 1); ; + } + + free(Memory_Block); + return true; +} diff --git a/IntelHexFile.cpp b/IntelHexFile.cpp new file mode 100644 index 0000000..b7e84e0 --- /dev/null +++ b/IntelHexFile.cpp @@ -0,0 +1,414 @@ +#include "IntelHexFile.h" + +/* +* the choice for the total length (16) of a line, but the specification +* can support an another value +*/ +#if 0 +bool BinToHexFile(const wstring& filePath, const vector& vBuffer) +{ +// +anderson_variable 06/10/11 /////////////////////////////////////// +// unsigned char unch = 0x12; +//int j=0; +//int str1_cnt=0; +//int str2_cnt=0; + +//CString str; +//CString str1 = L""; +//CString str2 = L""; +//CString str_tmp = L""; +// -anderson_variable 06/10/11 /////////////////////////////////////// + + wofstream out(filePath.c_str()) ; + if(! out.is_open()) + return false ; + + //hex format + out.setf(std::ios::hex, std::ios::basefield) ; + + t_one_line one_record ; + one_record.intel_adr = 0; + one_record.intel_type = INTEL_DATA_TYPE; + + char buf[256] = {0} ; + + int iULBA = static_cast((vBuffer.size() >> 16) & 0xFFFF); + unsigned int idx = 0; + + do //for(unsigned int idx = 0; idx < iULBA; ++idx) + { + //Extended Linear Address Record (32-bit format only) + memset(buf, 0, sizeof(buf)) ; + sprintf(buf, ":02000004%04X%02X\n", idx, static_cast(0x100 - 0x06 - (idx & 0xFF) - ((idx>>8) & 0xFF))); + out << buf ; + + size_t len = iULBA ? 0x10000 : (vBuffer.size() & 0xFFFF); + while(len > 0) + { + one_record.intel_lg_data = ( LL_MAX_LINE > len ) ? len : LL_MAX_LINE ; + copy(vBuffer.begin() + one_record.intel_adr + (idx<<16), + vBuffer.begin() + one_record.intel_adr + (idx<<16) + one_record.intel_lg_data, + one_record.intel_data) ; + + len -= one_record.intel_lg_data ; + + one_record.intel_lrc = one_record.intel_lg_data; + one_record.intel_lrc += ((one_record.intel_adr >> 8) & 0xff); + one_record.intel_lrc += (one_record.intel_adr &0xff); + one_record.intel_lrc += one_record.intel_type; + + memset(buf, 0, sizeof(buf)) ; + sprintf(buf, ":%02X%04X%02X", one_record.intel_lg_data, one_record.intel_adr, one_record.intel_type) ; + out << buf ; + + for(size_t i = 0; i < one_record.intel_lg_data ; ++ i) + { + memset(buf, 0, sizeof(buf)) ; + sprintf(buf, "%02X", (one_record.intel_data[i] & 0xff)) ; + out << buf ; + one_record.intel_lrc += one_record.intel_data[i] ; + } + + memset(buf, 0, sizeof(buf)) ; + sprintf(buf, "%02X\n", ((0x100 - one_record.intel_lrc) & 0xff)); + out << buf ; + one_record.intel_adr += one_record.intel_lg_data ; + } + idx++; + } while( iULBA--); + out << ":00000001FF\n" ; + + out.close() ; + + return true ; +} +#endif +bool HexFileToBin(const char* filePath, unsigned char* vOutData,unsigned long* FileSize,unsigned char PaddingByte) +{ + FILE *Filin ; /* input files */ + + /* size in bytes */ + const long MEMORY_SIZE = 16*1024*1024 ; + const long ADDRESS_MASK = 0x00FFFFFF ; + const int MAX_LINE_SIZE = 256 ; + const int NO_ADDRESS_TYPE_SELECTED = 0 ; + const int LINEAR_ADDRESS = 1 ; + const int SEGMENTED_ADDRESS = 2 ; + + unsigned int Seg_Lin_Select = NO_ADDRESS_TYPE_SELECTED; + + const int CKS_8 = 0 ; + const int CKS_16LE = 1 ; + const int CKS_16BE = 2 ; + + int PadByte = PaddingByte; + + /* line inputted from file */ + char Line[MAX_LINE_SIZE]; + + /* flag that a file was read */ + bool Enable_Checksum_Error = false ; + bool Status_Checksum_Error = false ; + + /* cmd-line parameter # */ + unsigned char *p; + unsigned int i; + + /* Application specific */ + + unsigned int Nb_Bytes; + unsigned int First_Word, Address, Segment, Upper_Address; + unsigned int Lowest_Address, Highest_Address, Starting_Address; + unsigned int Phys_Addr, hType; + unsigned int temp; + + bool Starting_Address_Setted = false; + + int temp2; + + unsigned char Data_Str[MAX_LINE_SIZE]; + unsigned char Checksum = 0; + + unsigned short int wCKS; + unsigned short int w; + unsigned int Cks_Type = CKS_8; + unsigned int Cks_Start, Cks_End, Cks_Addr, Cks_Value; + bool Cks_range_set = false; + bool Cks_Addr_set = false; + + /* Just a normal file name */ + Filin = fopen(filePath,"r") ; + if(Filin == 0L) + return false ; + + /* allocate a buffer */ + unsigned char* Memory_Block = (unsigned char*)malloc(MEMORY_SIZE, PadByte) ; + + /* To begin, assume the lowest address is at the end of the memory. + subsequent addresses will lower this number. At the end of the input + file, this value will be the lowest address. */ + Lowest_Address = MEMORY_SIZE - 1; + Highest_Address = 0; + + int readCnt = 0 ; + int checkCnt = 0 ; + bool boEndofFile=false; + + /* To begin, assume the lowest address is at the end of the memory. + subsequent addresses will lower this number. At the end of the input + file, this value will be the lowest address. */ + Segment = 0; + Upper_Address = 0; + Lowest_Address = MEMORY_SIZE - 1; + Highest_Address = 0; + + /* Now read the file & process the lines. */ + do /* repeat until EOF(Filin) */ + { + /* Read a line from input file. */ + fgets(Line,MAX_LINE_SIZE,Filin); + + /* Remove carriage return/line feed at the end of line. */ + i = strlen(Line)-1; + + if(':' != Line[0] && boEndofFile ==false) return false;//0x0a != Line[0] && NULL != Line[0]) return false; + + if (Line[i] == '\n') Line[i] = '\0'; + + /* Scan the first two bytes and nb of bytes. + The two bytes are read in First_Word since it's use depend on the + record type: if it's an extended address record or a data record. + */ + sscanf (Line, ":%2x%4x%2x%s",&Nb_Bytes,&First_Word,&hType,Data_Str); + + Checksum = Nb_Bytes + (First_Word >> 8) + (First_Word & 0xFF) + hType; + + p = Data_Str; + + /* If we're reading the last record, ignore it. */ + switch (hType) + { + /* Data record */ + case 0: + Address = First_Word; + + if (Seg_Lin_Select == SEGMENTED_ADDRESS) + Phys_Addr = (Segment << 4) + Address; + else + /* LINEAR_ADDRESS or NO_ADDRESS_TYPE_SELECTED + Upper_Address = 0 as specified in the Intel spec. until an extended address + record is read. */ + Phys_Addr = ((Upper_Address << 16) & ADDRESS_MASK) + Address; + + /* Check that the physical address stays in the buffer's range. */ + if ((Phys_Addr + Nb_Bytes) <= MEMORY_SIZE -1) + { + /* Set the lowest address as base pointer. */ + if (Phys_Addr < Lowest_Address) + Lowest_Address = Phys_Addr; + + /* Same for the top address. */ + temp = Phys_Addr + Nb_Bytes -1; + + if (temp > Highest_Address) + Highest_Address = temp; + + /* Read the Data bytes. */ + /* Bytes are written in the Memory block even if checksum is wrong. */ + if(Nb_Bytes==0) + return false; + for (i= Nb_Bytes; i > 0; i--) + { + sscanf (reinterpret_cast(p), "%2x",&temp2); + p += 2; + Memory_Block[Phys_Addr++] = temp2; + Checksum = (Checksum + temp2) & 0xFF; + }; + + /* Read the Checksum value. */ + sscanf (reinterpret_cast(p), "%2x",&temp2); + + /* Verify Checksum value. */ + Checksum = (Checksum + temp2) & 0xFF; + + if ((Checksum != 0) && Enable_Checksum_Error) + { + Status_Checksum_Error = true; + } + } + else + { + if (Seg_Lin_Select == SEGMENTED_ADDRESS) + fprintf(stderr,"Data record skipped at %4X:%4X\n",Segment,Address); + else + fprintf(stderr,"Data record skipped at %8X\n",Phys_Addr); + } + + break; + + /* End of file record */ + case 1: + /* Simply ignore checksum errors in this line. */ + boEndofFile=true; + break; + + /* Extended segment address record */ + case 2: + /* First_Word contains the offset. It's supposed to be 0000 so + we ignore it. */ + + /* First extended segment address record ? */ + if (Seg_Lin_Select == NO_ADDRESS_TYPE_SELECTED) + Seg_Lin_Select = SEGMENTED_ADDRESS; + + /* Then ignore subsequent extended linear address records */ + if (Seg_Lin_Select == SEGMENTED_ADDRESS) + { + sscanf (reinterpret_cast(p), "%4x%2x",&Segment,&temp2); + + /* Update the current address. */ + Phys_Addr = (Segment << 4) & ADDRESS_MASK; + + /* Verify Checksum value. */ + Checksum = (Checksum + (Segment >> 8) + (Segment & 0xFF) + temp2) & 0xFF; + + if ((Checksum != 0) && Enable_Checksum_Error) + Status_Checksum_Error = true; + } + break; + + /* Start segment address record */ + case 3: + /* Nothing to be done since it's for specifying the starting address for + execution of the binary code */ + break; + + /* Extended linear address record */ + case 4: + /* First_Word contains the offset. It's supposed to be 0000 so + we ignore it. */ + + /* First extended linear address record ? */ + if (Seg_Lin_Select == NO_ADDRESS_TYPE_SELECTED) + Seg_Lin_Select = LINEAR_ADDRESS; + + /* Then ignore subsequent extended segment address records */ + if (Seg_Lin_Select == LINEAR_ADDRESS) + { + sscanf (reinterpret_cast(p), "%4x%2x",&Upper_Address,&temp2); + + /* Update the current address. */ + Phys_Addr = Upper_Address << 4; + + /* Verify Checksum value. */ + Checksum = (Checksum + (Upper_Address >> 8) + (Upper_Address & 0xFF) + temp2) + & 0xFF; + + if ((Checksum != 0) && Enable_Checksum_Error) + Status_Checksum_Error = true; + } + break; + + /* Start linear address record */ + case 5: + /* Nothing to be done since it's for specifying the starting address for + execution of the binary code */ + break; + default: + break; // 20040617+ Added to remove GNU compiler warning about label at end of compound statement + } + } while (!feof (Filin)); + /*-----------------------------------------------------------------------------*/ + +// fprintf(stdout,"Lowest address = %08X\n",Lowest_Address); +// fprintf(stdout,"Highest address = %08X\n",Highest_Address); +// fprintf(stdout,"Pad Byte = %X\n", PadByte); + + wCKS = 0; + if( !Cks_range_set ) + { + Cks_Start = Lowest_Address; + Cks_End = Highest_Address; + } + switch (Cks_Type) + { + case CKS_8: + + for (i=Cks_Start; i<=Cks_End; i++) + { + wCKS += Memory_Block[i]; + } + + //fprintf(stdout,"8-bit Checksum = %02X\n",wCKS & 0xff); + if( Cks_Addr_set ) + { + wCKS = Cks_Value - (wCKS - Memory_Block[Cks_Addr]); + Memory_Block[Cks_Addr] = (unsigned char)(wCKS & 0xff); + //fprintf(stdout,"Addr %08X set to %02X\n",Cks_Addr, wCKS & 0xff); + } + break; + + case CKS_16BE: + + for (i=Cks_Start; i<=Cks_End; i+=2) + { + w = Memory_Block[i+1] | ((unsigned short)Memory_Block[i] << 8); + wCKS += w; + } + + //fprintf(stdout,"16-bit Checksum = %04X\n",wCKS); + if( Cks_Addr_set ) + { + w = Memory_Block[Cks_Addr+1] | ((unsigned short)Memory_Block[Cks_Addr] << 8); + wCKS = Cks_Value - (wCKS - w); + Memory_Block[Cks_Addr] = (unsigned char)(wCKS >> 8); + Memory_Block[Cks_Addr+1] = (unsigned char)(wCKS & 0xff); + //fprintf(stdout,"Addr %08X set to %04X\n",Cks_Addr, wCKS); + } + break; + + case CKS_16LE: + + for (i=Cks_Start; i<=Cks_End; i+=2) + { + w = Memory_Block[i] | ((unsigned short)Memory_Block[i+1] << 8); + wCKS += w; + } + + //fprintf(stdout,"16-bit Checksum = %04X\n",wCKS); + if( Cks_Addr_set ) + { + w = Memory_Block[Cks_Addr] | ((unsigned short)Memory_Block[Cks_Addr+1] << 8); + wCKS = Cks_Value - (wCKS - w); + Memory_Block[Cks_Addr+1] = (unsigned char)(wCKS >> 8); + Memory_Block[Cks_Addr] = (unsigned char)(wCKS & 0xff); + //fprintf(stdout,"Addr %08X set to %04X\n",Cks_Addr, wCKS); + } + + default: + ; + } + + /* This starting address is for the binary file, + + ex.: if the first record is :nn010000ddddd... + the data supposed to be stored at 0100 will start at 0000 in the binary file. + + Specifying this starting address will put FF bytes in the binary file so that + the data supposed to be stored at 0100 will start at the same address in the + binary file. + */ + + if(Starting_Address_Setted) + { + Lowest_Address = Starting_Address; + } + + if( Lowest_Address < Highest_Address) + { + memcpy(vOutData,Memory_Block + Lowest_Address, Highest_Address -Lowest_Address+ 1, ) ; + } + + free(Memory_Block); + return true ; +} diff --git a/IntelHexFile.h b/IntelHexFile.h new file mode 100644 index 0000000..d8c4210 --- /dev/null +++ b/IntelHexFile.h @@ -0,0 +1,144 @@ +// +// +/****INTEL HEX-RECORD FORMAT, copied from http://www.cs.net/lucid/intel.htm**** + +INTRODUCTION +Intel's Hex-record format allows program or data files to be encoded in a +printable (ASCII) format. This allows viewing of the object file with standard +tools and easy file transfer from one computer to another, or between a host +and target. An individual Hex-record is a single line in a file composed of +many Hex-records. + +HEX-RECORD CONTENT +Hex-Records are character strings made of several fields which specify the +record type, record length, memory address, data, and checksum. Each byte of +binary data is encoded as a 2-character hexadecimal number: the first ASCII +character representing the high-order 4 bits, and the second the low-order 4 +bits of the byte. + +The 6 fields which comprise a Hex-record are defined as follows: + Field Characters Description +1 Start code 1 An ASCII colon, ":". +2 Byte count 2 The count of the character pairs in the data field. +3 Address 4 The 2-byte address at which the data field is to be loaded into memory. +4 Type 2 00, 01, or 02. +5 Data 0-2n From 0 to n bytes of executable code, or memory loadable data. + n is normally 20 hex (32 decimal) or less. +6 Checksum 2 The least significant byte of the two's complement sum of the values represented by all the pairs of characters in the record except the start code and checksum. + +Each record may be terminated with a CR/LF/NULL. Accuracy of transmission is ensured by the byte count and checksum fields. + +HEX-RECORD TYPES +There are three possible types of Hex-records. +00 +A record containing data and the 2-byte address at which the data is to reside. +01 +A termination record for a file of Hex-records. Only one termination record is allowed per file and it must be the last line of the file. There is no data field. +02 +A segment base address record. This type of record is ignored by Lucid programmers. + + +HEX-RECORD EXAMPLE +Following is a typical Hex-record module consisting of four data records and a termination record. + + :10010000214601360121470136007EFE09D2190140 + :100110002146017EB7C20001FF5F16002148011988 + :10012000194E79234623965778239EDA3F01B2CAA7 + :100130003F0156702B5E712B722B732146013421C7 + :00000001FF + +The first data record is explained as follows: + : Start code. + + 10 Hex 10 (decimal 16), indicating 16 data character + pairs, 16 bytes of binary data, in this record. + + 01 Four-character 2-byte address field: hex address 0100, + 00 indicates location where the following data is to be loaded. + + 00 Record type indicating a data record. + +The next 16 character pairs are the ASCII bytes of the actual program data. + + 40 Checksum of the first Hex-record. + + +The termination record is explained as follows: + + : Start code. + + 00 Byte count is zero, no data in termination record. + + 00 Four-character 2-byte address field, zeros. + 00 + + 01 Record type 01 is termination. + + FF Checksum of termination record. + + +-------------------------------------------------------------------------------- + +[ Back to Data & Documentation ] [ Home ] +-------------------------------------------------------------------------------- + + +*/ + +/* Intel Hex format specifications + +The 8-bit Intel Hex File Format is a printable ASCII format consisting of one + or more data records followed by an end of file record. Each +record consists of one line of information. Data records may appear in any + order. Address and data values are represented as 2 or 4 hexadecimal +digit values. + +Record Format +:LLAAAARRDDDD......DDDDCC + + +LL +AAAA +RR +DD +CC +Length field. Number of data bytes. +Address field. Address of first byte. +Record type field. 00 for data and 01 for end of record. +Data field. +Checksum field. One's complement of length, address, record type and data + fields modulo 256. +CC = LL + AAAA + RR + all DD = 0 + +Example: +:06010000010203040506E4 +:00000001FF + +The first line in the above example Intel Hex file is a data record addressed + at location 100H with data values 1 to 6. The second line is the end +of file record, so that the LL field is 0 + +*/ + +#ifndef INTELHEXFILE_H +#define INTELHEXFILE_H + +#define LL_MAX_LINE 16 +typedef struct +{ + unsigned char intel_lg_data; + unsigned short intel_adr; + unsigned char intel_type; + unsigned char intel_data [LL_MAX_LINE]; + unsigned char intel_lrc; +} t_one_line; + +#define INTEL_DATA_TYPE 0 + +//save binary data in vBuffer to file in Intel Hex format +bool BinToHexFile(const char* filePath, unsigned char* vBuffer, unsigned long FileSize) ; + +// read binary data from Intel Hex file +bool HexFileToBin(const char* filePath, unsigned char* vOutData,unsigned long* FileSize,unsigned char PaddingByte) ; + +#endif // end of header file diff --git a/Macro.h b/Macro.h new file mode 100644 index 0000000..0e58d60 --- /dev/null +++ b/Macro.h @@ -0,0 +1,358 @@ +#pragma once + +#ifndef _MACRO_H +#define _MACRO_H +#include +#include +#include +// new defined macros +//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_SA 0x0A + +//first field of RQ +#define OUT_REQUEST 0x42 +#define IN_REQUEST 0xC2 + +//second field of RQ in case of bulk transfer +//#define TRANSCEIVE 0x01 +//#define DTC_READ 0x20 +//#define WRITE 0x30 +//#define READ_EEPROM 0x05 +//#define WRITE_EEPROM 0x06 +// values of Request Field of a setup packet +typedef enum +{ + TRANSCEIVE = 0x01, + + DTC_READ = 0x20, + WRITE = 0x30, + + ATMEL45_WRITE = 0x31, + + READ_EEPROM = 0x05, + WRITE_EEPROM = 0x06, + GET_BUTTON_STATUS = 0x11, +}USB_CMD; + +typedef struct ChipInfo { + char TypeName[100]; + size_t UniqueID; + char Class[100]; + char Description[256]; + + char Manufacturer[100]; + char ManufactureUrl[100]; + 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; + size_t VoltageInMv; +}CHIP_INFO; +//third field of RQ +#define CTRL_TIMEOUT 3000 ///< time out for control pipe or for firmwire + +// fourth field of RQ +#define RESULT_IN 0x01 ///< result in or not +#define NO_RESULT_IN 0x00 +#define GET_REGISTER 0x01 ///< get register value or not +#define NO_REGISTER 0x00 +#define RFU 0x00 + +// bulk write mode +#define PAGE_PROGRAM 0x01 ///< pp via bulk pipes +#define PAGE_WRITE 0x02 ///< pw via bulk pipes +#define AAI_1_BYTE 0x03 +#define AAI_2_BYTE 0x04 +#define PP_128BYTE 0x05 +#define PP_AT26DF041 0x06 ///< PP AT26DF041 +#define PP_SB_FPGA 0x07 ///< Silicon Blue FPGA +#define MODE_NUMONYX_PCM 0x08 ///< Mode_Numonyx_pcm +#define PP_4ADR_256BYTE 0x09 +#define PP_32BYTE 0x0A +#define PP_4ADDR_256BYTE_12 0x0B +#define PP_4ADDR_256BYTE_MICROM 0x0C + +// bulk read mode +#define BULK_NORM_READ 0x01 ///< read via bulk pipes +#define BULK_FAST_READ 0x02 ///< fast read via bulk pipes +#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 flash card +#define POLLING 0x02 ///< polling +#define SET_VPP 0x03 ///< set vpp +#define VPP_OFF 0x00 ///< vpp value +#define VPP_9V 0x01 +#define VPP_12V 0x02 + +#define SET_TARGET_FLASH 0x04 ///< set target FLASH_TRAY +#define APPLICATION_MEMORY_1 0x00 ///< application memory chip 1 +#define FLASH_CARD 0x01 ///< flash card +#define APPLICATION_MEMORY_2 0x02 ///< application memory chip 2 + +//for io & LED +#define SET_IO 0x07 ///< request +//IO number +#define IO_1 0x01 +#define IO_2 0x02 +#define IO_3 0x04 +#define IO_4 0x08 +//led number +#define LED_RED 0x01 +#define LED_GREEN 0x02 +#define LED_ORANGE 0x04 + +#define SUPPORT_ST +#define SUPPORT_SST +#define SUPPORT_WINBOND +#define SUPPORT_PMC +#define SUPPORT_SPANSION +#define SUPPORT_MACRONIX +#define SUPPORT_EON +#define SUPPORT_ATMEL +#define SUPPORT_AMIC +#define SUPPORT_ESMT +#define SUPPORT_INTEL +#define SUPPORT_SANYO +#define SUPPORT_TSI +#define SUPPORT_FREESCALE +#define SUPPORT_SILICONBLUE +#define SUPPORT_NANTRONICS +#define SUPPORT_ATO +#define SUPPORT_FIDELIX +#define SUPPORT_FUDAN + +// memory support list +#ifdef SUPPORT_NANTRONICS + #define SUPPORT_NANTRONICS_N25Sxx "N25Sxx" +#endif + +#ifdef SUPPORT_ATO + #define SUPPORT_ATO_ATO25Qxx "ATO25Qxx" +#endif + +#ifdef SUPPORT_ST + #define SUPPORT_ST_M25PExx "M25PExx" + #define SUPPORT_ST_M25Pxx "M25Pxx" + #define SUPPORT_ST_M45PExx "M45PExx" + #define SUPPORT_NUMONYX_Alverstone "Alverstone" + #define SUPPORT_NUMONYX_N25Qxxx_Large "N25Qxxx_Large" +#endif + +#ifdef SUPPORT_SST + #define SUPPORT_SST_25xFxxA "25xFxxA" + #define SUPPORT_SST_25xFxxB "25xFxxB" + #define SUPPORT_SST_25xFxxC "25xFxxC" + #define SUPPORT_SST_25xFxx "25xFxx" + #define SUPPORT_SST_26xFxxC "26VFxxC" +#endif + +#ifdef SUPPORT_WINBOND + #define SUPPORT_WINBOND_W25Bxx "W25Bxx" + #define SUPPORT_WINBOND_W25Pxx "W25Pxx" + #define SUPPORT_WINBOND_W25Pxx_Large "W25Pxx_Large" + #define SUPPORT_WINBOND_W25Xxx "W25Xxx" +#endif + +#ifdef SUPPORT_PMC + #define SUPPORT_PMC_PM25LVxxx "PM25LVxxx" + #define SUPPORT_PMC_PM25Wxxx "PM25Wxxx" +#endif + +#ifdef SUPPORT_SPANSION + #define SUPPORT_SPANSION_S25FLxx "S25FLxx" + #define SUPPORT_SPANSION_S25FLxx_Large "S25FLxx_Large" +#endif + +#ifdef SUPPORT_MACRONIX + #define SUPPORT_MACRONIX_MX25Lxxx "MX25Lxxx" + #define SUPPORT_MACRONIX_MX25Lxxx_Large "MX25Lxxx_Large" + #define SUPPORT_MACRONIX_MX25Lxxx_PP32 "MX25Lxxx_PP32" +#endif + +#ifdef SUPPORT_EON + #define SUPPORT_EON_EN25Xxx "EN25Xxx" + #define SUPPORT_EON_EN25QHxx_Large "EN25QHxx_Large" +#endif + +#ifdef SUPPORT_ATMEL + #define SUPPORT_ATMEL_AT26xxx "AT26xxx" + #define SUPPORT_ATMEL_AT25Fxxx "AT25Fxxx" + #define SUPPORT_ATMEL_AT25FSxxx "AT25FSxxx" + #define SUPPORT_ATMEL_45DBxxxD "AT45DBxxxD" + #define SUPPORT_ATMEL_45DBxxxB "AT45DBxxxB" +#endif + +#ifdef SUPPORT_AMIC + #define SUPPORT_AMIC_A25Lxxx "A25Lxxx" + #define SUPPORT_AMIC_A25LQxxx "A25LQxxx" +#endif + +#ifdef SUPPORT_ESMT + #define SUPPORT_ESMT_F25Lxx "F25Lxx" +#endif + +#ifdef SUPPORT_INTEL + #define SUPPORT_INTEL_S33 "S33" +#endif + +#ifdef SUPPORT_FREESCALE + #define SUPPORT_FREESCALE_MCF "MCF" +#endif + +#ifdef SUPPORT_SANYO + #define SUPPORT_SANYO_LE25FWxxx "LE25FWxxx" +#endif + +#ifdef SUPPORT_TSI + #define SUPPORT_TSI_TS25Lxx "TS25Lxx" + #define SUPPORT_TSI_TS25Lxx_0A "TS25Lxx_0A" +#endif + +#ifdef SUPPORT_SILICONBLUE + #define SUPPORT_SILICONBLUE_iCE65 "iCE65" +#endif + +#ifdef SUPPORT_FIDELIX + #define SUPPORT_FIDELIX_FM25Qxx "FM25Qxx" +#endif + +#ifdef SUPPORT_FUDAN + #define SUPPORT_FUDAN_FM25Fxx "FM25Fxx" +#endif + + +// for usb +#define USB_TIMEOUT 8000 ///< time out value for usb EP2 + +// for SR reads +#define MAX_TRIALS 0x80000 + +#define BIT0 0x01 +#define BIT1 0x02 +#define BIT2 0x04 +#define BIT3 0x08 +#define BIT4 0x10 +#define BIT5 0x20 +#define BIT6 0x40 +#define BIT7 0x80 +#define BIT8 0x100 +#define BIT9 0x200 +#define BIT10 0x400 +#define BIT11 0x800 +#define BIT12 0x1000 +#define BIT13 0x2000 +#define BIT14 0x4000 +#define BIT15 0x8000 + +#define ERASE BIT0 +#define PROGRAM BIT1 +#define VERIFY BIT2 +#define BLANK BIT3 +#define DETECT BIT4 +#define BATCH BIT5 +#define TYPE BIT6 +#define FSUM BIT7 +#define CSUM BIT8 +#define READ_TO_FILE BIT9 +#define BLINK BIT10 +#define DEVICE_ID BIT11 +#define LIST_TYPE BIT12 +//#define size_t unsigned int +struct CAddressRange +{ + size_t start; + size_t end; + 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, + SITE_ERROR, + SITE_OK, +}; + +enum +{ + Seriase_45 = 0x08, + Seriase_25 = 0x00, +}; + +typedef enum +{ + vccPOWEROFF = 0x00, + + vcc3_5V = 0x10, + vcc2_5V = 0x11, + vcc1_8V = 0x12, + + vccdo_nothing = 0xFF, + +} VCC_VALUE; + + +#endif //_MACRO_H diff --git a/MotorolaFile.c b/MotorolaFile.c new file mode 100644 index 0000000..d00b243 --- /dev/null +++ b/MotorolaFile.c @@ -0,0 +1,443 @@ + //-------------------------------------------------------------------------------- + //NAME + //srec - S-record file and record format + //DESCRIPTION + + //An S-record file consists of a sequence of specially formatted ASCII character strings. An S-record will be less than or equal to 78 bytes in length. + //The order of S-records within a file is of no significance and no particular order may be assumed. + + //The general format of an S-record follows: + + //+-------------------//------------------//-----------------------+ + //| type | count | address | data | checksum | + //+-------------------//------------------//-----------------------+ + + //type -- A char[2] field. These characters describe the type of record (S0, S1, S2, S3, S5, S7, S8, or S9). + //count -- A char[2] field. These characters when paired and interpreted as a hexadecimal value, display the count of remaining character pairs in the record. + + //address -- A char[4,6, or 8] field. These characters grouped and interpreted as a hexadecimal value, display the address at which the data field is to be loaded into memory. The length of the field depends on the number of bytes necessary to hold the address. A 2-byte address uses 4 characters, a 3-byte address uses 6 characters, and a 4-byte address uses 8 characters. + + //data -- A char [0-64] field. These characters when paired and interpreted as hexadecimal values represent the memory loadable data or descriptive information. + + //checksum -- A char[2] field. These characters when paired and interpreted as a hexadecimal value display the least significant byte of the ones complement of the sum of the byte values represented by the pairs of characters making up the count, the address, and the data fields. + + //Each record is terminated with a line feed. If any additional or different record terminator(s) or delay characters are needed during transmission to the target system it is the responsibility of the transmitting program to provide them. + + //S0 Record. The type of record is 'S0' (0x5330). The address field is unused and will be filled with zeros (0x0000). The header information within the data field is divided into the following subfields. + + + //mname is char[20] and is the module name. + //ver is char[2] and is the version number. + //rev is char[2] and is the revision number. + //description is char[0-36] and is a text comment. + + //Each of the subfields is composed of ASCII bytes whose associated characters, when paired, represent one byte hexadecimal values in the case of the version and revision numbers, or represent the hexadecimal values of the ASCII characters comprising the module name and description. + //S1 Record. The type of record field is 'S1' (0x5331). The address field is intrepreted as a 2-byte address. The data field is composed of memory loadable data. + + //S2 Record. The type of record field is 'S2' (0x5332). The address field is intrepreted as a 3-byte address. The data field is composed of memory loadable data. + + //S3 Record. The type of record field is 'S3' (0x5333). The address field is intrepreted as a 4-byte address. The data field is composed of memory loadable data. + + //S5 Record. The type of record field is 'S5' (0x5335). The address field is intrepreted as a 2-byte value and contains the count of S1, S2, and S3 records previously transmitted. There is no data field. + + //S7 Record. The type of record field is 'S7' (0x5337). The address field contains the starting execution address and is intrepreted as 4-byte address. There is no data field. + + //S8 Record. The type of record field is 'S8' (0x5338). The address field contains the starting execution address and is intrepreted as 3-byte address. There is no data field. + + //S9 Record. The type of record field is 'S9' (0x5339). The address field contains the starting execution address and is intrepreted as 2-byte address. There is no data field. + + //EXAMPLE + + //Shown below is a typical S-record format file. + + //S00600004844521B + //S1130000285F245F2212226A000424290008237C2A + //S11300100002000800082629001853812341001813 + //S113002041E900084E42234300182342000824A952 + //S107003000144ED492 + //S5030004F8 + //S9030000FC + //The file consists of one S0 record, four S1 records, one S5 record and an S9 record. + + //The S0 record is comprised as follows: + + //S0 S-record type S0, indicating it is a header record. + //06 Hexadecimal 06 (decimal 6), indicating that six character pairs (or ASCII bytes) follow. + //00 00 Four character 2-byte address field, zeroes in this example. + + //48 44 52 ASCII H, D, and R - "HDR". + //1B The checksum. + //The first S1 record is comprised as follows: + //S1 S-record type S1, indicating it is a data record to be loaded at a 2-byte address. + //13 Hexadecimal 13 (decimal 19), indicating that nineteen character pairs, representing a 2 byte address, 16 bytes of binary data, and a 1 byte checksum, follow. + //00 00 Four character 2-byte address field; hexidecimal address 0x0000, where the data which follows is to be loaded. + //28 5F 24 5F 22 12 22 6A 00 04 24 29 00 08 23 7C Sixteen character pairs representing the actual binary data. + //2A The checksum. + //The second and third S1 records each contain 0x13 (19) character pairs and are ended with checksums of 13 and 52, respectively. The fourth S1 record contains 07 character pairs and has a checksum of 92. + + //The S5 record is comprised as follows: + + //S5 S-record type S5, indicating it is a count record indicating the number of S1 records + //03 Hexadecimal 03 (decimal 3), indicating that three character pairs follow. + //00 04 Hexadecimal 0004 (decimal 4), indicating that there are four data records previous to this record. + //F8 The checksum. + //The S9 record is comprised as follows: + + //S9 S-record type S9, indicating it is a termination record. + //03 Hexadecimal 03 (decimal 3), indicating that three character pairs follow. + //00 00 The address field, hexadecimal 0 (decimal 0) indicating the starting execution address. + //FC The checksum. + + + //-------------------------------------------------------------------------------- + + //Instructor Notes + //There isn't any evidence that Motorola ever has made use of the header information within the data field of the S0 record, as described above. This must have been used by some third party vendors. + //This is the only place that a 78-byte limit on total record length or 64-byte limit on data length is documented. These values shouldn't be trusted for the general case. + //The count field can have values in the range of 0x3 (2 bytes of address + 1 byte checksum = 3, a not very useful record) to 0xff; this is the count of remaining character pairs, including checksum. + //If you write code to convert S-Records, you should always assume that a record can be as long as 514 (decimal) characters in length (255 * 2 = 510, plus 4 characters for the type and count fields), + //plus any terminating character(s). That is, in establishing an input buffer in C, you would declare it to be an array of 515 chars, thus leaving room for the terminating null character. +#include +#include +#include +#include +#include "Macro.h" +#include "MotorolaFile.h" + +extern unsigned char* pBufferforLoadedFile; +extern unsigned long g_ulFileSize; + +bool S19FileToBin(const char* filePath, unsigned char* vData,unsigned long* FileSize, unsigned char PaddingByte) +{ + FILE *Filin ; /* input files */ + + /* size in bytes */ + const long MEMORY_SIZE = 1024*1024 * 4; + const long ADDRESS_MASK = 0x003FFFFF ; + const int MAX_LINE_SIZE = 512 ; + + const int CKS_8 = 0 ; + const int CKS_16LE = 1 ; + const int CKS_16BE = 2 ; + + int PadByte = PaddingByte; + + /* line inputted from file */ + char Line[MAX_LINE_SIZE]; + + /* flag that a file was read */ + bool Enable_Checksum_Error = false ; + bool Status_Checksum_Error = false ; + + /* cmd-line parameter # */ + unsigned char *p; + unsigned int i; + + /* Application specific */ + + unsigned int Nb_Bytes; + unsigned int Address, Lowest_Address, Highest_Address, Starting_Address; + unsigned int Phys_Addr, sType; + unsigned int temp; + + bool Starting_Address_Setted = false; + + int temp2; + + unsigned char Data_Str[MAX_LINE_SIZE]; + unsigned char Checksum = 0; + + unsigned short int wCKS; + unsigned short int w; + unsigned int Cks_Type = CKS_8; + unsigned int Cks_Start, Cks_End, Cks_Addr, Cks_Value; + bool Cks_range_set = false; + bool Cks_Addr_set = false; + + /* Just a normal file name */ + Filin = fopen(filePath,"rt") ; + if(Filin == 0L) + return false ; + + /* allocate a buffer */ + unsigned char* Memory_Block=(unsigned char*)malloc(MEMORY_SIZE) ; + memset(Memory_Block,PadByte,MEMORY_SIZE); + + /* To begin, assume the lowest address is at the end of the memory. + subsequent addresses will lower this number. At the end of the input + file, this value will be the lowest address. */ + Lowest_Address = MEMORY_SIZE - 1; + Highest_Address = 0; + + int readCnt = 0 ; + int checkCnt = 0 ; + + /* Now read the file & process the lines. */ + do /* repeat until EOF(Filin) */ + { + /* Read a line from input file. */ + fgets(Line,MAX_LINE_SIZE,Filin); + + /* Remove carriage return/line feed at the end of line. */ + i = strlen(Line)-1; + + if (Line[i] == '\n') Line[i] = '\0'; + + // check if this file is an S-file + if('S' != Line[0] && Line[0] != '\0') return false; + + /* Scan starting address and nb of bytes. */ + /* Look at the record sType after the 'S' */ + switch(Line[1]) + { + /* 16 bits address */ + case '1': + sscanf (Line,"S%1x%2x%4x%s",&sType,&Nb_Bytes,&Address,Data_Str); + Checksum = Nb_Bytes + (Address >> 8) + (Address & 0xFF); + + /* Adjust Nb_Bytes for the number of data bytes */ + Nb_Bytes = Nb_Bytes - 3; + break; + + /* 24 bits address */ + case '2': + sscanf (Line,"S%1x%2x%6x%s",&sType,&Nb_Bytes,&Address,Data_Str); + Checksum = Nb_Bytes + (Address >> 16) + (Address >> 8) + (Address & 0xFF); + + /* Adjust Nb_Bytes for the number of data bytes */ + Nb_Bytes = Nb_Bytes - 4; + break; + + /* 32 bits address */ + case '3': + sscanf (Line,"S%1x%2x%8x%s",&sType,&Nb_Bytes,&Address,Data_Str); + Checksum = Nb_Bytes + (Address >> 24) + (Address >> 16) + (Address >> 8) + (Address & 0xFF); + + /* Adjust Nb_Bytes for the number of data bytes */ + Nb_Bytes = Nb_Bytes - 5; + break; + + default: + break; // 20040617+ Added to remove GNU compiler warning about label at end of compound statement + } + + p = Data_Str; + + /* If we're reading the last record, ignore it. */ + switch (sType) + { + /* Data record */ + case 1: + case 2: + case 3: + Phys_Addr = Address & ADDRESS_MASK; + + /* Check that the physical address stays in the buffer's range. */ + if ((Phys_Addr + Nb_Bytes) <= MEMORY_SIZE -1) + { + /* Set the lowest address as base pointer. */ + if (Phys_Addr < Lowest_Address) + Lowest_Address = Phys_Addr; + + /* Same for the top address. */ + temp = Phys_Addr + Nb_Bytes -1; + + if (temp > Highest_Address) + Highest_Address = temp; + + /* Read the Data bytes. */ + for (i= Nb_Bytes; i > 0; i--) + { + sscanf ((const char *)(p), "%2x",&temp2); + p += 2; + Memory_Block[Phys_Addr++] = temp2; + Checksum = (Checksum + temp2) & 0xFF; + }; + + /* Read the Checksum value. */ + sscanf ((const char *)(p), "%2x",&temp2); + + /* Verify Checksum value. */ + Checksum = (0xFF - Checksum) & 0xFF; + + if ((temp2 != Checksum) && Enable_Checksum_Error) + { + Status_Checksum_Error = true; + } + } + else + { + //fprintf(stderr,"Data record skipped at %8X\n",Phys_Addr); + } + break; + + /* Ignore all other records */ + default: + break; // 20040617+ Added to remove GNU compiler warning about label at end of compound statement + } + } while (!feof (Filin)); + fclose (Filin); + /*-----------------------------------------------------------------------------*/ + +// fprintf(stdout,"Lowest address = %08X\n",Lowest_Address); +// fprintf(stdout,"Highest address = %08X\n",Highest_Address); +// fprintf(stdout,"Pad Byte = %X\n", PadByte); + + wCKS = 0; + if( !Cks_range_set ) + { + Cks_Start = Lowest_Address; + Cks_End = Highest_Address; + } + switch (Cks_Type) + { + case 0: + + for (i=Cks_Start; i<=Cks_End; i++) + { + wCKS += Memory_Block[i]; + } + + //fprintf(stdout,"8-bit Checksum = %02X\n",wCKS & 0xff); + if( Cks_Addr_set ) + { + wCKS = Cks_Value - (wCKS - Memory_Block[Cks_Addr]); + Memory_Block[Cks_Addr] = (unsigned char)(wCKS & 0xff); + //fprintf(stdout,"Addr %08X set to %02X\n",Cks_Addr, wCKS & 0xff); + } + break; + + case 2: + + for (i=Cks_Start; i<=Cks_End; i+=2) + { + w = Memory_Block[i+1] | ((unsigned short)Memory_Block[i] << 8); + wCKS += w; + } + + //fprintf(stdout,"16-bit Checksum = %04X\n",wCKS); + if( Cks_Addr_set ) + { + w = Memory_Block[Cks_Addr+1] | ((unsigned short)Memory_Block[Cks_Addr] << 8); + wCKS = Cks_Value - (wCKS - w); + Memory_Block[Cks_Addr] = (unsigned char)(wCKS >> 8); + Memory_Block[Cks_Addr+1] = (unsigned char)(wCKS & 0xff); + //fprintf(stdout,"Addr %08X set to %04X\n",Cks_Addr, wCKS); + } + break; + + case 1: + + for (i=Cks_Start; i<=Cks_End; i+=2) + { + w = Memory_Block[i] | ((unsigned short)Memory_Block[i+1] << 8); + wCKS += w; + } + + //fprintf(stdout,"16-bit Checksum = %04X\n",wCKS); + if( Cks_Addr_set ) + { + w = Memory_Block[Cks_Addr] | ((unsigned short)Memory_Block[Cks_Addr+1] << 8); + wCKS = Cks_Value - (wCKS - w); + Memory_Block[Cks_Addr+1] = (unsigned char)(wCKS >> 8); + Memory_Block[Cks_Addr] = (unsigned char)(wCKS & 0xff); + //fprintf(stdout,"Addr %08X set to %04X\n",Cks_Addr, wCKS); + } + + default: + ; + } + + if(Starting_Address_Setted) + { + Lowest_Address = Starting_Address; + } + + if(pBufferforLoadedFile!= NULL) + free(pBufferforLoadedFile); +// pBufferforLoadedFile=(unsigned char*)malloc(Highest_Address-Lowest_Address+1); +// g_ulFileSize=Highest_Address -Lowest_Address+ 1; +// memcpy(pBufferforLoadedFile,Memory_Block+Lowest_Address,Highest_Address-Lowest_Address+1); + pBufferforLoadedFile=(unsigned char*)malloc(Highest_Address+1); + g_ulFileSize=Highest_Address + 1; + memcpy(pBufferforLoadedFile,Memory_Block,Highest_Address+1); + + free(Memory_Block); + return true ; +} + +bool BinToS19File(const char* filePath, unsigned char* vData, unsigned long FileSize) +{ + //ANSI only + FILE *FileOut ; /* input files */ + FileOut = fopen(filePath,"wt") ; + if(FileOut==NULL) + return false; + + int i; + int chksum; + int total = 0 ; + int addr = 0x00000000; + long l1total = FileSize; + unsigned char recbuf[32] ; + char s19buf[128] ; + + while (l1total >= 32) { + // copy data + total = 32; + memcpy(recbuf,vData+addr,total); + + chksum = total+5; /* total bytes in this record */ + chksum += addr & 0xff; + chksum += (addr>>8) & 0xff; + chksum += (addr>>16) & 0xff; + chksum += (addr>>24) & 0xff; + + fprintf(FileOut, "S3"); + fprintf(FileOut, "%02X%08X", total+5, addr) ; + + memset(s19buf, 0, sizeof(s19buf)) ; + for(i=0;i>8) & 0xff; + chksum += (addr>>16) & 0xff; + chksum += (addr>>24) & 0xff; + + fprintf(FileOut, "S3") ; ; /* record header preamble */ + fprintf(FileOut, "%02X%08X", total+5, addr) ; + + memset(s19buf, 0, sizeof(s19buf)) ; + for(i=0;i> 8) + (Address & 0xFF); + + /* Adjust Nb_Bytes for the number of data bytes */ + Nb_Bytes = Nb_Bytes - 3; + break; + + /* 24 bits address */ + case '2': + sscanf (Line,"S%1x%2x%6x%s",&sType,&Nb_Bytes,&Address,Data_Str); + Checksum = Nb_Bytes + (Address >> 16) + (Address >> 8) + (Address & 0xFF); + + /* Adjust Nb_Bytes for the number of data bytes */ + Nb_Bytes = Nb_Bytes - 4; + break; + + /* 32 bits address */ + case '3': + sscanf (Line,"S%1x%2x%8x%s",&sType,&Nb_Bytes,&Address,Data_Str); + Checksum = Nb_Bytes + (Address >> 24) + (Address >> 16) + (Address >> 8) + (Address & 0xFF); + + /* Adjust Nb_Bytes for the number of data bytes */ + Nb_Bytes = Nb_Bytes - 5; + break; + + default: + break; // 20040617+ Added to remove GNU compiler warning about label at end of compound statement + } + + p = Data_Str; + + /* If we're reading the last record, ignore it. */ + switch (sType) + { + /* Data record */ + case 1: + case 2: + case 3: + Phys_Addr = Address & ADDRESS_MASK; + + /* Check that the physical address stays in the buffer's range. */ + if ((Phys_Addr + Nb_Bytes) <= MEMORY_SIZE -1) + { + /* Set the lowest address as base pointer. */ + if (Phys_Addr < Lowest_Address) + Lowest_Address = Phys_Addr; + + /* Same for the top address. */ + temp = Phys_Addr + Nb_Bytes -1; + + if (temp > Highest_Address) + Highest_Address = temp; + + /* Read the Data bytes. */ + for (i= Nb_Bytes; i > 0; i--) + { + sscanf (reinterpret_cast(p), "%2x",&temp2); + p += 2; + Memory_Block[Phys_Addr++] = temp2; + Checksum = (Checksum + temp2) & 0xFF; + }; + + /* Read the Checksum value. */ + sscanf (reinterpret_cast(p), "%2x",&temp2); + + /* Verify Checksum value. */ + Checksum = (0xFF - Checksum) & 0xFF; + + if ((temp2 != Checksum) && Enable_Checksum_Error) + { + Status_Checksum_Error = true; + } + } + else + { + //fprintf(stderr,"Data record skipped at %8X\n",Phys_Addr); + } + break; + + /* Ignore all other records */ + default: + break; // 20040617+ Added to remove GNU compiler warning about label at end of compound statement + } + } while (!feof (Filin)); + fclose (Filin); + /*-----------------------------------------------------------------------------*/ + +// fprintf(stdout,"Lowest address = %08X\n",Lowest_Address); +// fprintf(stdout,"Highest address = %08X\n",Highest_Address); +// fprintf(stdout,"Pad Byte = %X\n", PadByte); + + wCKS = 0; + if( !Cks_range_set ) + { + Cks_Start = Lowest_Address; + Cks_End = Highest_Address; + } + switch (Cks_Type) + { + case CKS_8: + + for (i=Cks_Start; i<=Cks_End; i++) + { + wCKS += Memory_Block[i]; + } + + //fprintf(stdout,"8-bit Checksum = %02X\n",wCKS & 0xff); + if( Cks_Addr_set ) + { + wCKS = Cks_Value - (wCKS - Memory_Block[Cks_Addr]); + Memory_Block[Cks_Addr] = (unsigned char)(wCKS & 0xff); + //fprintf(stdout,"Addr %08X set to %02X\n",Cks_Addr, wCKS & 0xff); + } + break; + + case CKS_16BE: + + for (i=Cks_Start; i<=Cks_End; i+=2) + { + w = Memory_Block[i+1] | ((unsigned short)Memory_Block[i] << 8); + wCKS += w; + } + + //fprintf(stdout,"16-bit Checksum = %04X\n",wCKS); + if( Cks_Addr_set ) + { + w = Memory_Block[Cks_Addr+1] | ((unsigned short)Memory_Block[Cks_Addr] << 8); + wCKS = Cks_Value - (wCKS - w); + Memory_Block[Cks_Addr] = (unsigned char)(wCKS >> 8); + Memory_Block[Cks_Addr+1] = (unsigned char)(wCKS & 0xff); + //fprintf(stdout,"Addr %08X set to %04X\n",Cks_Addr, wCKS); + } + break; + + case CKS_16LE: + + for (i=Cks_Start; i<=Cks_End; i+=2) + { + w = Memory_Block[i] | ((unsigned short)Memory_Block[i+1] << 8); + wCKS += w; + } + + //fprintf(stdout,"16-bit Checksum = %04X\n",wCKS); + if( Cks_Addr_set ) + { + w = Memory_Block[Cks_Addr] | ((unsigned short)Memory_Block[Cks_Addr+1] << 8); + wCKS = Cks_Value - (wCKS - w); + Memory_Block[Cks_Addr+1] = (unsigned char)(wCKS >> 8); + Memory_Block[Cks_Addr] = (unsigned char)(wCKS & 0xff); + //fprintf(stdout,"Addr %08X set to %04X\n",Cks_Addr, wCKS); + } + + default: + ; + } + + if(Starting_Address_Setted) + { + Lowest_Address = Starting_Address; + } + + memcpy(); + copy(Memory_Block.begin() + Lowest_Address, + Memory_Block.begin() + Highest_Address + 1, + back_inserter(vData)) ; + return true ; +} +#if 0 +bool BinToS19File(const string& filePath, const vector& vData) +{ + //ANSI only + std::ofstream out(filePath.c_str()) ; + if(out == 0L) + return false ; + + int i; + int chksum; + int total = 0 ; + int addr = 0x00000000; + long l1total = vData.size() ; + vector recbuf(32) ; + char s19buf[128] ; + + while (l1total >= 32) { + // copy data + total = 32; + copy(vData.begin() + addr, vData.begin() + addr + total, recbuf.begin()) ; + + chksum = total+5; /* total bytes in this record */ + chksum += addr & 0xff; + chksum += (addr>>8) & 0xff; + chksum += (addr>>16) & 0xff; + chksum += (addr>>24) & 0xff; + + out << "S3" ; /* record header preamble */ + memset(s19buf, 0, sizeof(s19buf)) ; + sprintf(s19buf, "%02X%08X", total+5, addr) ; + out << s19buf ; /* byte count +3, addr */ + + memset(s19buf, 0, sizeof(s19buf)) ; + for(i=0;i>8) & 0xff; + chksum += (addr>>16) & 0xff; + chksum += (addr>>24) & 0xff; + + out << "S3" ; /* record header preamble */ + memset(s19buf, 0, sizeof(s19buf)) ; + sprintf(s19buf, "%02X%08X", total+5, addr) ; + out << s19buf ; /* byte count +3, addr */ + + memset(s19buf, 0, sizeof(s19buf)) ; + for(i=0;i +#include + +extern int m_isCanceled; +extern int m_bProtectAfterWritenErase; +extern int m_boEnReadQuadIO; +extern int m_boEnWriteQuadIO; +extern CHIP_INFO Chip_Info; +extern volatile bool g_bIsSF600; +extern Sleep(unsigned int ms); +extern bool Is_NewUSBCommand(int Index); + +unsigned char mcode_WRSR=0x01; +unsigned char mcode_WRDI=0x04; +unsigned char mcode_RDSR=0x05; +unsigned char mcode_WREN=0x06; +unsigned char mcode_SegmentErase=SE; +unsigned char mcode_ChipErase=CHIP_ERASE; +unsigned char mcode_Program=PAGE_PROGRAM; +unsigned char mcode_ProgramCode_4Adr=0x02; +unsigned char mcode_Read=BULK_FAST_READ; +unsigned char mcode_ReadCode=0x0B; +unsigned int g_AT45_PageSize=0; +unsigned int g_AT45_PageSizeMask=0; +size_t AT45ChipSize=0; +size_t AT45PageSize=0; +bool AT45doRDSR(unsigned char* cSR, int Index) +{ + unsigned char Out=0xD7; + CNTRPIPE_RQ rq ; + unsigned char vInstruction; //size 1 + + // first control packet + vInstruction = 0xD7; + + rq.Function = URB_FUNCTION_VENDOR_ENDPOINT ; + rq.Direction = VENDOR_DIRECTION_OUT ; + rq.Request = TRANSCEIVE ; + if(Is_NewUSBCommand(Index)) + { + rq.Value = RESULT_IN; + rq.Index = RFU; + } + else + { + rq.Value = RFU ; + rq.Index = RESULT_IN ; + } + rq.Length = (unsigned long) 1 ; + + if(OutCtrlRequest(&rq, &vInstruction, 1, Index) == SerialFlash_FALSE) + return SerialFlash_FALSE ; + + // second control packet : fetch data + unsigned char vBuffer ; //just read one bytes , in fact more bytes are also available + rq.Function = URB_FUNCTION_VENDOR_ENDPOINT ; + rq.Direction = VENDOR_DIRECTION_IN ; + rq.Request = TRANSCEIVE ; + if(Is_NewUSBCommand(Index)) + { + rq.Value = 1; + rq.Index = 0; + } + else + { + rq.Value = CTRL_TIMEOUT; + rq.Index = NO_REGISTER; + } + rq.Length = (unsigned long) 1; + + if(InCtrlRequest(&rq, &vBuffer, 1, Index) == SerialFlash_FALSE) + return SerialFlash_FALSE ; + + *cSR = vBuffer; + + return SerialFlash_TRUE; +} + +bool AT45WaitForWIP(int USBIndex) +{ + unsigned char cSR ; + size_t i = Chip_Info.Timeout*100; + if(i==0) + i=0x10000; + // wait until WIP = 0 + do{ + AT45doRDSR(&cSR,USBIndex) ; + Sleep(10); + }while((!(cSR & 0x80)) && (i-- > 0)) ; // poll bit 7 + if(i<=0) return false; + + return true; +} + +unsigned char getWriteMode(int USBIndex) +{ + unsigned char cMode; + unsigned char cSR ; + AT45doRDSR(&cSR,USBIndex); + bool powerOfTwo = (1 == (cSR & 0x1)); + + typedef enum + { + AT45DB011D = 0x1F22, + AT45DB021D = 0x1F23, + AT45DB041D = 0x1F24, + AT45DB081D = 0x1F25, + AT45DB161D = 0x1F26, + AT45DB321D = 0x1F27, + AT45DB642D = 0x1F28, + }; + + switch(Chip_Info.UniqueID) + { + case AT45DB011D: + case AT45DB021D: + case AT45DB041D: + case AT45DB081D: + cMode = powerOfTwo ? 1 : 2; //256 : 264; + break; + case AT45DB161D: + case AT45DB321D: + cMode = powerOfTwo ? 3 : 4; //512 : 528; + break; + case AT45DB642D: + cMode = powerOfTwo ? 5 : 6; //1024 : 1056; + break; + default: + cMode = powerOfTwo ? 1 : 2; //256 : 264; + ; + } + return cMode; + +} + +void SetPageSize(CHIP_INFO* mem, int USBIndex) +{ + unsigned char writeMode; + writeMode = getWriteMode(USBIndex); + mcode_Program=writeMode; + size_t pageSize[7] = {0, 256, 264, 512, 528, 1024, 1056}; + size_t pageSizeMask[7] = {0, (1<<8)-1, (1<<9)-1, (1<<9)-1, (1<<10)-1, (1<<10)-1, (1<<11)-1}; + mem->PageSizeInByte=pageSize[writeMode]; + + if(! (writeMode & 0x1) ) // for AT45DB:0x1F2200 - 0x1F2800 + mem->ChipSizeInByte=Chip_Info.ChipSizeInByte / 256 * 8+Chip_Info.ChipSizeInByte; + else + mem->ChipSizeInByte=Chip_Info.ChipSizeInByte ; + + AT45ChipSize=mem->ChipSizeInByte; + AT45PageSize=mem->PageSizeInByte; +} + +size_t GetChipSize(void) +{ + return AT45ChipSize; +} + +size_t GetPageSize(void) +{ + return AT45PageSize; +} + + +bool AT45xxx_protectBlock(int bProtect,int Index) +{ + CNTRPIPE_RQ rq ; + unsigned char vInstruction[4]; //size 1 + + rq.Function = URB_FUNCTION_VENDOR_ENDPOINT ; + rq.Direction = VENDOR_DIRECTION_OUT ; + rq.Request = TRANSCEIVE ; + if(Is_NewUSBCommand(Index)) + { + rq.Value = RESULT_IN; + rq.Index = RFU; + } + else + { + rq.Value = RFU ; + rq.Index = RESULT_IN ; + } + rq.Length = (unsigned long) 4 ; + // protect block ,set BP1 BP0 to 1 + if(bProtect) + { + vInstruction[0]=0x3D; + vInstruction[1]=0x2A; + vInstruction[2]=0x7F; + vInstruction[3]=0xA9; + } + else + { + vInstruction[0]=0x3D; + vInstruction[1]=0x2A; + vInstruction[2]=0x7F; + vInstruction[3]=0x9A; + } + + if(OutCtrlRequest(&rq, vInstruction, 4, Index) == SerialFlash_FALSE) + return false ; + return true; +} + +bool AT45rangeProgram(struct CAddressRange* AddrRange, unsigned char *vData, unsigned char modeWrite, unsigned char WriteCom, int Index) +{ + CHIP_INFO mem_id; + + SetPageSize(&mem_id,Index); + modeWrite=getWriteMode(Index); + size_t packageNum = (AddrRange->end - AddrRange->start + mem_id.PageSizeInByte- 1) / mem_id.PageSizeInByte; + size_t pageSize[2] = { 264, 256}; + unsigned char idx = modeWrite & 0x1; + size_t itrCnt = packageNum * mem_id.PageSizeInByte / pageSize[idx]; + unsigned char* itr_begin; + size_t i; +// AT45xxx_protectBlock(false,Index); + + FlashCommand_SendCommand_SetupPacketForAT45DBBulkWrite(AddrRange, modeWrite,WriteCom,Index); + + itr_begin = vData; + + for( i = 0; i < itrCnt; ++ i) + { + bool b = BulkPipeWrite(itr_begin + (i * pageSize[idx]), pageSize[idx], USB_TIMEOUT,Index); + if((!b) || m_isCanceled) + { + return false ; + } + } +// Sleep(10) ; + return true ; + +} + +int AT45rangSectorErase(size_t sectionSize, struct CAddressRange AddrRange,int USBIndex) +{ + // send request + CNTRPIPE_RQ rq ; + unsigned char vInstruction[5]={0x7C,0x50,0x50,0x50,0x50} ; + + // instrcution format + rq.Function = URB_FUNCTION_VENDOR_ENDPOINT ; + rq.Direction = VENDOR_DIRECTION_OUT ; + rq.Request = TRANSCEIVE ; + if(Is_NewUSBCommand(USBIndex)) + { + rq.Value = RESULT_IN; + rq.Index = RFU; + } + else + { + rq.Value = RFU ; + rq.Index = RESULT_IN ; + } + rq.Length = 4 ; + + size_t sectorNum = (AddrRange.end - AddrRange.start + sectionSize - 1) / sectionSize ; + size_t i; + + for( i = 0; i < sectorNum; ++ i) + { + size_t addr = (AddrRange.start + i * sectionSize) ; + vInstruction[1] = (unsigned char)((addr >> 16) & 0xff) ; //MSB + vInstruction[2] = (unsigned char)((addr >> 8) & 0xff) ; //M + vInstruction[3] = (unsigned char)(addr & 0xff) ; //LSB + + int b = OutCtrlRequest(&rq, vInstruction,4,USBIndex); + if((b==SerialFlash_FALSE)|| m_isCanceled) return false ; + + if(AT45WaitForWIP(USBIndex)==false) return false; + } + + return true ; +} + +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; + } + mem_id.SectorSizeInByte=Chip_Info.SectorSizeInByte; + + struct CAddressRange range; + + for(i=0; i 0)) ; +} + + +/** + * \brief + * wait Write In Process with a timeout. + * + * Unless the memory is malfunctioning, it should return + * before the timer counts down to 0 from 0xFFFFFFFF. + * + * \remarks + * SR bitmap: + * 7 6 5 4 3 2 1 0 + * SRWD 0 0 BP2 BP1 BP0 WEL WIP + * + */ +bool SerialFlash_waitForWIP(int Index) +{ + unsigned char cSR ; + size_t i = Chip_Info.Timeout*100; + if(i==0) + i=MAX_TRIALS; + // wait until WIP = 0 + do{ + SerialFlash_doRDSR(&cSR,Index) ; + Sleep(5); + }while((cSR & 0x01) && (i-- > 0)) ; + if(i<=0) + return false; + return true; +} + + +int SerialFlash_doWREN(int Index) +{ + unsigned char v=mcode_WREN;; + return FlashCommand_SendCommand_OutOnlyInstruction(&v, 1,Index); + +} + + +int SerialFlash_doWRDI(int Index) +{ + unsigned char v=mcode_WRDI; + return FlashCommand_SendCommand_OutOnlyInstruction(&v, 1,Index); + +} + +bool SST25xFxx_protectBlock(int bProtect,int Index) +{ + bool result = false ; + unsigned char tmpSRVal; + unsigned char dstSRVal ; + + SerialFlash_waitForWIP(Index); + // un-protect block ,set BP1 BP0 to 0 + dstSRVal = 0x00 ; + // protect block ,set BP1 BP0 to 1 + if(bProtect){ + dstSRVal |= 0x8C ; // 8C : 1000 1100 + } + + + unsigned char vInstruction[2] ; + vInstruction[0] = 0x50 ; //Write enable + FlashCommand_SendCommand_OutOnlyInstruction(vInstruction,1,Index); + + int numOfRetry = 1000 ; + vInstruction[0] = 0x01 ; //Write register + vInstruction[1] = dstSRVal; + FlashCommand_SendCommand_OutOnlyInstruction(vInstruction,2,Index); + + result = SerialFlash_doRDSR(&tmpSRVal,Index) ; + while( (tmpSRVal & 0x01) && numOfRetry > 0) // WIP = TRUE; + { + // read SR + result = SerialFlash_doRDSR(&tmpSRVal,Index) ; + + if(! result) return false; + + numOfRetry -- ; + + }; + + return ((tmpSRVal ^ dstSRVal)& 0x0C ) ? false:true; +} + +bool SST25xFxxA_protectBlock(int bProtect,int Index) +{ + bool result = false ; + unsigned char tmpSRVal; + unsigned char dstSRVal ; + + // un-protect block ,set BP1 BP0 to 0 + dstSRVal = 0x00 ; + // protect block ,set BP1 BP0 to 1 + if(bProtect){ + dstSRVal |= 0x0 ; // 8C : 1000 1100 + } + + int numOfRetry = 1000 ; + result = SerialFlash_doWRSR(dstSRVal,Index) ; + result = SerialFlash_doRDSR(&tmpSRVal,Index) ; + while( (tmpSRVal & 0x01) && numOfRetry > 0) // WIP = TRUE; + { + // read SR + result = SerialFlash_doRDSR(&tmpSRVal,Index) ; + + if(! result) return false; + + numOfRetry -- ; + + }; + + return ((tmpSRVal ^ dstSRVal)& 0x0C ) ? false:true; +} + +bool AT25FSxxx_protectBlock(int bProtect,int Index) +{ + bool result = false ; + unsigned char tmpSRVal; + unsigned char dstSRVal ; + + // un-protect block ,set BP1 BP0 to 0 + dstSRVal = 0x00 ; + // protect block ,set BP1 BP0 to 1 + if(bProtect){ + dstSRVal |= 0xFF ; // 8C : 1000 1100 + } + + int numOfRetry = 1000 ; + result = SerialFlash_doWRSR(dstSRVal,Index) ; + result = SerialFlash_doRDSR(&tmpSRVal,Index) ; + while( (tmpSRVal & 0x01) && numOfRetry > 0) // WIP = TRUE; + { + // read SR + result = SerialFlash_doRDSR(&tmpSRVal,Index) ; + + if(! result) return false; + + numOfRetry -- ; + + }; + + return ((tmpSRVal ^ dstSRVal)& 0x0C ) ? false:true; +} + +bool AT26Fxxx_protectBlock(int bProtect,int Index) +{ + const unsigned int AT26DF041 = 0x1F4400; + const unsigned int AT26DF004 = 0x1F0400; + const unsigned int AT26DF081A = 0x1F4501; + enum + { + PROTECTSECTOR = 0x36, // Write Enable + UNPROTECTSECTOR = 0x39, // Write Disable + READPROTECTIONREGISTER = 0x3C, // Write Disable + }; + if(AT26DF041 == Chip_Info.UniqueID) return true; // feature is not supported on this chip + + bool result = false ; + + int numOfRetry = 1000 ; + + result = SerialFlash_doWRSR(0,Index) ; + + unsigned char tmpSRVal; + do + { + result = SerialFlash_doRDSR(&tmpSRVal,Index) ; + numOfRetry -- ; + + }while( (tmpSRVal & 0x01) && numOfRetry > 0 && result); + + + if (tmpSRVal & 0x80 ) return false; ///< enable SPRL + + + // send request + CNTRPIPE_RQ rq ; + unsigned char vInstruction[4] ={0}; + + vInstruction[0] = bProtect ? PROTECTSECTOR : UNPROTECTSECTOR ; + + size_t iUniformSectorSize = 0x10000; // always regarded as 64K + size_t cnt = Chip_Info.ChipSizeInByte / iUniformSectorSize; + size_t i; + for( i = 0; i < cnt; ++i) + { + SerialFlash_doWREN(Index); + + vInstruction[1] = (unsigned char)i; + + rq.Function = URB_FUNCTION_VENDOR_ENDPOINT ; + rq.Direction = VENDOR_DIRECTION_OUT ; + rq.Request = TRANSCEIVE ; + if(Is_NewUSBCommand(Index)) + { + rq.Value = RESULT_IN; + rq.Index = RFU; + } + else + { + rq.Value = RFU ; + rq.Index = RESULT_IN ; + } + rq.Length = 4; + + if(OutCtrlRequest(&rq, vInstruction,4,Index)==SerialFlash_FALSE) + return false ; + } + + if(AT26DF081A == Chip_Info.UniqueID || AT26DF004 == Chip_Info.UniqueID) // 8K each for the last 64K + { + vInstruction[1] = (unsigned char)(cnt - 1); + for( i = 1; i < 8; ++i) + { + SerialFlash_doWREN(Index); + + vInstruction[2] = (unsigned char)(i<<5); + + rq.Function = URB_FUNCTION_VENDOR_ENDPOINT ; + rq.Direction = VENDOR_DIRECTION_OUT ; + rq.Request = TRANSCEIVE ; + if(Is_NewUSBCommand(Index)) + { + rq.Value = RESULT_IN; + rq.Index = RFU; + } + else + { + rq.Value = RFU ; + rq.Index = RESULT_IN ; + } + rq.Length = 4; + + if(OutCtrlRequest(&rq, vInstruction,4,Index) == SerialFlash_FALSE) + return false ; + } + } + + return true; +} + +bool CMX25LxxxdoRDSCUR(unsigned char* cSR,int Index) +{ + // read status + // send request + CNTRPIPE_RQ rq ; + unsigned char vInstruction=RDSCUR ; //size 1 + + rq.Function = URB_FUNCTION_VENDOR_ENDPOINT ; + rq.Direction = VENDOR_DIRECTION_OUT ; + rq.Request = TRANSCEIVE ; + if(Is_NewUSBCommand(Index)) + { + rq.Value = RESULT_IN; + rq.Index = RFU; + } + else + { + rq.Value = RFU ; + rq.Index = RESULT_IN ; + } + rq.Length = 1; + + if(OutCtrlRequest(&rq, &vInstruction,1,Index)==SerialFlash_FALSE) + return SerialFlash_FALSE ; + + // second control packet : fetch data + unsigned char vBuffer ; //just read one bytes , in fact more bytes are also available + rq.Function = URB_FUNCTION_VENDOR_ENDPOINT ; + rq.Direction = VENDOR_DIRECTION_IN ; + rq.Request = TRANSCEIVE ; + if(Is_NewUSBCommand(Index)) + { + rq.Value = 1; + rq.Index = RFU; + } + else + { + rq.Value = CTRL_TIMEOUT; + rq.Index = NO_REGISTER; + } + rq.Length = 1; + + if(InCtrlRequest(&rq, &vBuffer,1,Index)==SerialFlash_FALSE) + return SerialFlash_FALSE ; + + *cSR = vBuffer; + + return SerialFlash_TRUE; +} + + +bool CS25FLxxx_LargedoUnlockDYB(unsigned int cSR, int Index) +{ + // wait until WIP = 0 + if(SerialFlash_waitForWIP(Index)==false) return false; + + unsigned char vInstruction[15] ; + unsigned char dummy; + int i; + unsigned int topend,bottomstart,end; + + if(strstr(Chip_Info.Class,SUPPORT_SPANSION_S25FLxx_Large) != NULL)//256 + { + topend=0x20000; + bottomstart=0x1fe0000; + end=0x2000000; + } + else + { + topend=0x20000; + bottomstart=0xfe0000; + end=0x1000000; + } + + for( i=0;i>24); + vInstruction[2]=(unsigned char)(i>>16); + vInstruction[3]=(unsigned char)(i>>8); + vInstruction[4]=(unsigned char)(i); + vInstruction[5]=0xff; + FlashCommand_SendCommand_OutOnlyInstruction(vInstruction,6,Index); + SerialFlash_waitForWIP(Index); + } + + for( i=topend;i>24); + vInstruction[2]=(unsigned char)(i>>16); + vInstruction[3]=(unsigned char)(i>>8); + vInstruction[4]=(unsigned char)(i); + vInstruction[5]=0xff; + FlashCommand_SendCommand_OutOnlyInstruction(vInstruction,6,Index); + SerialFlash_waitForWIP(Index); + } + + for(i=bottomstart;i>24); + vInstruction[2]=(unsigned char)(i>>16); + vInstruction[3]=(unsigned char)(i>>8); + vInstruction[4]=(unsigned char)(i); + vInstruction[5]=0xff; + FlashCommand_SendCommand_OutOnlyInstruction(vInstruction,6,Index); + SerialFlash_waitForWIP(Index); + } + return true; +} + +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) + return SST25xFxx_protectBlock( bProtect, Index); + else if(strstr(Chip_Info.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) + return AT25FSxxx_protectBlock( bProtect, Index); + else if(strstr(Chip_Info.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) + { + unsigned char tmpSRVal; + bool result; + result=CMX25LxxxdoRDSCUR(&tmpSRVal,Index); + if(result==true && (tmpSRVal&0x80) && Chip_Info.MXIC_WPmode==true) + { + if(bProtect != false) return true; + SerialFlash_doWREN(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) + { + CS25FLxxx_LargedoUnlockDYB(0, Index); + } + } + else if(strstr(Chip_Info.Class,SUPPORT_SST_26xFxxC) != NULL) + { + unsigned char v=0x98; + SerialFlash_waitForWEL(Index) ; + FlashCommand_SendCommand_OutOnlyInstruction(&v,1,Index); + } + if(SerialFlash_is_protectbits_set(Index)==bProtect) return 1; + + bool result = false ; + unsigned char tmpSRVal; + unsigned char dstSRVal ; + //int numOfRetry = 3 ; + // un-protect block ,set BP2 BP1 BP2 to 0 + dstSRVal = 0x00 ; + // protect block ,set BP2 BP1 BP2 to 1 + if(bProtect){ + dstSRVal += 0x9C ; // 9C : 9001 1100 + } + + int numOfRetry = 1000 ; + result = SerialFlash_doWRSR(dstSRVal,Index) ; + result = SerialFlash_doRDSR(&tmpSRVal,Index) ; + while( (tmpSRVal & 0x01) && numOfRetry > 0) // WIP = TRUE; + { + // read SR + result = SerialFlash_doRDSR(tmpSRVal,Index) ; + + if(! result) return false; + + numOfRetry -- ; + + }; + + return ((tmpSRVal ^ dstSRVal)& 0x0C ) ? 0:1; +} + + +int SerialFlash_EnableQuadIO(int bEnable,int boRW,int Index) +{ + m_boEnWriteQuadIO = (bEnable & boRW); //Simon: ported done??? + m_boEnReadQuadIO = (bEnable & boRW); //Simon: ported done??? + return SerialFlash_TRUE; +} + +bool CEN25QHxx_LargeEnable4ByteAddrMode(bool Enable4Byte,int Index) +{ +// SerialFlash_doWREN(Index); + if(Enable4Byte) + { + unsigned char v= EN4B; + if( FlashCommand_TransceiveOut(&v,1,false,Index)==SerialFlash_FALSE) + return false; + } + else + { + unsigned char v= EXIT4B; + if(FlashCommand_TransceiveOut(&v,1,false,Index)==SerialFlash_FALSE) + return false; + } +} + +bool CN25Qxxx_LargeRDFSR(unsigned char *cSR, int Index) +{ + // send request + CNTRPIPE_RQ rq ; + unsigned char vInstruction=0x70 ; //size 1 + + rq.Function = URB_FUNCTION_VENDOR_ENDPOINT ; + rq.Direction = VENDOR_DIRECTION_OUT ; + rq.Request = TRANSCEIVE ; + if(Is_NewUSBCommand(Index)) + { + rq.Value = RESULT_IN; + rq.Index = RFU; + } + else + { + rq.Value = RFU ; + rq.Index = RESULT_IN ; + } + rq.Length = 1; + + if(OutCtrlRequest(&rq, &vInstruction,1,Index)==SerialFlash_FALSE) + return SerialFlash_FALSE ; + + // second control packet : fetch data + unsigned char vBuffer; //just read one bytes , in fact more bytes are also available + rq.Function = URB_FUNCTION_VENDOR_ENDPOINT ; + rq.Direction = VENDOR_DIRECTION_IN ; + rq.Request = TRANSCEIVE ; + if(Is_NewUSBCommand(Index)) + { + rq.Value = RESULT_IN; + rq.Index = RFU; + } + else + { + rq.Value = CTRL_TIMEOUT; + rq.Index = NO_REGISTER; + } + rq.Length = 1; + + if(OutCtrlRequest(&rq, &vInstruction,1,Index)==SerialFlash_FALSE) + return SerialFlash_FALSE ; + *cSR = vBuffer; + + return true ; +} + +bool CN25Qxxx_LargeEnable4ByteAddrMode(bool Enable4Byte,int Index) +{ +#if 0 + if(Enable4Byte) + { + WORD cSR; + RDNVCR(cSR, Index); + cSR &= 0xFFFE; + WRNVCR(cSR, Index); + } + return true; +#else + if(Enable4Byte) + { + unsigned char v= EN4B; + int numOfRetry = 5 ; + unsigned char re; + do{ + SerialFlash_waitForWEL(Index); + FlashCommand_TransceiveOut(&v,1,false,Index); + Sleep(100); + CN25Qxxx_LargeRDFSR(&re,Index); + }while((re & 0x01)==0 && numOfRetry-- > 0); + return true; + } + else + { + unsigned char re; +// CN25Qxxx_LargeRDFSR(&re,Index); + unsigned char v= EXIT4B; + int numOfRetry = 5 ; + + do{ + SerialFlash_waitForWEL(Index); + FlashCommand_TransceiveOut(&v,1,false,Index); + Sleep(100); + CN25Qxxx_LargeRDFSR(&re,Index); + }while((re & 0x01)==1 && numOfRetry-- > 0); + return true; + } +#endif +} + + +//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) + return CEN25QHxx_LargeEnable4ByteAddrMode(bEnable,Index); + + if(strstr(Chip_Info.Class,SUPPORT_NUMONYX_N25Qxxx_Large) != NULL) + return CN25Qxxx_LargeEnable4ByteAddrMode(bEnable, Index); + + return SerialFlash_TRUE; +} + + +/** + * \brief + * read data, check if 0xFF + * + * \returns + * true, if blank; false otherwise + */ +int SerialFlash_rangeBlankCheck(struct CAddressRange *Range,int Index) +{ + unsigned char *vBuffer; + unsigned int i; + Range->length = Range->end - Range->start; + + if (Range->length <= 0) + return SerialFlash_FALSE; + vBuffer = malloc(Range->length); + if (vBuffer != 0) + { + if(SerialFlash_rangeRead(Range, vBuffer,Index) == SerialFlash_FALSE) + { + free(vBuffer); + return false ; + } + for(i=0; ilength; i++) + { + if(vBuffer[i] != 0xFF) + { +// printf("not blank at %X(%d)=%X\r\n",i,i,vBuffer[i]); + free(vBuffer); + return false; + } + } + free(vBuffer); + return true ; + } + else + { + free(vBuffer); + return SerialFlash_FALSE; + } +} + + +/** + * \brief + * Write brief comment for Download here. + * + * it first check the data size and then delegates the actual operation to BulkPipeWrite() + * + * \param AddrRange + * the flash memory starting(inclusive) and end address(exlusive) + * + * \param vData + * data to be written into the flash memory. + * + * \returns + * true, if successfull + * false, if data size larger than memory size, or operation fails + */ +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) + return AT45rangeProgram(AddrRange, vData,mcode_Program, mcode_ProgramCode_4Adr, Index); + else if(strstr(Chip_Info.Class,SUPPORT_SPANSION_S25FLxx_Large)!=NULL) + { + if(g_bIsSF600==true) + return SerialFlash_bulkPipeProgram(AddrRange, vData, PP_4ADR_256BYTE,mcode_ProgramCode_4Adr,Index); + else + return SerialFlash_bulkPipeProgram(AddrRange, vData, PP_4ADDR_256BYTE_12,mcode_ProgramCode_4Adr,Index); + } + else + return SerialFlash_bulkPipeProgram(AddrRange, vData, mcode_Program, mcode_ProgramCode_4Adr,Index); +} + +int SerialFlash_rangeRead(struct CAddressRange *AddrRange, unsigned char *vData,int Index) +{ + if(strstr(Chip_Info.Class,SUPPORT_SPANSION_S25FLxx_Large)!=NULL) + { + if(g_bIsSF600==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 + return SerialFlash_bulkPipeRead(AddrRange, vData, (unsigned char) mcode_Read, (unsigned char) mcode_ReadCode, Index); +}; + + +/** + * \brief + * poll the status register after Erase operation. + * + * \returns + * To be defined + * + * (not fully implemented or used now) + * + * \remarks + * A polling command can be used to poll the status register after Erase operation + * + */ +int SerialFlash_DoPolling(int Index) +{ + CNTRPIPE_RQ rq ; + unsigned char vDataPack[4]; + + rq.Function = URB_FUNCTION_VENDOR_ENDPOINT ; + rq.Direction = VENDOR_DIRECTION_IN ; + rq.Request = POLLING ; + rq.Value = (CTRL_TIMEOUT >> 16) & 0xffff ; + rq.Index = CTRL_TIMEOUT & 0xffff ; + rq.Length = (unsigned long)(4) ; + + if(OutCtrlRequest(&rq, vDataPack, 4,Index) == SerialFlash_FALSE) + return SerialFlash_FALSE ; + + return SerialFlash_TRUE ; + +} + + +/** + * \brief + * retrieves object wellness flag + * + * before calling any other method, be sure to call is_good() to check the wellness + * which indicates whether the instance is constructed successfully or not + * + * \returns + * true only if all objects of chip info, chip itself, USB are correctly constructed + * false otherwise + * + */ +int SerialFlash_is_good() +{ +//Simon return ( m_info.is_good() && m_usb.is_open() ) ; + return SerialFlash_TRUE ; +} + +int SerialFlash_batchErase(size_t* vAddrs,size_t AddrSize,int Index) +{ +// if(strstr(Chip_Info.Class,SUPPORT_ATMEL_45DBxxxB) != NULL || strstr(Chip_Info.Class,SUPPORT_ATMEL_45DBxxxD) != NULL) +// return AT45batchErase(vAddrs, AddrSize,Index); + + if(0 == mcode_SegmentErase) return 1; // chipErase code not initialised or not supported, please check chip class ctor. + + if(SerialFlash_protectBlock(false,Index) == SerialFlash_FALSE) + return false ; + SerialFlash_Enable4ByteAddrMode(true, Index); + + // send request + CNTRPIPE_RQ rq ; + size_t i; + unsigned char vInstruction[5];//(5, mcode_SegmentErase) ; + vInstruction[0]=mcode_SegmentErase; + +// printf("mcode_SegmentErase=%x\n",mcode_SegmentErase); + // instrcution format + rq.Function = URB_FUNCTION_VENDOR_ENDPOINT ; + rq.Direction = VENDOR_DIRECTION_OUT ; + rq.Request = TRANSCEIVE ; + if(Is_NewUSBCommand(Index)) + { + rq.Value = NO_RESULT_IN; + rq.Index = RFU; + } + else + { + rq.Value = RFU ; + rq.Index = NO_RESULT_IN ; + } + rq.Length = 5; + + for(i=0; i0x1000000) + { + // MSB~ LSB (31...0) + vInstruction[1]=(unsigned char)((vAddrs[i] >> 24) & 0xff) ; //MSB + vInstruction[2] = (unsigned char)((vAddrs[i] >> 16) & 0xff) ; //M + vInstruction[3] = (unsigned char)((vAddrs[i] >> 8) & 0xff) ; //M + vInstruction[4] = (unsigned char)(vAddrs[i] & 0xff) ; //LSB + rq.Length = 5; + } + else + { + // MSB~ LSB (23...0) + vInstruction[1] = (unsigned char)((vAddrs[i] >> 16) & 0xff) ; //MSB + vInstruction[2] = (unsigned char)((vAddrs[i] >> 8) & 0xff) ; //M + vInstruction[3] = (unsigned char)(vAddrs[i] & 0xff) ; //LSB + rq.Length = 4; + } + OutCtrlRequest(&rq, vInstruction,rq.Length,Index); + + SerialFlash_waitForWIP(Index); + } + SerialFlash_Enable4ByteAddrMode(false, Index); + return true ; +} + +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) + return AT45rangSectorErase(sectionSize, *AddrRange,Index); + + if(SerialFlash_protectBlock(false,Index) == SerialFlash_FALSE) + return SerialFlash_FALSE ; + SerialFlash_Enable4ByteAddrMode(true, Index); + + // send request + CNTRPIPE_RQ rq ; + unsigned char vInstruction[5]; + vInstruction[0] = cmd; + + // instrcution format + rq.Function = URB_FUNCTION_VENDOR_ENDPOINT ; + rq.Direction = VENDOR_DIRECTION_OUT ; + rq.Request = TRANSCEIVE ; + if(Is_NewUSBCommand(Index)) + { + rq.Value = RESULT_IN; + rq.Index = RFU; + } + else + { + rq.Value = RFU ; + rq.Index = RESULT_IN ; + } + rq.Length = (unsigned long)(1) ; + + size_t sectorNum = (AddrRange->end - AddrRange->start + sectionSize - 1) / sectionSize ; + size_t i; + for(i = 0; i < sectorNum; ++ i) + { + SerialFlash_waitForWEL(Index) ; + + // MSB~ LSB (23...0) + size_t addr = (AddrRange->start + i * sectionSize) ; + + if(Chip_Info.ChipSizeInByte>0x1000000) + { + // MSB~ LSB (31...0) + vInstruction[1] = (unsigned char)((addr >> 24) & 0xff) ; //MSB + vInstruction[2] = (unsigned char)((addr >> 16) & 0xff) ; //M + vInstruction[3] = (unsigned char)((addr >> 8) & 0xff) ; //M + vInstruction[4] = (unsigned char)(addr & 0xff) ; //LSB + rq.Length = (unsigned long)(5) ; + } + else + { + // MSB~ LSB (23...0) + vInstruction[1] = (unsigned char)((addr >> 16) & 0xff) ; //MSB + vInstruction[2] = (unsigned char)((addr >> 8) & 0xff) ; //M + vInstruction[3] = (unsigned char)(addr & 0xff) ; //LSB + rq.Length = (unsigned long)(4); + } + + int b = OutCtrlRequest(&rq, vInstruction, rq.Length, Index); + if((b==SerialFlash_FALSE)|| m_isCanceled) return false ; + + SerialFlash_waitForWIP(Index) ; + } + SerialFlash_Enable4ByteAddrMode(false, Index); + + return true ; +} + +/// chip erase +int SerialFlash_chipErase(int Index) +{ + 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( SerialFlash_protectBlock(false,Index) == SerialFlash_FALSE) return false ; + SerialFlash_waitForWEL(Index) ; + unsigned char v = mcode_ChipErase; + FlashCommand_SendCommand_OutOnlyInstruction(&v,1,Index); + SerialFlash_waitForWIP(Index) ; + //if( SerialFlash_protectBlock(m_bProtectAfterWritenErase,Index) == SerialFlash_FALSE) return false ; + return true ; +} + + +int SerialFlash_bulkPipeProgram(struct CAddressRange *AddrRange, unsigned char *vData, unsigned char modeWrite, unsigned char WriteCom, int Index) +{ + size_t i,j,divider; + unsigned char write_temp[2]; + unsigned char *itr_begin; + if(SerialFlash_protectBlock(false,Index) == SerialFlash_FALSE) + return false ; + + if(modeWrite!= PP_SB_FPGA) + SerialFlash_waitForWEL(Index) ; + + SerialFlash_Enable4ByteAddrMode(true, Index); + if(SerialFlash_EnableQuadIO(true,m_boEnWriteQuadIO,Index) == SerialFlash_FALSE) + return false; + +// printf("WriteMode=%d, WriteCom=%X\r\n", modeWrite,WriteCom); + itr_begin = vData; + switch(modeWrite) + { + //transfer how many data each time + case MODE_NUMONYX_PCM: + case PP_32BYTE: + divider=9; + break; + case PP_128BYTE: + divider=7; + break; + default: + divider=8; + break; + } + + if((AddrRange->end/0x1000000)>(AddrRange->start/0x1000000))//(AddrRange.end>0x1000000 && AddrRange.start<0x1000000) ||(AddrRange.end>0x2000000 && AddrRange.start<0x2000000) || + { + struct CAddressRange down_range; + struct CAddressRange range_temp; + range_temp.start= AddrRange->start&0xFF000000; + range_temp.end= AddrRange->end + ((AddrRange->end % 0x1000000)? (0x1000000-(AddrRange->end % 0x1000000)):0); + + down_range.start = AddrRange->start; + down_range.end = AddrRange->end; + size_t packageNum; + size_t loop=(range_temp.end-range_temp.start)/0x1000000; +// printf("loop=%d \r\n",loop); +// printf("range_temp.end=%x,range_temp.start=%x\n\r",range_temp.end,range_temp.start); + + for(j=0; jend; + else + down_range.end=(AddrRange->start&0xFF000000)+(0x1000000*(j+1)); + + if(j==0) + down_range.start=AddrRange->start; + else + down_range.start=(AddrRange->start&0xFF000000)+(0x1000000*j); + + down_range.length=down_range.end-down_range.start; + packageNum = down_range.length >> divider ; +// printf("packageNum=%d \r\n",packageNum); + FlashCommand_SendCommand_SetupPacketForBulkWrite(&down_range, modeWrite,WriteCom,Index); + for( i = 0; i < packageNum; ++ i) + { + BulkPipeWrite((unsigned char *)(itr_begin + (i << divider)), 1<end - AddrRange->start) >> divider ; + FlashCommand_SendCommand_SetupPacketForBulkWrite(AddrRange, modeWrite,WriteCom,Index); + for(i = 0; i < packageNum; ++ i) + { + BulkPipeWrite((unsigned char *)((itr_begin + (i << divider))), 1<length = AddrRange->end - AddrRange->start; + if (AddrRange->length <= 0) { + return false; + } +// printf("modeRead=%d\r\n",modeRead); + +// printf("AddrRange->end=%x, AddrRange->start=%x\r\n",AddrRange->end,AddrRange->start); + if((AddrRange->end/0x1000000) > (AddrRange->start/0x1000000))//(AddrRange.end>0x1000000 && AddrRange.start<0x1000000) + { + struct CAddressRange read_range; + struct CAddressRange range_temp; + range_temp.start= AddrRange->start&0xFF000000; + range_temp.end= AddrRange->end + ((AddrRange->end % 0x1000000)? (0x1000000-(AddrRange->end % 0x1000000)):0); + + read_range.start=AddrRange->start; + read_range.end=AddrRange->end; + loop=(range_temp.end-range_temp.start)/0x1000000; + + for(j=0; jend; + else + read_range.end=(AddrRange->start&0xFF000000)+(0x1000000*(j+1)); + + if(j==0) + read_range.start=AddrRange->start; + else + read_range.start=((AddrRange->start&0xFF000000)+(0x1000000*j)); + + read_range.length=read_range.end-read_range.start; + + pageNum = read_range.length >> 9 ; + FlashCommand_SendCommand_SetupPacketForBulkRead(&read_range, modeRead,ReadCom,Index); + for(i = 0; i < pageNum; ++ i) + { + ret = BulkPipeRead(vData + (BufferLocation+i)*512, USB_TIMEOUT,Index); + if((ret!=512) || m_isCanceled) return 0 ; + //memcpy(vData + (BufferLocation+i)*512, v, 512); + } + BufferLocation += pageNum; + } + } + else + { + pageNum = AddrRange->length >> 9 ; + FlashCommand_SendCommand_SetupPacketForBulkRead(AddrRange, modeRead,ReadCom,Index); + for(i = 0; i < pageNum; ++ i) + { + ret = BulkPipeRead(vData + i*ret, USB_TIMEOUT,Index); + if((ret != 512) || m_isCanceled) + { + return false ; + } + //memcpy(vData + i*ret, v, ret); + } + } + if(SerialFlash_EnableQuadIO(false,m_boEnReadQuadIO,Index) == SerialFlash_FALSE) + return false; + SerialFlash_Enable4ByteAddrMode(false, Index); + return true ; +} + + +void SerialFlash_SetCancelOperationFlag() +{ + m_isCanceled = SerialFlash_TRUE; +} + +void SerialFlash_ClearCancelOperationFlag() +{ + m_isCanceled = SerialFlash_FALSE; +} + +int SerialFlash_readSR(unsigned char *cSR,int Index) +{ + return SerialFlash_doRDSR(cSR,Index); +} + +int SerialFlash_writeSR(unsigned char cSR,int Index) +{ + SerialFlash_doWREN(Index); + return SerialFlash_doWRSR(cSR,Index); +} + +int SerialFlash_is_protectbits_set(int Index) +{ + unsigned char sr; + SerialFlash_doRDSR(&sr,Index) ; + + return ((0 != (sr & 0x9C) )? 1: 0); +} + diff --git a/SerialFlash.h b/SerialFlash.h new file mode 100644 index 0000000..190ad68 --- /dev/null +++ b/SerialFlash.h @@ -0,0 +1,93 @@ +#pragma once + +#ifndef SERIALFLASHS + +#define SERIALFLASHS + +#define SerialFlash_FALSE -1 +#define SerialFlash_TRUE 1 + +//#define size_t unsigned int + + enum //list of all chip-specific instruction, for ST serial flash + { + WREN = 0x06, // Write Enable + WRDI = 0x04, // Write Disable + RDIDJ = 0x9F, //RDIDJ // Read Jedec ID , except 80 + RDSR = 0x05, // Read Status Register + WRSR = 0x01, // Write Status Register + READ = 0x03, // Byte Read + FREAD = 0x0B, // Fast Read + PP = 0x02, // Page Program + SE = 0xD8, // Sector Erase + CHIP_ERASE = 0xC7, //CHIP_ERASE // Bulk (or Chip) Erase + DP = 0xB9, // Deep Power Down + RDP = 0xAB, //RES // Release Deep Power Down + RES = 0xAB, //RES // RDP and read signature + RDSCUR = 0x2B, + GBULK = 0x98, + EN4B = 0xB7, + EXIT4B = 0xE9, + }; + + +int SerialFlash_doWRSR(unsigned char cSR,int Index); + +int SerialFlash_doRDSR(unsigned char *cSR,int Index); + +void SerialFlash_waitForWEL(int Index); + +bool SerialFlash_waitForWIP(int Index); + +int SerialFlash_doWREN(int Index); + +int SerialFlash_doWRDI(int Index); + +int SerialFlash_protectBlock(int bProtect,int Index); + +int SerialFlash_EnableQuadIO(int bEnable,int boRW,int Index); + +int SerialFlash_Enable4ByteAddrMode(int bEnable,int Index); + +int SerialFlash_rangeBlankCheck(struct CAddressRange *Range,int Index); + +int SerialFlash_rangeProgram(struct CAddressRange *AddrRange, unsigned char *vData,int Index); + +int SerialFlash_rangeRead(struct CAddressRange *AddrRange, unsigned char *vData,int Index); + +int SerialFlash_DoPolling(int Index); + +int SerialFlash_is_good(); + +#if 0 +int SerialFlash_batchErase(size_t *vAddrs,int Index); +#endif + +int SerialFlash_rangeErase(unsigned char cmd, size_t sectionSize, struct CAddressRange *AddrRange,int Index); + +int SerialFlash_chipErase(int Index); + +int SerialFlash_bulkPipeProgram(struct CAddressRange *AddrRange, unsigned char *vData, unsigned char modeWrite, unsigned char WriteCom, int Index); + +int SerialFlash_bulkPipeRead(struct CAddressRange *AddrRange, unsigned char *vData, unsigned char modeRead,unsigned char ReadCom,int Index); + +void SerialFlash_SetCancelOperationFlag(); + +void SerialFlash_ClearCancelOperationFlag(); + +int SerialFlash_readSR(unsigned char *cSR,int Index); + +int SerialFlash_writeSR(unsigned char cSR,int Index); + +int SerialFlash_is_protectbits_set(int Index); +bool SST25xFxxA_protectBlock(int bProtect,int Index); +bool SST25xFxx_protectBlock(int bProtect,int Index); +bool AT25FSxxx_protectBlock(int bProtect,int Index); +bool CEN25QHxx_LargeEnable4ByteAddrMode(bool Enable4Byte,int Index); +bool CN25Qxxx_LargeRDFSR(unsigned char *cSR, int Index); +bool CN25Qxxx_LargeEnable4ByteAddrMode(bool Enable4Byte,int Index); +size_t GetChipSize(void); +size_t GetPageSize(void); + + +#endif //SERIALFLASHS diff --git a/board.c b/board.c new file mode 100644 index 0000000..e077fdf --- /dev/null +++ b/board.c @@ -0,0 +1,609 @@ +#include "Macro.h" +#include "usbdriver.h" +#include "board.h" +#define SerialFlash_FALSE -1 +#define SerialFlash_TRUE 1 + +volatile bool g_bIsSF600=false; +extern char g_board_type[8]; +extern int g_firmversion; +extern unsigned int g_IO1Select; +extern unsigned int g_IO4Select; +extern Sleep(unsigned int ms); +void QueryBoard(int Index) +{ +// printf("QueryBoard\r\n"); + return; + if(!Is_usbworking()) + { + printf("Do not find SFxx programmer!!\n"); + return ; + } + + CNTRPIPE_RQ rq ; + char vBuffer[16]; + + rq.Function = URB_FUNCTION_VENDOR_ENDPOINT ; + rq.Direction = VENDOR_DIRECTION_IN ; + rq.Request = PROGINFO_REQUEST ; + rq.Value = RFU ; + rq.Index = 0x00 ; + rq.Length = (unsigned long)16; + memset(vBuffer, '\0', 16); + + if(InCtrlRequest(&rq, vBuffer,16,Index) == SerialFlash_FALSE) + { + printf("send fail\r\n"); + return ; + } + + memcpy(g_board_type,&vBuffer[0],8); +// memcpy(g_firmversion,&vBuffer[10],8); +// printf("g_board_type=%s\r\n",g_board_type); +// if(strstr(g_board_type,"SF600") != NULL) +// g_bIsSF600=true; +// else +// g_bIsSF600=false; +#if 0 + m_info.fpga_version=GetFPGAVersion(Index); + vector vBuffer1(3) ; + + rq.Function = URB_FUNCTION_VENDOR_OTHER ; + rq.Direction = VENDOR_DIRECTION_IN ; + rq.Request = 0x7; + rq.Value = 0 ; + rq.Index = 0xEF00 ; + rq.Length = 3; + + + if(! m_usb.InCtrlRequest(rq, vBuffer1,Index)) + { + return ; + } + + if(m_info.board_type==L"SF600") + { + ReadOnBoardFlash(false,Index); + m_info.dwUID=(DWORD)m_vUID[0]<<16 | (DWORD)m_vUID[1]<<8 | m_vUID[2]; + } + else + m_info.dwUID=(DWORD)vBuffer1[0]<<16 | (DWORD)vBuffer1[1]<<8 | vBuffer1[2]; +#endif +} + +unsigned char GetFPGAVersion(int Index) +{ + if(strstr(g_board_type,"SF600")==NULL) return -1; + + CNTRPIPE_RQ rq ; + unsigned char vDataPack ; + + rq.Function = URB_FUNCTION_VENDOR_ENDPOINT ; + rq.Direction = VENDOR_DIRECTION_IN; + rq.Request = 0x1C ; + rq.Value = RFU ; + rq.Index = 0 ; + rq.Length = 1 ; + + if(InCtrlRequest(&rq,&vDataPack,1,Index)==SerialFlash_FALSE){ + return -1 ; + } + + return vDataPack; +} +#if 0 +const board_info& GetBoardInfo(int Index) + { + // scott + QueryBoard(Index); + + return m_info; + } +#endif +bool SetIO(unsigned char ioState, int Index) +{ + CNTRPIPE_RQ rq ; + unsigned char vDataPack ; // 1 bytes, in fact no needs + + rq.Function = URB_FUNCTION_VENDOR_ENDPOINT ; + rq.Direction = VENDOR_DIRECTION_OUT ; + rq.Request = SET_IO ; + + if(Is_NewUSBCommand(Index)) + { + rq.Value = (ioState&0x0F)|0x70 ; + rq.Index = 0; + } + else + { + rq.Value = ioState ; + rq.Index = 0x07 ; + } + rq.Length = 0 ; + + if(OutCtrlRequest(&rq,&vDataPack,0,Index)==SerialFlash_FALSE){ + return false ; + } + + return true ; +} + +bool SetTargetFlash(unsigned char StartupMode,int Index) +{ + CNTRPIPE_RQ rq ; + unsigned char vInstruction ; + + rq.Function = URB_FUNCTION_VENDOR_ENDPOINT ; + rq.Direction = VENDOR_DIRECTION_OUT ; + rq.Request = SET_TARGET_FLASH; + rq.Value = StartupMode; + rq.Index = 0 ; + rq.Length = 0 ; + + if(OutCtrlRequest(&rq,&vInstruction,0,Index)==SerialFlash_FALSE ) + { + return false ; + } + + return true; +} + +#if 0 + bool ReadUID(int Index) + { + boost::mutex::scoped_lock l(mutex); + if(! m_usb.is_open() ) + { + return false; + } + if(m_info.board_type==L"SF600") + { + ReadOnBoardFlash(false,Index); + m_info.dwUID=(DWORD)m_vUID[0]<<16 | (DWORD)m_vUID[1]<<8 | m_vUID[2]; + m_dwUID=m_info.dwUID; + m_bManuID=m_vUID[3]; + return true; + } + + CNTRPIPE_RQ rq ; + vector vBuffer(3) ; + + // read + rq.Function = URB_FUNCTION_VENDOR_OTHER ; + rq.Direction = VENDOR_DIRECTION_IN ; + rq.Request = 0x7; + rq.Value = 0 ; + rq.Index = 0xEF00 ; + rq.Length = 3; + + if(! m_usb.InCtrlRequest(rq, vBuffer,Index)) + { + return false; + } + + m_dwUID=(DWORD)vBuffer[0]<<16 | (DWORD)vBuffer[1]<<8 | vBuffer[2]; + return true; + } + + + bool WriteUID(int Index) + { + boost::mutex::scoped_lock l(mutex); + if(! m_usb.is_open() ) + { + return false; + } + if(m_info.board_type==L"SF600") + { + return true; + } + + CNTRPIPE_RQ rq ; + + // read + rq.Function = URB_FUNCTION_VENDOR_OTHER ; + rq.Direction = VENDOR_DIRECTION_IN ; + rq.Request = 0x6; + rq.Value = (BYTE)(m_dwUID>>16) ; + rq.Index = 0xEF00 ; + rq.Length = 1; + + if(! m_usb.InCtrlRequest(rq, vector(1),Index)) + { + return false; + } + + rq.Index = 0xEF01 ; + rq.Value = (BYTE)(m_dwUID>>8) ; + + if(! m_usb.InCtrlRequest(rq, vector(1),Index)) + { + return false; + } + + rq.Index = 0xEF02 ; + rq.Value = (BYTE)(m_dwUID) ; + + if(! m_usb.InCtrlRequest(rq, vector(1),Index)) + { + return false; + } + + return true; + } + + bool ReadManufacturerID(int Index) + { + if(! m_usb.is_open() ) + { + return false; + } + if(m_info.board_type==L"SF600") + { + ReadOnBoardFlash(false,Index); + m_bManuID=m_vUID[3]; + return true; + } + + CNTRPIPE_RQ rq ; + vector vBuffer(1) ; + m_bManuID=0xFF; + + // read + rq.Function = URB_FUNCTION_VENDOR_OTHER ; + rq.Direction = VENDOR_DIRECTION_IN ; + rq.Request = 0x7; + rq.Value = 0 ; + rq.Index = 0xEF03; + rq.Length = 1; + + if(! m_usb.InCtrlRequest(rq, vBuffer,Index)) + { + return false; + } + m_bManuID=vBuffer[0]; + + return true; + } + + bool WriteManufacturerID(int Index) + { + boost::mutex::scoped_lock l(mutex); + if(! m_usb.is_open() ) + { + return false; + } + if(m_info.board_type==L"SF600") + { + return true; + } + + CNTRPIPE_RQ rq ; + + // read + rq.Function = URB_FUNCTION_VENDOR_OTHER ; + rq.Direction = VENDOR_DIRECTION_IN ; + rq.Request = 0x6; + rq.Value = m_bManuID ; + rq.Index = 0xEF03 ; + rq.Length = 1; + + if(! m_usb.InCtrlRequest(rq, vector(1),Index)) + { + return false; + } + + return true; + } +#endif +bool SetLEDProgBoard(size_t Color,int Index) +{ + if(! Is_usbworking()) + { + return false; + } + + CNTRPIPE_RQ rq ; + unsigned char vBuffer[16]; + + rq.Function = URB_FUNCTION_VENDOR_ENDPOINT ; + rq.Direction = VENDOR_DIRECTION_OUT ; + rq.Request = SET_IO ; + if(Is_NewUSBCommand(Index)) + { + rq.Value = (Color&0xFFF7) | (g_IO1Select<<1)|(g_IO4Select<<3); + rq.Index=0; + } + else + { + rq.Value = 0x09 ; + rq.Index = Color>>8 ;//LED 0:ON 1:OFF Bit0:Green Bit1:Orange Bit2:Red + } + rq.Length = 0 ; + + if(OutCtrlRequest(&rq,vBuffer,0,Index)==SerialFlash_FALSE) + { + return false; + } + + return true; +} +bool SetGreenLEDOn(bool boOn,int Index) +{ + return SetLEDProgBoard(boOn?0x0609:0x0709,Index); +} + +bool SetOrangeLEDOn(bool boOn, int Index) +{ + return SetLEDProgBoard(boOn?0x0509:0x0709,Index); +} + +bool SetRedLEDOn(bool boOn, int Index) +{ + return SetLEDProgBoard(boOn?0x0309:0x0709,Index); +} + +bool SetLEDOnOff(size_t Color,int Index) +{ + switch(Color) + { + case SITE_ERROR: + return SetRedLEDOn(true,Index); + case SITE_BUSY: + return SetOrangeLEDOn(true,Index); + case SITE_OK: + return SetGreenLEDOn(true,Index); + case SITE_NORMAL: + return SetLEDProgBoard(0x0709,Index);// Turn off LED + } + return false; +} + +bool SetCS(size_t value,int Index) +{ + if(! Is_usbworking()) + { + return false; + } + + CNTRPIPE_RQ rq ; + unsigned char vBuffer ; + rq.Function = URB_FUNCTION_VENDOR_ENDPOINT ; + rq.Direction = VENDOR_DIRECTION_OUT ; + rq.Request = SET_CS; + rq.Value = value; // 12MHz + rq.Index = RFU ; + rq.Length = 0 ; + + if(OutCtrlRequest(&rq, &vBuffer,0,Index)==SerialFlash_FALSE) + { + return false; + } + + return true; +} + +bool SetIOModeToSF600(size_t value,int Index) +{ + if(! Is_usbworking()) + { + return false; + } + + CNTRPIPE_RQ rq ; + unsigned char vBuffer ; + rq.Function = URB_FUNCTION_VENDOR_ENDPOINT ; + rq.Direction = VENDOR_DIRECTION_OUT ; + rq.Request = SET_IOMODE; + rq.Value = value; + rq.Index = RFU ; + rq.Length = 0 ; + + if(OutCtrlRequest(&rq, &vBuffer,0,Index)==SerialFlash_FALSE) + { + return false; + } + + return true; +} + +bool BlinkProgBoard(bool boIsV5,int Index) +{ + if(! Is_usbworking() ) + { + return false; + } + + SetGreenLEDOn(true,0); + + Sleep(500); + + SetGreenLEDOn(false,0); + + return true; +} + +bool ReadOnBoardFlash(unsigned char* Data,bool ReadUID,int Index) +{ + CNTRPIPE_RQ rq ; + unsigned char vBuffer[16] ; + + rq.Function = URB_FUNCTION_VENDOR_ENDPOINT ; + rq.Direction = VENDOR_DIRECTION_IN ; + rq.Request = 0x05 ; + if(Is_NewUSBCommand(Index)) + { + rq.Value = ReadUID; + rq.Index = 0; + } + else + { + rq.Value = 0x00 ; + rq.Index = ReadUID; + } + rq.Length = 16 ; + + if(InCtrlRequest(&rq, vBuffer,16,Index)==SerialFlash_FALSE) + { + return false; + } + memcpy(Data,vBuffer,4); +} +#if 0 + + bool WriteSF600UID(int Index) + { + CNTRPIPE_RQ rq ; + vector vBuffer(16) ; + + // first control packet + rq.Function = URB_FUNCTION_VENDOR_ENDPOINT ; + rq.Direction = VENDOR_DIRECTION_OUT ; + rq.Request = WRITE_EEPROM ; + rq.Value = 0; + rq.Index = RFU ; + rq.Length = vBuffer.size(); + + vBuffer[0]=(BYTE)(m_dwUID>>16) ; + vBuffer[1]=(BYTE)(m_dwUID>>8) ; + vBuffer[2]=(BYTE)(m_dwUID) ; + vBuffer[3]=m_bManuID ; + + if(! m_usb.OutCtrlRequest(rq, vBuffer,Index)) + return false ; + + return true ; + } + + bool SetSF600HoldPin(bool boHigh, int Index) + { + if(! m_usb.is_open() ) + { + return false; + } + + // send request + CNTRPIPE_RQ rq ; + vector vBuffer(0) ; + rq.Function = URB_FUNCTION_VENDOR_ENDPOINT ; + rq.Direction = VENDOR_DIRECTION_OUT ; + rq.Request = SET_HOLD; + rq.Value = (boHigh? 0x0C:0x08); + rq.Index = RFU ; + rq.Length = 0 ; + + if(! m_usb.OutCtrlRequest(rq, vBuffer,Index)) + { + return false; + } + + return true; + } + + bool SF600HoldPinControlBySW(bool boEnable, int Index) + { + if(! m_usb.is_open() ) + { + return false; + } + + // send request + CNTRPIPE_RQ rq ; + vector vBuffer(0) ; + rq.Function = URB_FUNCTION_VENDOR_ENDPOINT ; + rq.Direction = VENDOR_DIRECTION_OUT ; + rq.Request = SET_HOLD; + rq.Value = (boEnable? 0x08:0x00); + rq.Index = RFU ; + rq.Length = 0 ; + + if(! m_usb.OutCtrlRequest(rq, vBuffer,Index)) + { + return false; + } + + return true; + } +#endif + +bool LeaveSF600Standalone(bool Enable,int USBIndex) +{ + if(! Is_usbworking()) + { + return false; + } + + CNTRPIPE_RQ rq ; + unsigned char vBuffer ; + rq.Function = URB_FUNCTION_VENDOR_ENDPOINT ; + rq.Direction = VENDOR_DIRECTION_OUT ; + rq.Request = SET_SA; + rq.Value = Enable; + rq.Index = RFU ; + rq.Length = 0 ; + + if(OutCtrlRequest(&rq,&vBuffer,0,USBIndex)==SerialFlash_FALSE) + { + return false; + } + + return true; +} + +bool SetSPIClockValue(unsigned short v,int Index) +{ + if(!Is_usbworking() ) + return false; + + // send request + CNTRPIPE_RQ rq ; + unsigned char vBuffer; + rq.Function = URB_FUNCTION_VENDOR_ENDPOINT ; + rq.Direction = VENDOR_DIRECTION_OUT ; + rq.Request = SET_SPICLK; + rq.Value = v ; + rq.Index = RFU ; + rq.Length = 0 ; + + if(OutCtrlRequest(&rq, &vBuffer,0,Index)==SerialFlash_FALSE) + return false; + + return true; +} + +unsigned int ReadUID(int Index) +{ + if(! Is_usbworking() ) + { + return false; + } + unsigned int dwUID=0; + + if(g_bIsSF600==true) + { + unsigned char vUID[4]; + ReadOnBoardFlash(vUID,false,Index); + dwUID=(unsigned int)vUID[0]<<16 | (unsigned int)vUID[1]<<8 | vUID[2]; + return dwUID; + } + + CNTRPIPE_RQ rq ; + unsigned char vBuffer[3] ; + + // read + rq.Function = URB_FUNCTION_VENDOR_OTHER ; + rq.Direction = VENDOR_DIRECTION_IN ; + rq.Request = 0x7; + rq.Value = 0 ; + rq.Index = 0xEF00 ; + rq.Length = 3; + + if( InCtrlRequest(&rq, vBuffer,3,Index)==SerialFlash_FALSE) + { + return false; + } + + dwUID=(unsigned int)vBuffer[0]<<16 | (unsigned int)vBuffer[1]<<8 | vBuffer[2]; + return dwUID; +} + diff --git a/board.h b/board.h new file mode 100644 index 0000000..ef647c0 --- /dev/null +++ b/board.h @@ -0,0 +1,25 @@ + +#pragma once + +#ifndef _BOARD_H +#define _BOARD_H + +void QueryBoard(int Index); +unsigned char GetFPGAVersion(int Index); +bool SetIO(unsigned char ioState, int Index); +bool SetTargetFlash(unsigned char StartupMode,int Index); +bool SetLEDProgBoard(size_t Clolor,int Index); +bool SetGreenLEDOn(bool boOn,int Index); +bool SetOrangeLEDOn(bool boOn, int Index); +bool SetRedLEDOn(bool boOn, int Index); +bool SetLEDOnOff(size_t Color,int Index); +bool SetCS(size_t value,int Index); +bool SetIOModeToSF600(size_t value,int Index); +bool BlinkProgBoard(bool boIsV5,int Index); +bool ReadOnBoardFlash(unsigned char* Data,bool ReadUID,int Index); +bool LeaveSF600Standalone(bool Enable,int USBIndex); +bool SetSPIClockValue(unsigned short v,int Index); +unsigned int ReadUID(int Index); + +#endif + diff --git a/dpcmd.c b/dpcmd.c new file mode 100644 index 0000000..4b790ac --- /dev/null +++ b/dpcmd.c @@ -0,0 +1,1326 @@ +#if 1 +#include +#include +#include +#include "Macro.h" + +#include "usbdriver.h" +#include "ChipInfoDb.h" +#include "SerialFlash.h" +#include "project.h" +#include +#include +#include +#include +#include +#include + #include + +#include "dpcmd.h" +#include "board.h" +#define min(a,b) (a>b? b:a) + +extern unsigned char* pBufferForLastReadData; +extern unsigned char* pBufferforLoadedFile; +extern unsigned int g_uiFileChecksum; +extern unsigned long g_ulFileSize; +extern volatile bool g_bIsSF600; +extern unsigned char g_BatchIndex; +extern volatile bool g_bIsSF600; + +unsigned int g_Vcc=vcc3_5V; +unsigned int g_Vpp=9; +unsigned int g_uiAddr=0; +unsigned int g_uiLen=0; +unsigned int g_ucFill=0xFF; +unsigned int g_ucTarget=1; +unsigned int g_uiTimeout=300; +unsigned int g_ucSPIClock=clk_12M; +unsigned int g_uiBlink=0; +unsigned int g_uiDeviceID=0; +unsigned int g_IO1Select=0; +unsigned int g_IO4Select=1; + +bool g_bEnableVpp=false; +int g_StartupMode=STARTUP_APPLI_SF_1; +bool g_bStatus=true; +extern void Sleep(unsigned int ms); + + +CHIP_INFO Chip_Info; +char *l_opt_arg; +struct CAddressRange DownloadAddrRange; +struct CAddressRange UploadAddrRange; +char* g_parameter_read="\0"; +char* g_parameter_program="\0"; +char* g_parameter_auto="\0"; +char* g_parameter_batch="\0"; +char* g_parameter_fsum="\0"; +char* g_parameter_raw="\0"; +char* g_parameter_raw_return="\0"; +char* g_parameter_addr="0"; +char* g_parameter_length="\0"; +char* g_parameter_fill="FF"; +char* g_parameter_type="\0"; +char* g_parameter_timeout="300"; +char* g_parameter_target="1"; +char* g_parameter_vcc="NO"; +//char* g_parameter_spi_clk="2"; +char* g_parameter_blink="0"; +char g_LogPath[512]={0}; + +unsigned long g_ucOperation; +struct memory_id g_ChipID; +char g_board_type[8]; +int g_firmversion; +//bool g_bIsSF600=false; +int g_CurrentSeriase=Seriase_25; +int m_isCanceled = 0; +int m_bProtectAfterWritenErase = 0; +int m_boEnReadQuadIO = 0; +int m_boEnWriteQuadIO = 0; +volatile bool g_is_operation_on_going=false; +bool g_is_operation_successful=true; +bool g_bDisplayTimer=true; + + +//char* const short_options = "?Ldber:p:u:sf:I:R:a:l:vx:T:S:N:B:D:F:V:t:g:c:POik:"; + +static const char* msg_err_communication = "Error: USB communication error or configuration file missing.\n"; +static const char* msg_err_openfile = "Error: Failed to open file.\n"; +static const char* msg_err_identifychip = "Error: chip not identified.\n"; +static const char* msg_err_timeout_abortion = "\nError: Abort abnormally due to timeout.\n*** You might need to un-plug the USB device to recover the state. ***\n"; +static const char* msg_err_lengthoverflow_abortion= "\nError: Length parameter exceeding file size, operation aborted\n"; +static const char* msg_err_addroverflow_abortion = "\nError: Exceeding chip size, operation aborted\n"; +static const char* msg_warning_optionignore_al = "\nWarning: either --addr or --length cannot be used with --auto, will be ignored\n"; +static const char* msg_info_loading = "\nLoading file, please wait ..."; +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_auto = "\nAuto Sequences, please wait ..."; +static const char* msg_info_verifying = "\nVerifying, please wait ..."; +static const char* msg_info_unknownoption= "\nError: illegal option."; +static const char* msg_info_chipblank = "\nThe chip is blank"; +static const char* msg_info_chipnotblank = "\nThe chip is NOT blank"; +static const char* msg_info_eraseOK = "\nErase OK"; +static const char* msg_info_erasefail = "\nError: Erase Failed"; +static const char* msg_info_progOK = "\nProgram OK"; +static const char* msg_info_progfail = "\nError: Program Failed"; +static const char* msg_info_readOK = "\nRead OK"; +static const char* msg_info_readfail = "\nRead Failed"; +static const char* msg_info_autoOK = "\nAutomatic program OK"; +static const char* msg_info_autofail = "\nError: Automatic program Failed"; +static const char* msg_info_verifyOK = "\nVerify OK"; +static const char* msg_info_verifyfail = "\nError: Verify 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:"; + +struct option long_options[] = { + { "help", 0, NULL, '?' }, + { "list", 0, NULL, 'L' }, + { "detect", 0, NULL, 'd' }, + { "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' }, + { "raw-instruction", 1, NULL, 'I' }, + { "raw-require-return", 1, NULL, 'R' }, + { "addr", 1, NULL, 'a' }, + { "length", 1, NULL, 'l' }, + { "verify", 0, NULL, 'v' }, + { "fill", 1, NULL, 'x' }, + { "type", 1, NULL, 'T' }, + { "lock-start", 1, NULL, 'S' }, + { "lock-length", 1, NULL, 'N' }, + { "blink", 1, NULL, 'B' }, +// { "device", 1, NULL, 'D' }, +// { "fix-device", 1, NULL, 'F' }, + { "list-device-id", 1, NULL, 'V' }, + { "timeout", 1, NULL, 't' }, + { "target", 1, NULL, 'g' }, + { "vcc", 1, NULL, 'c' }, + { "vpp", 0, NULL, 'P' }, + { "log", 1, NULL, 'O' }, + { "silent", 0, NULL, 'i' }, + { "spi-clk", 1, NULL, 'k' }, + { "set-io1", 1, NULL, '1' }, + { "set-io4", 1, NULL, '4' }, + { 0, 0, 0, 0}, +}; + +#if 0 +int verbose = 1; + +void print_endpoint(struct usb_endpoint_descriptor *endpoint) +{ + printf(" bEndpointAddress: %02xh\n", endpoint->bEndpointAddress); + printf(" bmAttributes: %02xh\n", endpoint->bmAttributes); + printf(" wMaxPacketSize: %d\n", endpoint->wMaxPacketSize); + printf(" bInterval: %d\n", endpoint->bInterval); + printf(" bRefresh: %d\n", endpoint->bRefresh); + printf(" bSynchAddress: %d\n", endpoint->bSynchAddress); +} + +void print_altsetting(struct usb_interface_descriptor *interface) +{ + int i; + + printf(" bInterfaceNumber: %d\n", interface->bInterfaceNumber); + printf(" bAlternateSetting: %d\n", interface->bAlternateSetting); + printf(" bNumEndpoints: %d\n", interface->bNumEndpoints); + printf(" bInterfaceClass: %d\n", interface->bInterfaceClass); + printf(" bInterfaceSubClass: %d\n", interface->bInterfaceSubClass); + printf(" bInterfaceProtocol: %d\n", interface->bInterfaceProtocol); + printf(" iInterface: %d\n", interface->iInterface); + + for (i = 0; i < interface->bNumEndpoints; i++) + print_endpoint(&interface->endpoint[i]); +} + +void print_interface(struct usb_interface *interface) +{ + int i; + + for (i = 0; i < interface->num_altsetting; i++) + print_altsetting(&interface->altsetting[i]); +} + +void print_configuration(struct usb_config_descriptor *config) +{ + int i; + + printf(" wTotalLength: %d\n", config->wTotalLength); + printf(" bNumInterfaces: %d\n", config->bNumInterfaces); + printf(" bConfigurationValue: %d\n", config->bConfigurationValue); + printf(" iConfiguration: %d\n", config->iConfiguration); + printf(" bmAttributes: %02xh\n", config->bmAttributes); + printf(" MaxPower: %d\n", config->MaxPower); + + for (i = 0; i < config->bNumInterfaces; i++) + print_interface(&config->interface[i]); +} + +int print_device(struct usb_device *dev, int level) +{ + usb_dev_handle *udev; + char description[256]; + char string[256]; + int ret, i; + + udev = usb_open(dev); + if (udev) { + if (dev->descriptor.iManufacturer) { + ret = usb_get_string_simple(udev, dev->descriptor.iManufacturer, string, sizeof(string)); + if (ret > 0) + snprintf(description, sizeof(description), "%s - ", string); + else + snprintf(description, sizeof(description), "%04X - ", + dev->descriptor.idVendor); + } else + snprintf(description, sizeof(description), "%04X - ", + dev->descriptor.idVendor); + + if (dev->descriptor.iProduct) { + ret = usb_get_string_simple(udev, dev->descriptor.iProduct, string, sizeof(string)); + if (ret > 0) + snprintf(description + strlen(description), sizeof(description) - + strlen(description), "%s", string); + else + snprintf(description + strlen(description), sizeof(description) - + strlen(description), "%04X", dev->descriptor.idProduct); + } else + snprintf(description + strlen(description), sizeof(description) - + strlen(description), "%04X", dev->descriptor.idProduct); + + } else + snprintf(description, sizeof(description), "%04X - %04X", + dev->descriptor.idVendor, dev->descriptor.idProduct); + + printf("%.*sDev #%d: %s\n", level * 2, " ", dev->devnum, + description); + + if (udev && verbose) { + if (dev->descriptor.iSerialNumber) { + ret = usb_get_string_simple(udev, dev->descriptor.iSerialNumber, string, sizeof(string)); + if (ret > 0) + printf("%.*s - Serial Number: %s\n", level * 2, + " ", string); + } + } + + if (udev) + usb_close(udev); + + if (verbose) { + if (!dev->config) { + printf(" Couldn't retrieve descriptors\n"); + return 0; + } + + for (i = 0; i < dev->descriptor.bNumConfigurations; i++) + print_configuration(&dev->config[i]); + } else { + for (i = 0; i < dev->num_children; i++) + print_device(dev->children[i], level + 1); + } + + return 0; +} + +int Check(int argc, char *argv[]) +{ + struct usb_bus *bus; + + if (argc > 1 && !strcmp(argv[1], "-v")) + verbose = 1; + + usb_init(); + + usb_find_busses(); + usb_find_devices(); + + for (bus = usb_busses; bus; bus = bus->next) { + if (bus->root_dev && !verbose) { + printf("root device:"); + print_device(bus->root_dev, 0); + } + else { + struct usb_device *dev; + + for (dev = bus->devices; dev; dev = dev->next) { + printf("non-root device:"); + print_device(dev, 0); + } + } + } + + return 0; +} + +#endif +int Sequence() +{ + // *** the calling order in the following block must be kept as is *** + bool boResult=true; + + boResult &= BlankCheck(); + if(boResult==false) + return EXCODE_FAIL_BLANK; + + boResult &= Erase(); + if(boResult==false) + return EXCODE_FAIL_ERASE; + + boResult &= Program(); + if(boResult==false) + return EXCODE_FAIL_PROG; + + boResult &= Read(); + if(boResult==false) + return EXCODE_FAIL_READ; + + boResult &= Auto(); + if(boResult==false) + return EXCODE_FAIL_BATCH; + + + boResult &= CalChecksum(); + if(boResult==true) + { + if(g_ucOperation & CSUM) + { + if(g_uiLen==0) + return CRC32(pBufferForLastReadData, Chip_Info.ChipSizeInByte); + else + return CRC32(pBufferForLastReadData, g_uiLen); + } + } + else + return EXCODE_FAIL_CHKSUM; + + boResult &= Verify(); + if(boResult==false) + return EXCODE_FAIL_VERIFY; + + return EXCODE_PASS; +} + + +void *print_message_function( void *ptr ) +{ + char *message; + message = (char *) ptr; + printf("%s \n", message); +} + +void GetLogPath(char* pBuf) +{ + memset(pBuf,0,512); + if (readlink ("/proc/self/exe", pBuf, 512) != -1) + { + if(strlen(pBuf)<(511-sizeof("/log.txt"))) + strcat(pBuf,"/log.txt"); +// printf("%s\r\n",pBuf); + } +} + +void EnterStandaloneMode(int USBIndex) +{ + if(g_bIsSF600==true) + LeaveSF600Standalone(false,USBIndex); +} + +void LeaveStandaloneMode(int USBIndex) +{ + if(g_bIsSF600==true) + LeaveSF600Standalone(true,USBIndex); +} + +void WriteLog(int ErrorCode, bool Init) +{ + FILE *FileOut=NULL ; /* output files */ + time_t rawtime; + struct tm * timeinfo; + char buffer [512]={0}; + char* Result[]={ + " PASS\n", + " FAIL\n", + " Erase Fail\n", + " Program Fail\n", + " Verify Fail\n", + " Read Fail\n", + " Blank Check Fail\n", + " Auto Batch Fail\n", + " Checksum Fail\n", + " Identify Fail\n", + " Unknow Fail\n" + }; + + time (&rawtime); + timeinfo = localtime (&rawtime); + + strftime (buffer,80,"%Y-%b-%d %T",timeinfo); + if(Init) + { + FileOut = fopen(g_LogPath,"wt") ; + if(FileOut != NULL) + fprintf(FileOut, "%s%s%s",buffer," USB communication =",Result[ErrorCode]); + } + else + { + FileOut = fopen(g_LogPath,"a+t") ; + if(FileOut != NULL) + fprintf(FileOut, "%s%s",buffer,Result[ErrorCode]); + } + + if(FileOut != NULL) + fclose(FileOut); +} + +int main(int argc, char *argv[]) +{ + #if 0 //Check all USB device capability + Check(argc,argv); + return; + #endif + int c; + int iExitCode=EXCODE_PASS; + bool bDetect=false; + + printf("\nDpCmd Linux 1.1.0.05 Engine Version:\nLast Built on Jun 22 2015\n\n"); + + g_ucOperation=0; + GetLogPath(g_LogPath); + + if(argc==1) + { + cli_classic_usage(false); + return 0; + } + if(OpenUSB()==0) + iExitCode=EXCODE_FAIL_USB; + +// QueryBoard(0); + LeaveStandaloneMode(0); + + while((c = getopt_long (argc, argv, short_options, long_options, NULL)) != -1) + { + switch (c) + { + case '?': + cli_classic_usage(true); + CloseProject(); + ExitProgram(); + return EXCODE_PASS; + case 'L': + g_ucOperation |= LIST_TYPE; + break; + case 'd': + bDetect=true; + break; + case 'b': + g_ucOperation |= BLANK; + break; + case 'e': + g_ucOperation |= ERASE; + break; + case 'r': + g_parameter_read = optarg; + g_ucOperation |= READ_TO_FILE; + break; + case 'p': + g_parameter_program= optarg; + g_ucOperation |= PROGRAM; + break; + case 'u': + g_parameter_auto = optarg; + g_ucOperation |= BATCH; + g_BatchIndex=2; + break; + case 'z': + g_parameter_batch = optarg; + g_ucOperation |= BATCH; + g_BatchIndex=1; + break; + case 's': // display chip checksum + g_ucOperation |= CSUM; + break; + case 'f': //display file checksum + g_parameter_fsum = optarg; + g_ucOperation |= FSUM; + break; + case 'I': + g_parameter_raw = optarg; + break; + case 'R': //raw-require-return + g_parameter_raw_return = optarg; + break; + /* Optional Switches that add fine-tune ability to Basic Switches: */ + case 'a': + g_parameter_addr = optarg; + g_uiAddr=0; + sscanf(optarg,"%x",&g_uiAddr); + break; + case 'l': + g_uiLen=0; + sscanf(optarg,"%x",&g_uiLen); + break; + case 'v': + g_ucOperation |= VERIFY; + break; + case 'x': + g_ucFill=0xFF; + sscanf(optarg,"%x",&g_ucFill); + break; + case 'T': + g_parameter_type= optarg; //type + break; + case 'S': //lock start +// l_opt_arg = optarg; +// printf("hexadecimal starting address (with arg: %s)\n", l_opt_arg); + break; + case 'N': //lock length +// l_opt_arg = optarg; +// printf("hexadecimal length of area that will be kept unchanged while updating (with arg: %s)\n", l_opt_arg); + break; + case 'B': + sscanf(optarg,"%d",&g_uiBlink); + g_ucOperation |= BLINK; + break; + case 'D': // device + l_opt_arg = optarg; + printf("activate only the programmer connected to USBx (with arg: %s)\n", l_opt_arg); + break; + case 'F': + l_opt_arg = optarg; + printf("Fix programmer serial number with programmer sequence. (with arg: %s)\n", l_opt_arg); + break; + case 'V': + sscanf(optarg,"%d",&g_uiDeviceID); + g_ucOperation |= DEVICE_ID; //list device id + break; + /* Miscellaneous options: */ + case 't': + l_opt_arg = optarg; + sscanf(l_opt_arg,"%d",&g_uiTimeout); + break; + case 'g': + g_parameter_target=optarg; + sscanf(optarg,"%d",&g_ucTarget); + break; + case 'c': + g_parameter_vcc=optarg; + sscanf(optarg,"%d",&g_Vcc); + break; + case 'P': + g_bEnableVpp=true; + break; + case 'O': //Log file + strcpy(g_LogPath,optarg); +// printf("%s\r\n",g_LogPath); + break; + case 'i': + g_bDisplayTimer=false; + break; + case 'k': + l_opt_arg = optarg; + sscanf(l_opt_arg,"%d",&g_ucSPIClock); + break; + case '1': + l_opt_arg = optarg; + sscanf(l_opt_arg,"%d",&g_IO1Select); + break; + case '4': + l_opt_arg = optarg; + sscanf(l_opt_arg,"%d",&g_IO4Select); + break; + default: + break; + } + } + if(bDetect==true) + { +// printf("%s\r\n",g_LogPath); + WriteLog(iExitCode, true); + printf("detecting chip\r\n"); + Chip_Info=GetFirstDetectionMatch(0); + if(Chip_Info.UniqueID !=0 ) + { + printf("By reading the chip ID, the chip applies to [ %s ]\r\n", Chip_Info.TypeName); + printf("%s chip size is %d bytes.\r\n",Chip_Info.TypeName,Chip_Info.ChipSizeInByte); + } + else + { + printf("%s",msg_err_identifychip); + iExitCode=EXCODE_FAIL_IDENTIFY; + } + goto Exit; + } + else + WriteLog(iExitCode, true); + + if(iExitCode != EXCODE_PASS) goto Exit; + + iExitCode=Handler(); + +Exit: + CloseProject(); + ExitProgram(); + WriteLog(iExitCode,false); + return iExitCode; +} + +void ExitProgram(void) +{ + if(pBufferForLastReadData != NULL) + free(pBufferForLastReadData); + if(pBufferforLoadedFile != NULL) + free(pBufferforLoadedFile); +} + + +void cli_classic_usage(bool IsShowExample) +{ + printf("Basic Usages:\n"); + printf("./dpcmd -uxxx\n"); + printf("./dpcmd --auto=xxx\n"); + if(IsShowExample) + printf("Usage Examples:\n" + "1. dpcmd -r\"f:\\file.bin\", \n reads the chip and save it into a file \"file.bin\"\n" + "2. dpcmd -rSTDOUT -a0x100 -l0x23, \n reads 0x23 bytes starting from 0x100 and display it on the screen\n" + "3. dpcmd -ufile.bin, \n Update the whole chip with file.bin\n" + "4. Dpcmd -ufile.bin -a0x100, \n Replace the serial flash contents for the size of file.bin with file.bin.\n" + " (contents outside the replace area will be kept unchanged)\n" + "5. dpcmd -pfile.bin -a0x100, \n program file.bin into the serial flash starting from address 0x100\n" + " (the target area is assumed to be blank already)\n" + "6. dpcmd -pfile.bin -x0xaa, \n programs file.bin into the serial flash and fill the rest area with 0xaa\n" + " (the target area is assumed to be blank already)\n" + "Remark: -a, -l only works with -p, -r, -s and -u\n" + "Remark: -x only works with -p"); + + printf("(space is not needed between the switches and parameters. E.g. dpcmd -ubio.bin)\n"); + printf(" -? [ --help ] show this help message\n" + " --list print supported chip list\n" + " -d [ --detect ] detect chip\n" + " -b [ --blank ] blank check\n" + " -e [ --erase ] erase entire chip\n" + " -r [ --read ] arg read chip contents and save to a bin/hex/s19 file\n" + " -p [ --prog ] arg program chip without erase\n" + " -u [ --auto ] arg automatically run the following sequence:\n" + " - Read the memory content\n" + " - Compare the memory content\n" + " - Erase only the sectors with some differences\n" + " - Program only the erased sectors with file data from address 0\n" + " -z [ --batch ] arg automatically run the following sequence:\n" + " - check if the chip is blank or not;\n" + " - 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" + " --raw-instruction arg issue raw serial flash instructions.\n" + " - use spaces(" ") to delimite bytes.\n" + " - instructions must be enclosed in double quotation marks(\"\")\n" + " Example:\n" + " dpcmd --raw-instruction \"03 FF 00 12\"\n" + " --raw-require-return arg (=0) 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' \n" + " --raw-require-return 1\n" + "\n" + "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" + " - defaults to 0, if omitted.\n" + " -l [ --length ] arg hexadecimal length to read/program in bytes,\n" + " - works with --prog/read/sum/auto only\n" + " - defaults to whole file if omitted\n" + " -v [ --verify ] verify checksum file and chip\n" + " - works with --prog/auto only\n" + " -x [ --fill ] arg (=FF) fill spare space with an hex value(e.g.FF),\n" + " - works with --prog, --auto only\n" + " --type arg Specify a type to override auto detection\n" + " - use --list arguement to look up supported type.\n" + " --lock-start arg hexadecimal starting address(e.g. 0x1000),\n" + " - works with --prog/read/sum/auto only\n" + " - defaults to 0, if omitted.\n" + " --lock-length arg hexadecimal length of area that will be kept\n" + " unchanged while updating\n" + " - used along with --auto only.\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" +// " - n: Blink the programmer connected to USBn 3 times.\n" +// " --device arg (work with all Basic Switchs)\n" +// " - 1: activate only the programmer connected to USB1\n" +// " - n: activate only the programmer connected to USBn\n" +// " note: if '--device' is not used, the command will\n" +// " be executed on all connected programmer.\n" +// " --fix-device arg Fix programmer serial number with programmer sequence.\n" +// " - instructions must be enclosed in double quotation marks(\"\")\n" +// " Example:\n" +// " dpcmd --fix-device \"1 DP000001\"\n" + " --list-device-id arg \n" +// " - 0 : List all ID of programmers from USB1 to USBn (Default)\n" +// " note: the sequence is assigned by OS during USB plug-in.\n" + " - 1: Prompt the device ID of programmer connected to USB1.\n" +// " - n: Prompt the device ID of programmer connected to USBn.\n" + "\n" + "Miscellaneous options:\n" + " -t [ --timeout ] arg (=300) Timeout value in seconds\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" + " --vcc arg (=0) specify vcc\n" + " 0, 3.5V(Default)\n" + " 1, 2.5V\n" + " 2, 1.8V\n" + " 1800 ~ 3800, 1.8V ~ 3.8V\n" + " (minimum step 100mV)(For SF600/SF600Plus only)\n" + " --vpp apply vpp when the memory chip supports it\n" + " --log arg Record the operation result in given/appointed .txt file\n" + " Example:\n" + " ./dpcmd --log /tmp/log.txt\n" + " Note: If user didn't use this command, \n" + " the operation result will be recorded in \"log.txt\"\n" + " - work with --prog and --erase.\n" + " -i [ --silent ] supress the display of real-time timer counting\n" + " - used when integrating with 3rd-party tools(e.g. IDE)\n" + " --spi-clk arg (=2) specify SPI clock:\n" + " 2, 12 MHz(Default)\n" + " 0, 24 MHz\n" + " 1, 8 MHz\n" + " 3, 3 MHz\n" + " 4, 2.18 MHz\n" + " 5, 1.5 MHz\n" + " 6, 750 KHz\n" + " 7, 375 KHz\n" + " --set-io1 arg (=0) specify Level of IO1(SF100) or GPIO1(SF600/SF600Plus):\n" + " 0, Low(Default)\n" + " 1, High\n" + " --set-io4 arg (=1) specify Level of IO4(SF100) or GPIO2(SF600/SF600Plus):\n" + " 0, Low\n" + " 1, High(Default)\n" + "\n\n\n"); +} + +int OpenUSB(void) +{ + return usb_driver_init(); +} + +int Handler(void) +{ + if(Is_usbworking()==true) + { + #if 0 + if(m_vm.count("fix-device")) + { + FixProgrammer(); + return EXCODE_PASS; + } + + AssignedDevice(); + #endif + if((g_ucOperation & BLINK)==BLINK) + { + BlinkProgrammer(); + return EXCODE_PASS; + } + + if((g_ucOperation & DEVICE_ID)==DEVICE_ID) + { + ListSFSerialID(); + return EXCODE_PASS; + } + } + else + { + printf("Error: Programmers are not connected.\r\n"); + return EXCODE_FAIL_OTHERS; + } + if(!InitProject()) return EXCODE_FAIL_OTHERS; + //my_timer t; // opertion timer + + if(ListTypes()) return EXCODE_PASS; + + if(strlen(g_parameter_type)>0) + { + RawInstructions(0); + return Sequence(); + } + else if(DetectChip()) + { + return Sequence(); + } + else + return EXCODE_FAIL_IDENTIFY; + + return EXCODE_FAIL_OTHERS; +} + +bool InitProject(void) +{ + if(Is_usbworking()) + { + int targets[4] = + { + STARTUP_APPLI_CARD, + STARTUP_APPLI_SF_1, + STARTUP_APPLI_SF_2, + STARTUP_APPLI_SF_SKT, + }; + g_StartupMode=targets[g_ucTarget]; + SetTargetFlash((unsigned char)targets[g_ucTarget], 0); + SetSPIClock(); + SetVcc(); + + if(strlen(g_parameter_type)>0) + { + if(Dedi_Search_Chip_Db_ByTypeName(g_parameter_type,&Chip_Info,1)) + { + printf("Chip Type %s is applied manually.\r\n",Chip_Info.TypeName); + printf("%s chip size is %d bytes.\n\n",Chip_Info.TypeName,Chip_Info.ChipSizeInByte); + ProjectInitWithID(Chip_Info,0); + } + else + { + printf("Chip Type Unknow is applied manually.\r\n"); + return false; + } + + } + else + { + ProjectInit(0); + } + return true; + } + return false; +} + +void CloseProject(void) +{ + EnterStandaloneMode(0); + usb_driver_release(); +} + +bool DetectChip(void) +{ + RawInstructions(0); + + if(!Is_usbworking()) + { + printf("%s",msg_err_communication); + return false; + } + if(0 == Chip_Info.UniqueID) + { + printf("%s",msg_err_identifychip); + return false; + } + + printf("By reading the chip ID, the chip applies to [ %s ]\n",Chip_Info.TypeName); + printf("%s parameters to be applied by default\n",Chip_Info.TypeName); + printf("%s chip size is %d bytes.\n\n",Chip_Info.TypeName,Chip_Info.ChipSizeInByte); + return true; + +} + +/* Simon: add later */ +void SetVpp(void) { +} + +void SetSPIClock(void) +{ +// sscanf(g_parameter_spi_clk,"%d",&g_ucSPIClock); + SetSPIClockValue(g_ucSPIClock,0); +} + +void SetVcc(void) +{ +// sscanf(g_parameter_vcc,"%d",&g_Vcc); + if(g_Vcc<=3800 && g_Vcc>=1800 && g_bIsSF600==true) + ; + else + g_Vcc= (0x10 | (g_Vcc&0x03)); + //printf("Vcc=%x\r\n",g_Vcc); +} + +int do_loadFile(void) +{ + char* filename; + if(g_ucOperation & PROGRAM) + filename=g_parameter_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)",filename); + return LoadFile(filename); +} + +bool ListTypes(void) +{ + if((g_ucOperation&LIST_TYPE)!=LIST_TYPE) return false; + Dedi_List_AllChip(); + + return true; +} + +void BlinkProgrammer(void) +{ + bool IsV5=is_BoardVersionGreaterThan_5_0_0(0); + if(IsV5==false) return; + + if(g_uiBlink<=1) + { + printf("Blink LED on USB device 1 \r\n"); + BlinkProgBoard(IsV5,0); + Sleep(500); + BlinkProgBoard(IsV5,0); + Sleep(500); + BlinkProgBoard(IsV5,0); + } + else + printf("Error: Did not find the programmer.\r\n"); +} + +void ListSFSerialID(void) +{ + unsigned int dwUID=0; + if(g_uiDeviceID<=1) + { + dwUID=ReadUID(0); + printf("1,\tDP%06d\r\n",dwUID); + } + else + printf("The number of programmer is not defined!\r\n"); +} + +void do_BlankCheck(void) +{ + printf("%s",msg_info_checking); + Run(BLANKCHECK_WHOLE_CHIP); + + Wait ( msg_info_chipblank, msg_info_chipnotblank ); +} + +void do_Erase(void) +{ + printf("%s,",msg_info_erasing); + Run(ERASE_WHOLE_CHIP); + + Wait( msg_info_eraseOK, msg_info_erasefail) ; +} + +void do_Program(void) +{ + if(!do_loadFile()) return; + + SaveProgContextChanges(); + + printf("%s",msg_info_programming); + Run(PROGRAM_CHIP); + + if( Wait( msg_info_progOK, msg_info_progfail ) ) + { + printf("\nChecksum(whole file): %08X",g_uiFileChecksum); + printf("\nChecksum(Written part of file): %08X\n",CRC32(pBufferforLoadedFile, min(DownloadAddrRange.end-DownloadAddrRange.start,g_ulFileSize))); + } +} + +void do_Read(void) +{ + DownloadAddrRange.start=g_uiAddr; + DownloadAddrRange.length=g_uiLen; + DownloadAddrRange.end=g_uiAddr+g_uiLen; + + printf("%s",msg_info_reading); + Run(READ_ANY_BY_PREFERENCE_CONFIGURATION); + Wait(msg_info_readOK,msg_info_readfail); +} + +void do_DisplayOrSave(void) +{ + if(strcmp(g_parameter_read, "STDOUT")==0) + { + int i,Len=UploadAddrRange.end-UploadAddrRange.start; + printf("\n"); + printf("Hex value display (starting from 0x%02X, 0x%02Xbytes in total): \n",g_uiAddr,g_uiLen); + for(i=0; i()); + m_context.Prog_CustomizedAddrFrom = hexstring_to_size_t(m_vm["addr"].as()); + m_context.Prog_CustomizedDataLength = hexstring_to_size_t(m_vm["length"].as()); + m_context.LockStartFrom = hexstring_to_size_t(m_vm["lock-start"].as()); + m_context.LockLength = hexstring_to_size_t(m_vm["lock-length"].as()); +#endif +} + +void do_Auto(void) +{ + if(do_loadFile()==0) return; + SaveProgContextChanges(); + + printf("%s",msg_info_auto); + Run(AUTO); + + if( Wait(msg_info_autoOK,msg_info_autofail) ) + { + printf("\nChecksum(whole file): %08X",g_uiFileChecksum); + printf("\nChecksum(Written part of file): %08X\n",CRC32(pBufferforLoadedFile, DownloadAddrRange.end-DownloadAddrRange.start)); + } +} + +void do_Verify(void) +{ + printf("%s",msg_info_verifying); + Run(VERIFY_CONTENT); + + Wait(msg_info_verifyOK,msg_info_verifyfail); +} + +void do_ReadSR(int Index) +{ + unsigned char rdsr=0x05; + unsigned char cSR; + if(FlashCommand_SendCommand_OneOutOneIn(&rdsr,1,&cSR,1,Index)==0) + printf("SR unavailable\n"); + else + printf("SR=0x%02X\n",cSR); + +} + +void do_RawInstructions(int Index) +{ + unsigned char vOut[512]; + unsigned char vIn[512]={0xFF,0xFF,0xFF,0}; + unsigned char Length=0; + int i=0; + char* pch; + char parameter[40]; + strcpy(parameter,g_parameter_raw); + TurnONVcc(Index); + pch = strtok (parameter," ,;-"); + while( pch!= NULL) + { + sscanf(pch,"%02x",&vOut[i]); + i++; + pch = strtok (NULL, " ,;-"); + } + + if(strlen(g_parameter_raw_return)>0) + sscanf(g_parameter_raw_return,"%d",&Length); + + if(Length>0) + FlashCommand_SendCommand_OneOutOneIn(vOut,i,vIn,Length,Index); + else + FlashCommand_SendCommand_OutOnlyInstruction(vOut,i,Index); + + if(Length>0) + { + printf("issuing raw instruction \"%s\" returns %d bytes as required:\n",g_parameter_raw,Length); + for(i=0; i0) + do_RawInstructions(Index); +} + +bool BlankCheck(void) +{ + if(g_ucOperation&BLANK) + do_BlankCheck(); + + return g_bStatus; +} + +bool Erase(void) +{ + if(g_ucOperation&ERASE) + do_Erase(); + + return g_bStatus; +} + +bool Program(void) +{ + if(g_ucOperation&PROGRAM) + do_Program(); + + return g_bStatus; +} + +bool Read(void) +{ + if(g_ucOperation&READ_TO_FILE) + { + do_Read(); + do_DisplayOrSave(); + } + return g_bStatus; +} + +bool Auto(void) +{ + if(g_ucOperation & BATCH) + do_Auto(); + return g_bStatus; +} + +bool Verify(void) +{ + if(g_ucOperation & VERIFY) + do_Verify(); + return g_bStatus; +} + + +bool CalChecksum(void) +{ + if(g_ucOperation & FSUM) + { + do_loadFile(); + printf("\nChecksum(file): 0x%08X\n",g_uiFileChecksum); + } + + if(g_ucOperation & CSUM) + { + do_Read(); + + if( g_uiAddr==0 && g_uiLen ==0) + { + printf("\nChecksum of the whole chip(address starting from: 0x%X, 0x%X bytes in total): %08X\n",g_uiAddr,Chip_Info.ChipSizeInByte,CRC32(pBufferForLastReadData,Chip_Info.ChipSizeInByte)); + } + else + { + printf("\nChecksum(address starting from: 0x%X, 0x%X bytes in total): %08X\n",g_uiAddr,g_uiLen,CRC32(pBufferForLastReadData, min(g_uiLen,Chip_Info.ChipSizeInByte))); + } + + } + + return g_bStatus; +} + +bool Wait(const char* strOK,const char* strFail) +{ + + size_t timeOut = g_uiTimeout; + struct timeval tv,basetv,diff; + + Sleep(100); // wait till the new thread starts .... + + gettimeofday (&basetv , NULL); + printf("\n"); + + while( g_is_operation_on_going==true) + { + gettimeofday (&tv , NULL); + if(tv.tv_sec-basetv.tv_sec > timeOut) + { + timersub(&tv, &basetv, &diff); + printf("%d.00%d\t s elapsed\r",diff.tv_sec,(diff.tv_usec>>10)&0x03); + printf("%s",msg_err_timeout_abortion); + g_bStatus=false; + return false; + } + + if(g_bDisplayTimer==true) + { + timersub(&tv, &basetv, &diff); + printf("%d.%d\t s elapsed\r",diff.tv_sec,(diff.tv_usec>>8)); + } + } + printf("\n%s\n",g_is_operation_successful? strOK : strFail); + g_bStatus=g_is_operation_successful; + return g_bStatus; +} + +int FlashIdentifier(CHIP_INFO*Chip_Info, int search_all) { + long UniqueID = 0; + int rc = 0; + UniqueID = flash_ReadId(0x9f, 4, 1); + if (UniqueID != 0) { +// printf("\n UniqueID(1) = 0x%lx\n", UniqueID); + rc = Dedi_Search_Chip_Db(0x9f, UniqueID, Chip_Info, search_all); + if(rc && (search_all == 0)) + return rc; + } + UniqueID = 0; + rc = 0; + UniqueID = flash_ReadId(0x9f, 3, 1); + if (UniqueID != 0) { +// printf("\n UniqueID(2) = 0x%lx\n", UniqueID); + rc = Dedi_Search_Chip_Db(0x9f, UniqueID, Chip_Info, search_all); + if(rc && (search_all == 0)) + return rc; + } + UniqueID = 0; + rc = 0; + UniqueID = flash_ReadId(0x9f, 2, 1); + if (UniqueID != 0) { +// printf("\n UniqueID(3) = 0x%lx\n", UniqueID); + rc = Dedi_Search_Chip_Db(0x9f, UniqueID, Chip_Info, search_all); + if(rc && (search_all == 0)) + return rc; + } + UniqueID = 0; + rc = 0; + UniqueID = flash_ReadId(0x15, 2, 1); + if (UniqueID != 0) { +// printf("\n UniqueID(4) = 0x%lx\n", UniqueID); + rc = Dedi_Search_Chip_Db(0x15, UniqueID, Chip_Info, search_all); + if(rc && (search_all == 0)) + return rc; + } + UniqueID = 0; + rc = 0; + UniqueID = flash_ReadId(0xab, 3, 1); + if (UniqueID != 0) { +// printf("\n UniqueID(5) = 0x%lx \n", UniqueID); + rc = Dedi_Search_Chip_Db(0xab, UniqueID, Chip_Info, search_all); + if(rc && (search_all == 0)) + return rc; + } + UniqueID = 0; + rc = 0; + UniqueID = flash_ReadId(0xab, 2, 1); + if (UniqueID != 0) { +// printf("\n UniqueID(6) = 0x%lx\n", UniqueID); + rc = Dedi_Search_Chip_Db(0xab, UniqueID, Chip_Info, search_all); + if(rc && (search_all == 0)) + return rc; + } + UniqueID = 0; + rc = 0; + UniqueID = flash_ReadId(0x90, 3, 1); + if (UniqueID != 0) { +// printf("\n UniqueID(7) = 0x%lx\n", UniqueID); + rc = Dedi_Search_Chip_Db(0x90, UniqueID, Chip_Info, search_all); + if(rc && (search_all == 0)) + return rc; + } + UniqueID = 0; + rc = 0; + UniqueID = flash_ReadId(0x90, 2, 1); + if (UniqueID != 0) { +// printf("\n UniqueID(8) = 0x%lx\n", UniqueID); + rc = Dedi_Search_Chip_Db(0x90, UniqueID, Chip_Info, search_all); + if(rc && (search_all == 0)) + return rc; + } + UniqueID = 0; + rc = 0; + UniqueID = flash_ReadId(0x90, 5, 1); // for 25LF020 + if (UniqueID != 0) { +// printf("\n UniqueID(8) = 0x%lx\n", UniqueID); + UniqueID = UniqueID - 0xFFFF0000; + rc = Dedi_Search_Chip_Db(0x90, UniqueID, Chip_Info, search_all); + if(rc && (search_all == 0)) + return rc; + } + return rc; +} + +#endif + + + + + + + diff --git a/dpcmd.h b/dpcmd.h new file mode 100644 index 0000000..b4048fa --- /dev/null +++ b/dpcmd.h @@ -0,0 +1,97 @@ + +#pragma once + +#ifndef _DPCMD_H +#define _DPCMD_H +enum ErrorCode +{ + EXCODE_PASS, + EXCODE_FAIL_USB, + EXCODE_FAIL_ERASE, + EXCODE_FAIL_PROG, + EXCODE_FAIL_VERIFY, + EXCODE_FAIL_READ, + EXCODE_FAIL_BLANK, // 5 + EXCODE_FAIL_BATCH, + EXCODE_FAIL_CHKSUM, + EXCODE_FAIL_IDENTIFY, + EXCODE_FAIL_OTHERS, +}; + +typedef enum +{ + BLANKCHECK_WHOLE_CHIP, + PROGRAM_CHIP, + ERASE_WHOLE_CHIP, + READ_WHOLE_CHIP, + READ_ANY_BY_PREFERENCE_CONFIGURATION, + VERIFY_CONTENT, + AUTO, + + Download2Card, + // 07.03.2009 + UPDATE_FIRMWARE, + AUTO_UPDATE_FIRMWARE, + +} OPERATION_TYPE; + + 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); +void CloseProject(void); +bool DetectChip(void); +void SetVpp(void); +void SetSPIClock(void); +void SetVcc(void); +int do_loadFile(void); +void BlinkProgrammer(void); +void ListSFSerialID(void); +void do_BlankCheck(void); +void do_Erase(void); +void do_Program(void); +void do_Read(void); +void do_DisplayOrSave(void); +void SaveProgContextChanges(void); +void do_Auto(void); +void do_Verify(void); +void do_ReadSR(int Index); +void do_RawInstructions(int Index); +void RawInstructions(int Index); +bool BlankCheck(void); +bool Erase(void); +bool Program(void); +bool Read(void); +bool Auto(void); +bool Verify(void); +bool CalChecksum(void); +int Handler(); +bool ListTypes(void); +void GetLogPath(char* path); +bool Wait(const char* strOK,const char* strFail); +void ExitProgram(void); + + +#endif diff --git a/makefile b/makefile new file mode 100644 index 0000000..038a6eb --- /dev/null +++ b/makefile @@ -0,0 +1,20 @@ +# +# This file is part of the DediProg project. +# +# + +PROGRAM = dpcmd +CC = gcc +CFLAGS = -Os -Wall -lpthread + +FEATURE_LIBS += -lusb -lpthread +PROGRAMMER_OBJS += dpcmd.o usbdriver.o FlashCommand.o SerialFlash.o parse.o board.o project.o IntelHexFile.o MotorolaFile.o + + +$(PROGRAM): $(PROGRAMMER_OBJS) + $(CC) $(CFLAGS) -o $(PROGRAM) $(PROGRAMMER_OBJS) $(FEATURE_LIBS) + + +clean: + rm -f $(PROGRAM) $(PROGRAM).exe *.o *.d *.c~ *.h~ *~ + diff --git a/parse.c b/parse.c new file mode 100644 index 0000000..d66ca01 --- /dev/null +++ b/parse.c @@ -0,0 +1,671 @@ +#include +#include +#include +#include + +#include "Macro.h" +#include "ChipInfoDb.h" +#define linebufsize 512 +#define filebufsize 1024*1024 +#define min(a,b) (((a)>(b))? (b):(a)) +#define max(a,b) (((a) > (b)) ? (a) : (b)) + +void getExecPath(char* Path) +{ + memset(Path,0,512); + if (readlink ("/proc/self/exe", Path, 512) != -1) + { +// printf("%s\r\n",Path); + dirname (Path); +// printf("%s\r\n",Path); + strcat(Path,"/ChipInfoDb.dedicfg"); +// printf("%s\r\n",Path); + + } +} + +long fsize(FILE *fp){ + long prev=ftell(fp); + fseek(fp, 0L, SEEK_END); + long sz=ftell(fp); + fseek(fp,prev,SEEK_SET); //go back to where we were + return sz; +} + + +int Dedi_Search_Chip_Db(long RDIDCommand, long UniqueID, CHIP_INFO *Chip_Info, int search_all) +{ + FILE* fp; /*Declare file pointer variable*/ + int found_flag = 0; + char file_line_buf[linebufsize], *tok, fname[256], *file_buf, test[256]; + char* pch; + long sz=0; + char Path[512]; + getExecPath(Path); +// printf("%s\r\n",Path); + /*If file doesn't exist or filetype isn't allowed exit and*/ + /*error message & return (1) control to the OS*/ + if ((fp = fopen(Path,"rt")) == NULL) + { + fprintf(stderr,"Error opening file: %s\n",fname); + return 1; + } + sz=fsize(fp); + file_buf = (char*)malloc(sz); + + memset(file_buf, '\0', sz); + /*Read into the buffer contents within thr file stream*/ + + while(fgets(file_line_buf, linebufsize, fp) != NULL) + { + pch=strstr(file_line_buf,"TypeName"); + if(pch!= NULL) + { + if(found_flag==1) + break; + memset(test, '\0', 100); + strcpy(test,pch+strlen("TypeName")); + tok = strtok(test,"\"= \t"); + Chip_Info->TypeName[0] = '\0'; + Chip_Info->Class[0] = '\0'; + Chip_Info->UniqueID = 0; + Chip_Info->Description[0] = '\0'; + Chip_Info->Manufacturer[0] = '\0'; + Chip_Info->ManufactureUrl[0] = '\0'; + Chip_Info->ProgramIOMethod[0] = '\0'; + Chip_Info->Voltage[0] = '\0'; + Chip_Info->Clock[0] = '\0'; + Chip_Info->ManufactureID = 0; + Chip_Info->JedecDeviceID = 0; + Chip_Info->AlternativeID = 0; + Chip_Info->ChipSizeInByte = 0; + Chip_Info->SectorSizeInByte = 0; + Chip_Info->BlockSizeInByte = 0; + Chip_Info->PageSizeInByte = 0; + Chip_Info->AddrWidth = 0; + Chip_Info->IDNumber = 0; + Chip_Info->RDIDCommand = 0; + Chip_Info->MaxErasableSegmentInByte=0; + Chip_Info->DualID=false;; + Chip_Info->VppSupport=0; + Chip_Info->MXIC_WPmode=false; + Chip_Info->Timeout=0; + // end of struct init + strcpy(Chip_Info->TypeName,tok); + continue; + } + + pch=strstr(file_line_buf,"Class"); + if(pch != NULL) + { + memset(test, '\0', 80); + strcpy(test,pch+strlen("Class")); + tok = strtok(test,"\"= \t"); +// printf("Class = %s\n",tok); + strcpy(Chip_Info->Class,tok); + continue; + } + pch=strstr(file_line_buf,"UniqueID"); + if(pch != NULL) + { + memset(test, '\0', 80); + strcpy(test,pch+strlen("UniqueID")); + tok = strtok(test,"\"= \t"); +// printf("UniqueID = 0x%lx\n",strtol(tok,NULL,16)); + Chip_Info->UniqueID = strtol(tok,NULL,16); + if((UniqueID == Chip_Info->UniqueID)) + found_flag = 1; + continue; + } + pch=strstr(file_line_buf,"Manufacturer"); + if(pch != NULL) + { + memset(test, '\0', 80); + strcpy(test,pch+strlen("Manufacturer")); + tok = strtok(test,"\"= \t"); + //printf("Manufacturer = %s\n",tok); + strcpy(Chip_Info->Manufacturer,tok); + continue; + } + pch=strstr(file_line_buf,"Voltage"); + if(pch != NULL) + { + memset(test, '\0', 80); + strcpy(test,pch+strlen("Voltage")); + tok = strtok(test,"\"= \t"); + //printf("Voltage = %s\n",tok); + if(strcmp(tok, "3.3V") == 0) + Chip_Info->VoltageInMv = 3300; + else if(strcmp(tok, "2.5V") == 0) + Chip_Info->VoltageInMv = 2500; + else if(strcmp(tok, "1.8V") == 0) + Chip_Info->VoltageInMv = 1800; + else + Chip_Info->VoltageInMv = 3300; + continue; + } + pch=strstr(file_line_buf,"JedecDeviceID"); + if(pch != NULL) + { + memset(test, '\0', 80); + strcpy(test,pch+strlen("JedecDeviceID")); + tok = strtok(test,"\"= \t"); + //printf("JedecDeviceID = 0x%lx\n",strtol(tok,NULL,16)); + Chip_Info->JedecDeviceID = strtol(tok,NULL,16); + continue; + } + pch=strstr(file_line_buf,"ChipSizeInKByte"); + if(pch != NULL ) + { + memset(test, '\0', 80); + strcpy(test,pch+strlen("ChipSizeInKByte")); + tok = strtok(test,"\"= \t"); + //printf("ChipSizeInKByte = %ld\n",strtol(tok,NULL,10)); + Chip_Info->ChipSizeInByte = strtol(tok,NULL,10)*1024; + continue; + } + pch=strstr(file_line_buf,"SectorSizeInByte"); + if(pch != NULL ) + { + memset(test, '\0', 80); + strcpy(test,pch+strlen("SectorSizeInByte")); + tok = strtok(test,"\"= \t"); + //printf("SectorSizeInByte = %ld\n",strtol(tok,NULL,10)); + Chip_Info->SectorSizeInByte = strtol(tok,NULL,10); + continue; + } + pch=strstr(file_line_buf,"BlockSizeInByte"); + if(pch != NULL ) + { + memset(test, '\0', 80); + strcpy(test,pch+strlen("BlockSizeInByte")); + tok = strtok(test,"\"= \t"); + //printf("BlockSizeInByte = %ld\n",strtol(tok,NULL,10)); + Chip_Info->BlockSizeInByte = strtol(tok,NULL,10); + continue; + } + pch=strstr(file_line_buf,"PageSizeInByte"); + if(pch != NULL ) + { + memset(test, '\0', 80); + strcpy(test,pch+strlen("PageSizeInByte")); + tok = strtok(test,"\"= \t"); + //printf("PageSizeInByte = %ld\n",strtol(tok,NULL,10)); + Chip_Info->PageSizeInByte = strtol(tok,NULL,10); + continue; + } + pch=strstr(file_line_buf,"AddrWidth"); + if(pch != NULL ) + { + memset(test, '\0', 80); + strcpy(test,pch+strlen("AddrWidth")); + tok = strtok(test,"\"= \t"); + //printf("AddrWidth = %ld\n",strtol(tok,NULL,10)); + Chip_Info->AddrWidth = strtol(tok,NULL,10); + continue; + } + pch=strstr(file_line_buf,"IDNumber"); + if(pch != NULL ) + { + memset(test, '\0', 80); + strcpy(test,pch+strlen("IDNumber")); + tok = strtok(test,"\"= \t"); + //printf("IDNumber = %ld\n",strtol(tok,NULL,10)); + Chip_Info->IDNumber = strtol(tok,NULL,10); + continue; + } + pch=strstr(file_line_buf,"VppSupport"); + if(pch != NULL ) + { + memset(test, '\0', 80); + strcpy(test,pch+strlen("VppSupport")); + tok = strtok(test,"\"= \t"); + //printf("IDNumber = %ld\n",strtol(tok,NULL,10)); + Chip_Info->VppSupport = strtol(tok,NULL,10); + continue; + } + pch=strstr(file_line_buf,"RDIDCommand"); + if(pch != NULL ) + { + memset(test, '\0', 80); + strcpy(test,pch+strlen("RDIDCommand")); + tok = strtok(test,"\"= \t"); + Chip_Info->RDIDCommand = strtol(tok,NULL,16); + continue; + } + pch=strstr(file_line_buf,"Timeout"); + if(pch != NULL ) + { + memset(test, '\0', 80); + strcpy(test,pch+strlen("Timeout")); + tok = strtok(test,"\"= \t"); + Chip_Info->Timeout= strtol(tok,NULL,16); + continue; + } + pch=strstr(file_line_buf,"MXIC_WPmode"); + if(pch != NULL ) + { + memset(test, '\0', 80); + strcpy(test,pch+strlen("MXIC_WPmode")); + tok = strtok(test,"\"= \t"); + if(strstr(tok,"true") != NULL) + Chip_Info->MXIC_WPmode=true; + else + Chip_Info->MXIC_WPmode=false; + //starting checking input data + } +#if 0 + pch=strstr(file_line_buf,"Description="); + if( pch != NULL) + { + memset(test, '\0', 80); + strcpy(test,pch+strlen("Description=")); + tok = strtok(test,"\""); + // printf("Description = %s\n",tok); + strcpy(Chip_Info->Description,tok); + continue; + } + pch=strstr(file_line_buf,"ManufactureUrl="); + if(pch != NULL) + { + memset(test, '\0', 80); + strcpy(test,pch+strlen("ManufactureUrl=")); + tok = strtok(test,"\""); + //printf("ManufactureUrl = %s\n",tok); + strcpy(Chip_Info->ManufactureUrl,tok); + continue; + } + pch=strstr(file_line_buf,"Clock="); + if(pch != NULL) + { + memset(test, '\0', 80); + strcpy(test,pch+strlen("Clock=")); + tok = strtok(test,"\""); + //printf("Clock = %s\n",tok); + Chip_Info->Clock[0] = '\0'; + continue; + } + pch=strstr(file_line_buf,"ManufactureID="); + if(pch != NULL) + { + memset(test, '\0', 80); + strcpy(test,pch+strlen("ManufactureID=")); + tok = strtok(test,"\""); + printf("ManufactureID = 0x%lx\n",strtol(tok,NULL,16)); + Chip_Info->ManufactureID = strtol(tok,NULL,16); + } + pch=strstr(file_line_buf,"DeviceID="); + if(pch != NULL) + { + memset(test, '\0', 80); + strcpy(test,pch+strlen("DeviceID=")); + tok = strtok(test,"\""); + //printf("DeviceID = 0x%lx\n",strtol(tok,NULL,16)); + Chip_Info->AlternativeID= strtol(tok,NULL,16); + } +#endif + + }/*Continue until EOF is encoutered*/ + fclose(fp); /*Close file*/ + Chip_Info->MaxErasableSegmentInByte = max(Chip_Info->SectorSizeInByte, Chip_Info->BlockSizeInByte); + free(file_buf); + return found_flag; /*Executed without errors*/ +}/*End main*/ + +int Dedi_Search_Chip_Db_ByTypeName(char* TypeName, CHIP_INFO *Chip_Info, int search_all) +{ + FILE* fp; /*Declare file pointer variable*/ + int found_flag = 0,i; + char file_line_buf[linebufsize], *tok, fname[256], *file_buf, test[256]; + char* pch; + long sz=0; + char Type[256]={0}; + char Path[512]; + getExecPath(Path); + + for(i=0; iTypeName[0] = '\0'; + Chip_Info->Class[0] = '\0'; + Chip_Info->UniqueID = 0; + Chip_Info->Description[0] = '\0'; + Chip_Info->Manufacturer[0] = '\0'; + Chip_Info->ManufactureUrl[0] = '\0'; + Chip_Info->ProgramIOMethod[0] = '\0'; + Chip_Info->Voltage[0] = '\0'; + Chip_Info->Clock[0] = '\0'; + Chip_Info->ManufactureID = 0; + Chip_Info->JedecDeviceID = 0; + Chip_Info->AlternativeID = 0; + Chip_Info->ChipSizeInByte = 0; + Chip_Info->SectorSizeInByte = 0; + Chip_Info->BlockSizeInByte = 0; + Chip_Info->PageSizeInByte = 0; + Chip_Info->AddrWidth = 0; + Chip_Info->IDNumber = 0; + Chip_Info->RDIDCommand = 0; + Chip_Info->MaxErasableSegmentInByte=0; + Chip_Info->DualID=false;; + Chip_Info->VppSupport=0; + Chip_Info->MXIC_WPmode=false; + Chip_Info->Timeout=0; + // end of struct init + strcpy(Chip_Info->TypeName,tok); + } + else + found_flag=0; + } + + if(found_flag==0) + continue; + + pch=strstr(file_line_buf,"Class"); + if(pch != NULL) + { + memset(test, '\0', 80); + strcpy(test,pch+strlen("Class")); + tok = strtok(test,"\"= \t"); + //printf("Class = %s\n",tok); + strcpy(Chip_Info->Class,tok); + continue; + } + pch=strstr(file_line_buf,"UniqueID"); + if(pch != NULL) + { + memset(test, '\0', 80); + strcpy(test,pch+strlen("UniqueID")); + tok = strtok(test,"\"= \t"); + //printf("UniqueID = 0x%lx\n",strtol(tok,NULL,16)); + Chip_Info->UniqueID = strtol(tok,NULL,16); + continue; + } + pch=strstr(file_line_buf,"Manufacturer"); + if(pch != NULL) + { + memset(test, '\0', 80); + strcpy(test,pch+strlen("Manufacturer")); + tok = strtok(test,"\"= \t"); + //printf("Manufacturer = %s\n",tok); + strcpy(Chip_Info->Manufacturer,tok); + continue; + } + pch=strstr(file_line_buf,"Voltage"); + if(pch != NULL) + { + memset(test, '\0', 80); + strcpy(test,pch+strlen("Voltage")); + tok = strtok(test,"\"= \t"); + //printf("Voltage = %s\n",tok); + if(strcmp(tok, "3.3V") == 0) + Chip_Info->VoltageInMv = 3300; + else if(strcmp(tok, "2.5V") == 0) + Chip_Info->VoltageInMv = 2500; + else if(strcmp(tok, "1.8V") == 0) + Chip_Info->VoltageInMv = 1800; + else + Chip_Info->VoltageInMv = 3300; + continue; + } + pch=strstr(file_line_buf,"JedecDeviceID"); + if(pch != NULL) + { + memset(test, '\0', 80); + strcpy(test,pch+strlen("JedecDeviceID")); + tok = strtok(test,"\"= \t"); + //printf("JedecDeviceID = 0x%lx\n",strtol(tok,NULL,16)); + Chip_Info->JedecDeviceID = strtol(tok,NULL,16); + continue; + } + pch=strstr(file_line_buf,"ChipSizeInKByte"); + if(pch != NULL ) + { + memset(test, '\0', 80); + strcpy(test,pch+strlen("ChipSizeInKByte")); + tok = strtok(test,"\"= \t"); + //printf("ChipSizeInKByte = %ld\n",strtol(tok,NULL,10)); + Chip_Info->ChipSizeInByte = strtol(tok,NULL,10)*1024; + continue; + } + pch=strstr(file_line_buf,"SectorSizeInByte"); + if(pch != NULL ) + { + memset(test, '\0', 80); + strcpy(test,pch+strlen("SectorSizeInByte")); + tok = strtok(test,"\"= \t"); + //printf("SectorSizeInByte = %ld\n",strtol(tok,NULL,10)); + Chip_Info->SectorSizeInByte = strtol(tok,NULL,10); + continue; + } + pch=strstr(file_line_buf,"BlockSizeInByte"); + if(pch != NULL ) + { + memset(test, '\0', 80); + strcpy(test,pch+strlen("BlockSizeInByte")); + tok = strtok(test,"\"= \t"); + //printf("BlockSizeInByte = %ld\n",strtol(tok,NULL,10)); + Chip_Info->BlockSizeInByte = strtol(tok,NULL,10); + continue; + } + pch=strstr(file_line_buf,"PageSizeInByte"); + if(pch != NULL ) + { + memset(test, '\0', 80); + strcpy(test,pch+strlen("PageSizeInByte")); + tok = strtok(test,"\"= \t"); + //printf("PageSizeInByte = %ld\n",strtol(tok,NULL,10)); + Chip_Info->PageSizeInByte = strtol(tok,NULL,10); + continue; + } + pch=strstr(file_line_buf,"AddrWidth"); + if(pch != NULL ) + { + memset(test, '\0', 80); + strcpy(test,pch+strlen("AddrWidth")); + tok = strtok(test,"\"= \t"); + //printf("AddrWidth = %ld\n",strtol(tok,NULL,10)); + Chip_Info->AddrWidth = strtol(tok,NULL,10); + continue; + } + pch=strstr(file_line_buf,"IDNumber"); + if(pch != NULL ) + { + memset(test, '\0', 80); + strcpy(test,pch+strlen("IDNumber")); + tok = strtok(test,"\"= \t"); + //printf("IDNumber = %ld\n",strtol(tok,NULL,10)); + Chip_Info->IDNumber = strtol(tok,NULL,10); + continue; + } + pch=strstr(file_line_buf,"VppSupport"); + if(pch != NULL ) + { + memset(test, '\0', 80); + strcpy(test,pch+strlen("VppSupport")); + tok = strtok(test,"\"= \t"); + //printf("IDNumber = %ld\n",strtol(tok,NULL,10)); + Chip_Info->VppSupport = strtol(tok,NULL,10); + continue; + } + pch=strstr(file_line_buf,"RDIDCommand"); + if(pch != NULL ) + { + memset(test, '\0', 80); + strcpy(test,pch+strlen("RDIDCommand")); + tok = strtok(test,"\"= \t"); + Chip_Info->RDIDCommand = strtol(tok,NULL,16); + continue; + } + pch=strstr(file_line_buf,"Timeout"); + if(pch != NULL ) + { + memset(test, '\0', 80); + strcpy(test,pch+strlen("Timeout")); + tok = strtok(test,"\"= \t"); + Chip_Info->Timeout= strtol(tok,NULL,16); + continue; + } + pch=strstr(file_line_buf,"MXIC_WPmode"); + if(pch != NULL ) + { + memset(test, '\0', 80); + strcpy(test,pch+strlen("MXIC_WPmode")); + tok = strtok(test,"\"= \t"); + if(strstr(tok,"true") != NULL) + Chip_Info->MXIC_WPmode=true; + else + Chip_Info->MXIC_WPmode=false; + //starting checking input data + continue; + } +#if 0 + + pch=strstr(file_line_buf,"ManufactureUrl="); + if(pch != NULL) { + memset(test, '\0', 80); + strcpy(test,pch+strlen("ManufactureUrl=")); + tok = strtok(test,"\""); + //printf("ManufactureUrl = %s\n",tok); + strcpy(Chip_Info->ManufactureUrl,tok); + } + pch=strstr(file_line_buf,"Description="); + if( pch != NULL) { + memset(test, '\0', 80); + strcpy(test,pch+strlen("Description=")); + tok = strtok(test,"\""); + //printf("Description = %s\n",tok); + strcpy(Chip_Info->Description,tok); + } + pch=strstr(file_line_buf,"Clock="); + if(pch != NULL) { + memset(test, '\0', 80); + strcpy(test,pch+strlen("Clock=")); + tok = strtok(test,"\""); + //printf("Clock = %s\n",tok); + Chip_Info->Clock[0] = '\0'; + } + + pch=strstr(file_line_buf,"ManufactureID="); + if(pch != NULL) { + memset(test, '\0', 80); + strcpy(test,pch+strlen("ManufactureID=")); + tok = strtok(test,"\""); + //printf("ManufactureID = 0x%lx\n",strtol(tok,NULL,16)); + Chip_Info->ManufactureID = strtol(tok,NULL,16); + } + + pch=strstr(file_line_buf,"DeviceID="); + if(pch != NULL) { + memset(test, '\0', 80); + strcpy(test,pch+strlen("DeviceID=")); + tok = strtok(test,"\""); + //printf("DeviceID = 0x%lx\n",strtol(tok,NULL,16)); + Chip_Info->AlternativeID= strtol(tok,NULL,16); + } +#endif + }/*Continue until EOF is encoutered*/ + fclose(fp); /*Close file*/ + Chip_Info->MaxErasableSegmentInByte = max(Chip_Info->SectorSizeInByte, Chip_Info->BlockSizeInByte); + if(found_flag==0) + { + Chip_Info->TypeName[0]=0; + Chip_Info->UniqueID=0; + } + free(file_buf); + return found_flag; /*Executed without errors*/ +}/*End main*/ + +void Dedi_List_AllChip() +{ + FILE* fp; /*Declare file pointer variable*/ + char file_line_buf[linebufsize], *tok, fname[15], *file_buf, test[100];; + char* pch; + char TypeName[100],Manufacturer[100]; + long sz=0; + char Path[512]; + getExecPath(Path); + + /*If file doesn't exist or filetype isn't allowed exit and*/ + /*error message & return (1) control to the OS*/ + if ((fp = fopen(Path,"rt")) == NULL){ + fprintf(stderr,"Error opening file: %s\n",fname); + return 1; + } + sz=fsize(fp); + file_buf=(char*)malloc(sz); + memset(file_buf, '\0', sz); + /*Read into the buffer contents within thr file stream*/ + while(fgets(file_line_buf, linebufsize, fp) != NULL) + { + pch=strstr(file_line_buf,"TypeName"); + if(pch!= NULL) + { + memset(test, '\0', 100); + strcpy(test,pch+strlen("TypeName")); + tok = strtok(test,"\"= \t"); + // end of struct init + TypeName[0]='\0'; + Manufacturer[0]='\0'; + strcpy(TypeName,tok); + continue; + } + pch=strstr(file_line_buf,"Manufacturer"); + if(pch != NULL) + { + memset(test, '\0', 100); + strcpy(test,pch+strlen("Manufacturer")); + tok = strtok(test,"\"= \t"); + //printf("Manufacturer = %s\n",tok); + strcpy(Manufacturer,tok); + if(TypeName[0] != '\0' && Manufacturer[0] != '\0') + printf("%s\t\tby %s\r\n",TypeName,Manufacturer); + } + }/*Continue until EOF is encoutered*/ + fclose(fp); /*Close file*/ +}/*End main*/ + + +/***********************PARSE.TXT (CONTENT)**********************/ +/* "Move each word to the next line" */ +/***********************PARSE.EXE (OUTPUT)***********************/ +/* C:\>parse */ +/* Enter filename: parse.txt */ +/* */ +/* Move */ +/* each */ +/* word */ +/* to */ +/* the */ +/* next */ +/* line. */ +/* */ +/* Press any key to continue . . . */ +/****************************************************************/ diff --git a/project.c b/project.c new file mode 100644 index 0000000..a4043f8 --- /dev/null +++ b/project.c @@ -0,0 +1,1384 @@ +#include "Macro.h" +#include "project.h" +#include "IntelHexFile.h" +#include "MotorolaFile.h" +#include "dpcmd.h" +#include "SerialFlash.h" +#include +#include +#include +#define min(a,b) (a>b? b:a) + +unsigned char* pBufferForLastReadData=NULL; +unsigned char* pBufferforLoadedFile=NULL; +unsigned long g_ulFileSize=0; +unsigned int g_uiFileChecksum=0; +unsigned char g_BatchIndex=2; +extern unsigned int g_ucFill; +extern m_boEnReadQuadIO; +extern m_boEnWriteQuadIO; +extern volatile bool g_bIsSF600; +extern char g_board_type[8]; +extern int g_firmversion; +extern char* g_parameter_vcc; + +//extern bool S19FileToBin(const char* filePath, unsigned char* vData,unsigned long* FileSize, unsigned char PaddingByte); +//extern bool HexFileToBin(const char* filePath, unsigned char* vOutData,unsigned long* FileSize,unsigned char PaddingByte); +extern unsigned char mcode_WRSR; +extern unsigned char mcode_WRDI; +extern unsigned char mcode_RDSR; +extern unsigned char mcode_WREN; +extern unsigned char mcode_SegmentErase; +extern unsigned char mcode_ChipErase; +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 int g_StartupMode; +extern int g_CurrentSeriase; +extern struct CAddressRange DownloadAddrRange; +extern struct CAddressRange UploadAddrRange; +extern bool g_is_operation_on_going; +extern bool g_is_operation_successful; +extern unsigned int g_Vcc; +extern unsigned int g_Vpp; +extern unsigned int g_uiAddr; +extern unsigned int g_uiLen; +extern bool g_bEnableVpp; +#define FIRMWARE_VERSION(x,y,z) ((x<<16) | (y<<8) | z) + +enum FILE_FORMAT{ + BIN , + HEX, + S19, + } ; + +void Sleep(unsigned int mSec) +{ + usleep(mSec*1000); +} + +void TurnONVpp(void) +{ + if(g_bEnableVpp==true) + dediprog_set_vpp_voltage(Chip_Info.VppSupport); +} + +void TurnOFFVpp(void) +{ + if(g_bEnableVpp==true) + dediprog_set_vpp_voltage(0); +} + +void TurnONVcc(int Index) +{ +// printf("g_Vcc=%x\n",g_Vcc); + dediprog_set_spi_voltage(g_Vcc,Index); +} + +void TurnOFFVcc(int Index) +{ + dediprog_set_spi_voltage(0,Index); +} + + +unsigned int CRC32(unsigned char* v, unsigned long size) +{ + unsigned int checksum = 0; + unsigned long i; + for(i=0;i Chip_Info.ChipSizeInByte - 1) + return false; + + size_t size = DownloadAddrRange.length; + if(size > g_ulFileSize && g_ucFill==0xFF) + return false; + + if(DownloadAddrRange.end > Chip_Info.ChipSizeInByte) + return false; + + return true; +} + +bool ProgramChip(int Index) +{ + bool need_padding = (g_ucFill != 0xFF); + unsigned char* vc; + struct CAddressRange real_addr; + real_addr.start=(DownloadAddrRange.start &(~(0x200 - 1))); + real_addr.end=((DownloadAddrRange.end + (0x200 - 1)) & (~(0x200 - 1))); + real_addr.length=real_addr.end-real_addr.start; + + vc=(unsigned char*)malloc(real_addr.length); + memset(vc,g_ucFill,real_addr.length); + + if(need_padding==true) + { + memcpy(vc+(DownloadAddrRange.start & 0x1FF),pBufferforLoadedFile,min(g_ulFileSize,DownloadAddrRange.length)); + } + else + { + memcpy(vc+(DownloadAddrRange.start & 0x1FF),pBufferforLoadedFile,DownloadAddrRange.length); + } + + bool result= SerialFlash_rangeProgram(&real_addr, vc,Index); + + return result; + +} + +bool ReadChip(const struct CAddressRange range,int Index) +{ + bool result = true; + unsigned char* vc; + size_t addrStart = range.start; + size_t addrLeng = range.length; + struct CAddressRange addr; + addr.start= range.start &(~(0x200 - 1)); + addr.end=(range.end + (0x200 - 1)) & (~(0x200 - 1)); + addr.length=addr.end-addr.start; + vc=(unsigned char*)malloc(addr.length); + + result = SerialFlash_rangeRead(&addr, vc, Index); + + if(result) + { + if(pBufferForLastReadData != NULL) + free(pBufferForLastReadData); + + unsigned int offset = (addrStart & 0x1FF); + pBufferForLastReadData=(unsigned char*)malloc(range.length); + memcpy(pBufferForLastReadData,vc+offset,range.length); + UploadAddrRange=range; + } + + if(vc != NULL) + free (vc); + + return result; + +} + +bool threadBlankCheck(int Index) +{ + bool result = false; +// bool is_greater_than_5_0_0 = is_BoardVersionGreaterThan_5_0_0(Index); + struct CAddressRange Addr; + Addr.start=0; + Addr.end=Chip_Info.ChipSizeInByte; + + //(L"Blank Checking ..."); + +// if(is_greater_than_5_0_0) +// SetLEDOnOff(SITE_BUSY,Index); + + SetIOMode(false,Index); + + + result = SerialFlash_rangeBlankCheck(&Addr,Index) ; + +// m_bOperationResult[Index]=result? 1:RES_BLANK; +#if 0 + if( !bAuto[Index] ) + { + + m_context.runtime.elapsed_time_of_last_operation = timer.elapsed() ; + Log(wformat(L"Operation completed. \n%1% seconds elapsed.")%m_context.runtime.elapsed_time_of_last_operation); + + CompleteCnt++; + + if( CompleteCnt==GetDevNum() ) + { + m_context.runtime.is_operation_on_going = false; + m_chip[Index]->ClearCancelOperationFlag(); + } + + if(is_greater_than_5_0_0) + m_board->SetLEDOnOff(result? SITE_OK:SITE_ERROR,Index); + } +#endif +// SetLEDOnOff(result? SITE_OK:SITE_ERROR,Index); +// g_is_operation_on_going = false; + g_is_operation_successful = result; + return result; +} + +bool threadEraseWholeChip(int Index) +{ + bool result = false; +// bool is_greater_than_5_0_0 = is_BoardVersionGreaterThan_5_0_0(Index); + +// if(is_greater_than_5_0_0) +// SetLEDOnOff(SITE_BUSY,Index); + +// Log(L"Erasing a whole chip ..."); + +// power::CAutoVccPower autopowerVcc(m_usb, m_context.power.vcc,Index); +// power::CAutoVppPower autopowerVpp(m_usb, SupportedVpp(),Index); + result = SerialFlash_chipErase(Index); + +// Log(result ? L"A whole chip erased" : L"Error: Failed to erase a whole chip"); + +// m_bOperationResult[Index]=result? 1:RES_ERASE; +#if 0 + if( !bAuto[Index] ) + { + m_context.runtime.is_operation_successful = result; + m_context.runtime.elapsed_time_of_last_operation = timer.elapsed() ; + Log(wformat(L"Operation completed. \n%1% seconds elapsed.")%m_context.runtime.elapsed_time_of_last_operation); + + CompleteCnt++; + + if( CompleteCnt==GetDevNum() ) + { + m_context.runtime.is_operation_on_going = false; + m_chip[Index]->ClearCancelOperationFlag(); + } + + if(is_greater_than_5_0_0) + m_board->SetLEDOnOff(result? SITE_OK:SITE_ERROR,Index); + } +#endif +// SetLEDOnOff(result? SITE_OK:SITE_ERROR,Index); + g_is_operation_successful = result; +// g_is_operation_on_going = false; + return result; +} + +bool threadReadRangeChip(struct CAddressRange range,int Index) +{ + bool result = true; +// bool is_greater_than_5_0_0 = is_BoardVersionGreaterThan_5_0_0(Index); + struct CAddressRange AddrRound; + +// if(is_greater_than_5_0_0) +// SetLEDOnOff(SITE_BUSY,Index); + + SetIOMode(false,Index); + + AddrRound.start= (range.start &(~(0x1FF))); + AddrRound.end=((range.end +0x1FF) & (~(0x1FF))); + AddrRound.length=AddrRound.end-AddrRound.start; + unsigned char *pBuffer = malloc(AddrRound.length); + + if(pBufferForLastReadData==NULL) + pBufferForLastReadData=malloc(range.end-range.start); + else + { + free(pBufferForLastReadData); + pBufferForLastReadData=malloc(range.end-range.start); + } + if(pBufferForLastReadData==NULL) + { + printf("allocate memory fail.\n"); + free(pBuffer); + return false; + } + + result = SerialFlash_rangeRead(&AddrRound, pBuffer, Index); + if(result) + { + UploadAddrRange.start = range.start; + UploadAddrRange.end= range.end; + UploadAddrRange.length = range.end-range.start; + memcpy(pBufferForLastReadData,pBuffer+ (UploadAddrRange.start & 0x1FF),UploadAddrRange.length); + } + free(pBuffer); + +// if(is_greater_than_5_0_0) +// SetLEDOnOff(result? SITE_OK:SITE_ERROR,Index); + + return result; + +} + +bool threadReadChip(int Index) +{ + bool result = false; + bool is_greater_than_5_0_0 = is_BoardVersionGreaterThan_5_0_0(Index); + struct CAddressRange Addr; + Addr.start=0; + Addr.end=Chip_Info.ChipSizeInByte; + +// if(is_greater_than_5_0_0) +// SetLEDOnOff(SITE_BUSY,Index); + + SetIOMode(false,Index); + + if(pBufferForLastReadData==NULL) + pBufferForLastReadData=(unsigned char*)malloc(Chip_Info.ChipSizeInByte); + else + { + free(pBufferForLastReadData); + pBufferForLastReadData=(unsigned char*)malloc(Chip_Info.ChipSizeInByte); + } + if(pBufferForLastReadData==NULL) + { + printf("allocate memory fail.\n"); + return false; + } + + result = SerialFlash_rangeRead(&Addr, pBufferForLastReadData,Index); + + if(result) + { + UploadAddrRange.start = 0; + UploadAddrRange.end=Chip_Info.ChipSizeInByte; + UploadAddrRange.length=Chip_Info.ChipSizeInByte; + } + +// if(is_greater_than_5_0_0) +// SetLEDOnOff(result?SITE_OK:SITE_ERROR,Index); + + g_is_operation_successful = result; + + return result; +} +bool threadConfiguredReadChip(int Index) +{ + bool result = true; + struct CAddressRange addr; + addr.start= DownloadAddrRange.start; + addr.length= DownloadAddrRange.end-DownloadAddrRange.start; + + + if(0 == addr.length && Chip_Info.ChipSizeInByte > addr.start) + addr.length = Chip_Info.ChipSizeInByte - addr.start; + + addr.end=addr.length+addr.start; + if(addr.start >= Chip_Info.ChipSizeInByte) + { + result = false; + } + else if(0 == addr.start && (0 == addr.length)) + { + result = threadReadChip(Index); + } + else + { + result = threadReadRangeChip(addr,Index); + } + + g_is_operation_successful = result; +// g_is_operation_on_going = false; + return result; +} + +bool threadProgram(int Index) +{ + bool result = true; + SetIOMode(true,Index); + + + if(g_ulFileSize== 0) + { + result = false; + } + + if( result && (!ValidateProgramParameters(Index)) ) + { + result = false; + } + + if( result && ProgramChip(Index)) + { + result = true; + } + else + { + result = false; + } + +// if(is_greater_than_5_0_0) +// SetLEDOnOff(result? SITE_OK:SITE_ERROR,Index); + g_is_operation_successful = result; + return result; +} + +bool threadCompareFileAndChip(int Index) +{ + bool result = true; +// bool is_greater_than_5_0_0 = is_BoardVersionGreaterThan_5_0_0(Index); + +// if(is_greater_than_5_0_0) +// SetLEDOnOff(SITE_BUSY,Index); + + SetIOMode(false,Index); + + if(g_ulFileSize==0) + result = false; + + if( result && (!ValidateProgramParameters(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,offset); + unsigned int i=0; + #if 0 + for(i=0; i<10; i++) + { + if(pBufferforLoadedFile[i] != pBufferForLastReadData[i]) + printf("Data deferent at %X, pBufferforLoadedFile[i]=%x,pBufferForLastReadData[i]=%x\r\n",i,pBufferforLoadedFile[i],pBufferForLastReadData[i]); + } + #endif + + result = (crcChip == crcFile); + } + +// if(is_greater_than_5_0_0) +// SetLEDOnOff(result? SITE_OK:SITE_ERROR,Index); + + g_is_operation_successful = result; + return result; +} + +size_t GenerateDiff(size_t* Addr,unsigned char* in1, unsigned long long size1, unsigned char* in2, unsigned long long size2, size_t baseAddr, size_t step) +{ + size_t upper = min(size1, size2); + size_t realAddr,i,j=0; + + for(i = 0; i < upper; ++i) + { + if(in1[i] != in2[i]) + { + realAddr = i + baseAddr; + Addr[j++]=(realAddr & (~(step - 1))); + + i += ((step - 1)|realAddr) - realAddr; + if(i >= upper) break; + } + } + return j; +} + +size_t Condense(size_t* out,unsigned char* vc, size_t* addrs, size_t addrSize, size_t baseAddr, size_t step) +{ + size_t* itr, itr_end; + size_t i,j,outSize=0; + itr_end=addrs+addrSize; + + for(j=0; j (1<<16)); + + return ((mcode_SegmentErase!=0) && fast_load) + ? RangeUpdateThruSectorErase(Index) + : RangeUpdateThruChipErase(Index); +} +bool ReplaceChipContentThruChipErase(int Index) +{ + if(!threadBlankCheck(Index))//not blank + { + if(!threadEraseWholeChip(Index)) + return false; + } + + return threadProgram(Index); +} + +bool threadPredefinedBatchSequences(int Index) +{ + bool result = true; + + if(g_ulFileSize==0) result = false; + + size_t option=2; + bool bVerifyAfterCompletion; + // 07.11.2009 + bool bIdentifyBeforeOperation; + + if( result && (!ValidateProgramParameters(Index)) ) result = false; +#if 0 + if(strstr(Chip_Info.Class,SUPPORT_MACRONIX_MX25Lxxx)!= NULL + ||strstr(Chip_Info.Class,SUPPORT_MACRONIX_MX25Lxxx_Large) != NULL + ||strstr(Chip_Info.Class,SUPPORT_MACRONIX_MX25Lxxx_PP32)!=NULL) + Sleep(10); +#endif + + if( result ) + { + switch(g_BatchIndex) + { + case 1: + result=ReplaceChipContentThruChipErase(Index); + break; + case 2: + default: + result = RangeUpdate(Index); + break; + } + } + + return result; +} + +void threadRun(void* Type) +{ + THREAD_STRUCT* thread_data=(THREAD_STRUCT*)Type; + OPERATION_TYPE opType=thread_data->type; + int Index=thread_data->USBIndex; + g_is_operation_successful = true; + + g_is_operation_on_going = true; + + if( opType==UPDATE_FIRMWARE ) + { + return; + } + if(opType==AUTO_UPDATE_FIRMWARE) + { + return; + } + + if(1)//is_good()) + { + TurnONVcc(Index); + bool is_greater_than_5_0_0 = is_BoardVersionGreaterThan_5_0_0(Index); + + if(is_greater_than_5_0_0) + SetLEDOnOff(SITE_BUSY,Index); + + if(IdentifyChipBeforeOperation(Index)==false) + { + printf("Warning: Failed to detect flash.\r\n"); + g_is_operation_on_going = false; + g_is_operation_successful = false; + SetLEDOnOff(g_is_operation_successful? SITE_OK:SITE_ERROR,Index); + TurnOFFVcc(Index); + + return; + } + // operations + switch(opType) + { + case BLANKCHECK_WHOLE_CHIP: + threadBlankCheck(Index); + break; + + case ERASE_WHOLE_CHIP: + threadEraseWholeChip(Index); + break; + + case PROGRAM_CHIP: + TurnONVpp(); + threadProgram(Index); + break; + + case READ_WHOLE_CHIP: +// m threadReadChip(Index); + break; + + case READ_ANY_BY_PREFERENCE_CONFIGURATION: + threadConfiguredReadChip(Index); + break; + + case VERIFY_CONTENT: + threadCompareFileAndChip(Index); + break; + + case AUTO: + TurnONVpp(); + threadPredefinedBatchSequences(Index) ; + break; + + default: + break; + } + } + TurnOFFVcc(Index); + TurnOFFVpp(); + SetLEDOnOff(g_is_operation_successful? SITE_OK:SITE_ERROR,Index); + g_is_operation_on_going = false; +} + + +void Run(OPERATION_TYPE type) +{ + pthread_t id; + int i,ret; + g_is_operation_on_going = true; + THREAD_STRUCT thread_data; + thread_data.type=type; + thread_data.USBIndex=0; + ret=pthread_create(&id,NULL,(void *) threadRun,(void*)&thread_data); + +} + +void SetIOMode(bool isProg,int Index) +{ + size_t IOValue=0; + m_boEnReadQuadIO=0; + m_boEnWriteQuadIO=0; + + if(g_bIsSF600==false) return; + + SetIOModeToSF600(IOValue, Index); + return; +// if(strlen(Chip_Info.ProgramIOMethod)==0) +// { +// SetIOModeToSF600(IOValue, Index); +// return; +// } + +#if 0 + if(isProg) + { + switch(m_context.chip.IO_Mode) + { + case Context::CChipContext::IO_Single: + default: + if(out[1].find(L"SW")!=-1) + IOValue=0; + break; + case Context::CChipContext::IO_Dual1: + case Context::CChipContext::IO_Dual2: + if((out[0]==L"SPDD" || out[0]==L"SPQD") && out[1].find(L"DW")!=-1) + IOValue = 1; + else if((out[0]==L"DPDD" || out[0]==L"QPQD") && out[1].find(L"DW")!=-1) + IOValue = 2; + break; + case Context::CChipContext::IO_Quad1: + case Context::CChipContext::IO_Quad2: + if(out[0]==L"SPDD" && out[1].find(L"DW")!=-1) + IOValue = 1; + else if(out[0]==L"DPDD" && out[1].find(L"DW")!=-1) + IOValue = 2; + else if(out[0]==L"SPQD" && out[1].find(L"QW")!=-1) + IOValue = 3; + else if(out[0]==L"QPQD" && out[1].find(L"QW")!=-1) + IOValue = 4; + break; + } + } + else + { + switch(m_context.chip.IO_Mode) + { + case Context::CChipContext::IO_Single: + default: + break; + case Context::CChipContext::IO_Dual1: + case Context::CChipContext::IO_Dual2: + if(out[0]==L"SPDD" || out[0]==L"SPQD") + IOValue = 1; + else if(out[0]==L"DPDD" || out[0]==L"QPQD") + IOValue = 2; + break; + case Context::CChipContext::IO_Quad1: + case Context::CChipContext::IO_Quad2: + if(out[0]==L"SPDD") + IOValue = 1; + else if(out[0]==L"DPDD") + IOValue = 2; + else if(out[0]==L"SPQD") + IOValue = 3; + else if(out[0]==L"QPQD") + IOValue = 4; + break; + } + } + + if((m_context.StartupMode[Index]==Context::STARTUP_APPLI_SF_SKT) && (IOValue>=3)) + { + IOValue-=2; + Log(L"Warning: Socket mode can not support Quad IO."); + } + + switch(IOValue) + { + case 0: + Log(L"Single IO is set."); + break; + case 1: + case 2: + Log(L"Dual IO is set."); + break; + case 3: + case 4: + Log(L"Quad IO is set."); + if( m_chip[Index] ) + { + m_chip[Index]->m_boEnReadQuadIO=(out[1].find(L'R')!=-1);//true; + m_chip[Index]->m_boEnWriteQuadIO=(out[1].find(L'W')!=-1); + } + break; + } + + m_board->SetIOMode(IOValue, Index); + SetProgramReadCom(IOValue,Index); +#endif +} + +int is_BoardVersionGreaterThan_5_0_0(int Inde) +{ + if(g_firmversion < FIRMWARE_VERSION(5, 0, 0)) + return false; + return true; +} + +int is_SF100nBoardVersionGreaterThan_5_5_0(int Inde) +{ + if((g_firmversion >= FIRMWARE_VERSION(5, 5, 0)) && strstr(g_board_type,"SF100") != NULL) + return true; + return false; +} + +int is_SF600nBoardVersionGreaterThan_6_9_0(int Inde) +{ + if(strstr(g_board_type,"SF600") != NULL) + { + if((g_firmversion > FIRMWARE_VERSION(7, 0, 1)) || (g_firmversion == FIRMWARE_VERSION(6, 9, 0))) + return true; + } + return false; +} + +CHIP_INFO GetFirstDetectionMatch(int Index) +{ + CHIP_INFO binfo; + binfo.UniqueID=0; + int Found=0; + int i=0; + int Loop=3; + if(strcmp(g_parameter_vcc,"NO") != 0) + Loop=1; + + for(i=0; i +#include +#include +#include "Macro.h" +#include "usbdriver.h" + +unsigned int m_nbDeviceDetected = 0; +unsigned char DevIndex = 0; +extern volatile bool g_bIsSF600; +extern int g_CurrentSeriase; +extern char g_board_type[8]; +extern int g_firmversion; +extern Sleep(unsigned int ms); +extern CHIP_INFO Chip_Info; +#define SerialFlash_FALSE -1 +#define SerialFlash_TRUE 1 +extern int is_SF100nBoardVersionGreaterThan_5_5_0(int Inde); + +bool Is_NewUSBCommand(int Index) +{ + if(is_SF100nBoardVersionGreaterThan_5_5_0(Index) || is_SF600nBoardVersionGreaterThan_6_9_0(Index)) + return true; + return false; +} +extern unsigned char GetFPGAVersion(int Index); + +void usb_dev_init(void) +{ + usb_init(); + usb_find_busses(); + usb_find_devices(); +} + +void usb_db_init(void) +{ + int i; + for(i=0; inext) + { + for (dev = bus->devices; dev; dev = dev->next) + { + if ((dev->descriptor.idVendor == vid) && (dev->descriptor.idProduct == pid)) + { + usb_device_entry[dev_index].usb_device_handler = *dev; + usb_device_entry[dev_index].valid = 1; + dev_index++; + break; + } + } + } + return dev_index; +} + + +int OutCtrlRequest( CNTRPIPE_RQ *rq, unsigned char *buf, unsigned long buf_size ,int Index ) +{ + unsigned long bytesWrite; + int requesttype; + int ret = 0; + + if( Index==-1 ) + Index = DevIndex; + + if( (rq->Function!=URB_FUNCTION_VENDOR_ENDPOINT) && (g_bIsSF600==true)) return true; + + requesttype = 0x00; + + if( rq->Direction==VENDOR_DIRECTION_IN ) requesttype |= 0x80; + if( rq->Function==URB_FUNCTION_VENDOR_DEVICE ) requesttype |= 0x40; + if( rq->Function==URB_FUNCTION_VENDOR_INTERFACE ) requesttype |= 0x41; + if( rq->Function==URB_FUNCTION_VENDOR_ENDPOINT ) requesttype |= 0x42; + if( rq->Function==URB_FUNCTION_VENDOR_OTHER ) requesttype |= 0x43; + + + if (dediprog_handle ) { + ret = usb_control_msg(dediprog_handle, requesttype, rq->Request, rq->Value, rq->Index, buf, buf_size, DEFAULT_TIMEOUT); + }// else + // printf("no device"); + if(ret != buf_size) + { + #if 0 + printf("Control Pipe output error!\n"); + printf("rq->Direction=%X\n",rq->Direction); + printf("rq->Function=%X\n",rq->Function); + printf("rq->Request=%X\n",rq->Request); + printf("rq->Value=%X\n",rq->Value); + printf("rq->Index=%X\n",rq->Index); + printf("rq->Length=%X\n",rq->Length); + printf("buf_size=%X\n",buf_size); + printf("buf[0]=%X\n",buf[0]); + printf("g_bIsSF600=%d\n",g_bIsSF600); + #endif + //printf("Error=0x%x\r\n",usb_strerror()); + return -1; + } + return ret; +} + + +int InCtrlRequest( CNTRPIPE_RQ *rq, unsigned char *buf, unsigned long buf_size, int Index ) +{ + //boost::mutex::scoped_lock l(mutex); + + unsigned long bytesRead; + int requesttype; + int ret = 0; + + if( (rq->Function!=URB_FUNCTION_VENDOR_ENDPOINT) && (g_bIsSF600==true)) return true; + if( Index==-1 ) + Index = DevIndex; + + if(sizeof(buf) == 0) + return 0; + + + requesttype = 0x00; + + if( rq->Direction==VENDOR_DIRECTION_IN ) requesttype |= 0x80; + if( rq->Function==URB_FUNCTION_VENDOR_DEVICE ) requesttype |= 0x40; + if( rq->Function==URB_FUNCTION_VENDOR_INTERFACE ) requesttype |= 0x41; + if( rq->Function==URB_FUNCTION_VENDOR_ENDPOINT ) requesttype |= 0x42; + if( rq->Function==URB_FUNCTION_VENDOR_OTHER ) requesttype |= 0x43; + + if (dediprog_handle ) { + ret = usb_control_msg(dediprog_handle, requesttype, rq->Request, rq->Value, rq->Index, buf, buf_size, DEFAULT_TIMEOUT); + }// else + // printf("no device"); + + if(ret != buf_size) + { +// printf("Control Pipe input error!\n"); + return -1; + } + + return ret; +} + + +// part of USB driver , open usb pipes for data transfor +// should be called after usb successfully opens pipes. +int dediprog_start_appli(int Index) +{ + //IsSF600(Index); + CNTRPIPE_RQ rq ; + int ret; + unsigned char vInstruction; + + // special instruction + vInstruction = 0 ; + + rq.Function = URB_FUNCTION_VENDOR_OTHER ; + rq.Direction = VENDOR_DIRECTION_IN ; + rq.Request = 0xb ; + rq.Value = 0x00 ; + rq.Index = 0x00 ; + rq.Length = 0x01 ; + + ret = OutCtrlRequest(&rq, &vInstruction, 1, 0); + + return 0; +} + +int dediprog_get_chipid(int Index) +{ + //IsSF600(Index); + CNTRPIPE_RQ rq ; + int ret; + unsigned char vInstruction[3]; + + memset(vInstruction, 0, 3); + rq.Function = URB_FUNCTION_VENDOR_ENDPOINT ; + rq.Direction = VENDOR_DIRECTION_OUT ; + rq.Request = 0x1 ; + rq.Value = 0xff ; + if(Is_NewUSBCommand(Index)) + rq.Index = 0 ; + else + rq.Index = 0x1 ; + + rq.Length = 0x1 ; + + vInstruction[0]= 0x9f; + + ret = OutCtrlRequest(&rq, vInstruction, 1, Index); + + + // special instruction + memset(vInstruction, 0, 3); + + rq.Function = URB_FUNCTION_VENDOR_ENDPOINT ; + rq.Direction = VENDOR_DIRECTION_IN ; + rq.Request = 0x1 ; + rq.Value = 0x0 ; + rq.Index = 0x00 ; + rq.Length = 0x03 ; + + ret = InCtrlRequest(&rq, vInstruction, 3, Index); + return 0; +} + +// return size read +// if fail , return -1 +//long CUSB::BulkPipeRead(PBYTE pBuff, UINT sz, UINT timeOut) const +int BulkPipeRead(unsigned char *pBuff, unsigned int timeOut, int Index) +{ + int ret; + if( Index==-1 ) Index = DevIndex; + + unsigned long cnRead = 512; + ret = usb_bulk_read(dediprog_handle, 0x82, pBuff, cnRead, DEFAULT_TIMEOUT); + cnRead = ret; + return cnRead ; +} + + +//long CUSB::BulkPipeWrite(PBYTE pBuff, UINT sz, UINT timeOut) const +int BulkPipeWrite(unsigned char *pBuff, unsigned int size,unsigned int timeOut, int Index) +{ + int ret; + int nWrite = 512 ; + char pData[512]; + + memset(pData, 0xFF, 512); // fill buffer with 0xFF + + memcpy(pData, pBuff , size); + + if( Index==-1 ) Index = DevIndex; + + ret = usb_bulk_write(dediprog_handle, (g_bIsSF600==true)? 0x01:0x02,pData, nWrite, DEFAULT_TIMEOUT); + nWrite = ret; + return nWrite; +} + + +int dediprog_set_spi_voltage(int v,int Index) +{ + int ret; + int voltage_selector; + CNTRPIPE_RQ rq ; + unsigned char vBuffer[12]; + + if(0 == v) Sleep(200); + + rq.Function = URB_FUNCTION_VENDOR_ENDPOINT ; + rq.Direction = VENDOR_DIRECTION_OUT ; + rq.Request = SET_VCC ; + rq.Length = 0 ; + + if(Is_NewUSBCommand(Index)) + { +// if(g_bIsSF600==true && (strstr(Chip_Info.Class,SUPPORT_ATMEL_45DBxxxB) != NULL || strstr(Chip_Info.Class,SUPPORT_ATMEL_45DBxxxD) != NULL)) +// v |= 0x8000; +// printf("v==%x\n",v); + rq.Value = v ; + rq.Index = 0; + } + else + { + rq.Value = v ; + rq.Index = 0x04 | g_CurrentSeriase; // ID detect mode + } + ret = OutCtrlRequest(&rq, NULL, 0, Index); +// printf("ret=%x\r\n",ret); + #if 0 + if(g_bIsSF600==true && v!=0) + { + unsigned char Vol[36]={ + 0xD0,0x07,0x00,0x00,0x10,0x0E,0x00,0x00,0x10,0x0E,0x00,0x00,// VccL=2700mV, VccP=3600mV, VccBuffer=3600mV + 0xD0,0x07,0x00,0x00,0x8C,0x0A,0x00,0x00,0x8C,0x0A,0x00,0x00,// VccL=2000mV, VccP=2700mV, VccBuffer=2700mV + 0xB0,0x04,0x00,0x00,0xD0,0x07,0x00,0x00,0xD0,0x07,0x00,0x00// VccL=1200mV, VccP=2000mV, VccBuffer=2000mV + }; + rq.Index = 0x04 | g_CurrentSeriase; // ID detect mode + rq.Length = 12 ; + if(v>=1800 && v<4500) + { + unsigned char vol[12]={ + ((float)v*0.8),(unsigned int)((float)v*0.8)>>8,(unsigned int)((float)v*0.8)>>16,(unsigned int)((float)v*0.8)>>24, + v, v>>8, v>>16, v>>24, + v, v>>8, v>>16, v>>24 + }; + int i=0; + for(i; i<12; i++) + vBuffer[i]=vol[i]; + } + else + { + int loop=(v & 0x03)*12; + int i=loop; + for(i; i<(loop+12) ;i++) + vBuffer[i-loop]=Vol[i]; + } + ret = OutCtrlRequest(&rq, vBuffer, 12, Index); + } + else + { + rq.Index = 0x00 ; + rq.Length = 0 ; + ret = OutCtrlRequest(&rq, NULL, 0, Index); + } + + if (ret != rq.Length) { + printf("Command Set SPI Voltage 0x%x failed!\n", voltage_selector); + return false; + } +#endif + if(0 != v) Sleep(200); + return true; +} + + +int dediprog_set_vpp_voltage(int volt) +{ + int ret; + int voltage_selector; + CNTRPIPE_RQ rq ; + + + switch (volt) { + case 0: + /* Admittedly this one is an assumption. */ + voltage_selector = 0x0; + break; + case 9: + voltage_selector = 0x1; + break; + case 12: + voltage_selector = 0x2; + break; + default: + return 1; + } + + rq.Function = URB_FUNCTION_VENDOR_ENDPOINT ; + rq.Direction = VENDOR_DIRECTION_OUT ; + rq.Request = 0x03 ; + rq.Value = voltage_selector ; + rq.Index = 0 ; + rq.Length = 0x0 ; + + ret = OutCtrlRequest(&rq, NULL, 0, 0); + + if (ret == SerialFlash_FALSE) { +// printf("Command Set VPP Voltage 0x%x failed!\n", voltage_selector); + return 1; + } + return 0; +} + +int dediprog_set_spi_clk(int khz) +{ + return 0; + int ret; + int hz_selector; + //IsSF600(Index); + CNTRPIPE_RQ rq ; + + + switch (khz) { + case 24000: + /* Admittedly this one is an assumption. */ + hz_selector = 0x0; + break; + case 8000: + hz_selector = 0x1; + break; + case 12000: + hz_selector = 0x2; + break; + case 3000: + hz_selector = 0x3; + break; + case 2180: + hz_selector = 0x4; + break; + case 1500: + hz_selector = 0x5; + break; + case 750: + hz_selector = 0x6; + break; + case 375: + hz_selector = 0x7; + break; + default: + printf("Unknown clk %i KHz! Aborting.\n", khz); + return 1; + } +// printf("Setting SPI clk to %u.%03u MHz\n", khz / 1000, +// khz % 1000); + + rq.Function = URB_FUNCTION_VENDOR_ENDPOINT ; + rq.Direction = VENDOR_DIRECTION_OUT ; + rq.Request = 0x61 ; + rq.Value = hz_selector ; + rq.Index = 0 ; + rq.Length = 0x0 ; + + ret = OutCtrlRequest(&rq, NULL, 0, 0); + + if (ret == SerialFlash_FALSE) { +// printf("Command Set SPI clk 0x%x failed!\n", hz_selector); + return 1; + } + return 0; +} + + +int usb_driver_init(void) +{ + struct usb_bus *bus; + struct usb_device *dev; + + int device_cnt = 0; + int ret; + dediprog_handle=NULL; + usb_dev_init(); + + device_cnt = FindUSBDevice(); + if(usb_device_entry[device_cnt-1].valid==0) + { + printf("Error: Programmers are not connected.\n"); + return 0; + } + + dediprog_handle = usb_open(&usb_device_entry[device_cnt-1].usb_device_handler); + if(dediprog_handle==NULL) + { + printf("Error: Programmers are not connected.\n"); + return 0; + } + ret = usb_set_configuration(dediprog_handle, 1); + ret = usb_claim_interface(dediprog_handle, 0); + g_bIsSF600=false; + + IsSF600(0); + dediprog_start_appli(0); + IsSF600(0); + + return ((dediprog_handle != NULL)? 1:0); +} + + +int usb_driver_release(void) +{ + if(dediprog_handle==NULL) return 0; + usb_release_interface(dediprog_handle, 0); + usb_close (dediprog_handle); + return 0; +} + + +#if 0 //Simon: unit test code +int usb_driver_test(void) +{ + struct usb_bus *bus; + struct usb_device *dev; + + unsigned int vid = 0x0483; + unsigned int pid = 0xdada; + int device_cnt = 0; + int ret, i; + char string[256]; + unsigned char readaddr[3]; + unsigned char writeaddr[3]; + usb_dev_handle *udev; + usb_dev_init(); + + device_cnt = FindUSBDevice(); +// printf("\ndevice_cnt =%d\n", device_cnt); + dediprog_handle = usb_open(&usb_device_entry[device_cnt-1].usb_device_handler); + ret = usb_set_configuration(dediprog_handle, 1); + ret = usb_claim_interface(dediprog_handle, 0); + dediprog_start_appli(0); + + dediprog_set_spi_voltage(3300); + + dediprog_get_chipid(0); + + dediprog_set_leds(PASS_ON | BUSY_ON | ERROR_ON); + usb_close (dediprog_handle); + + return 0; +} +#endif + + +bool Is_usbworking(void) +{ + usleep(1000); // unknow reson + return ((dediprog_handle != NULL)? true:false); +} +//long long flash_ReadId(boost::tuple command,int Index) +long flash_ReadId(unsigned int read_id_code, unsigned int out_data_size ,int Index) +{ + // read status +// if(! m_usb.is_open() ) +// return 0 ; + + // RDID is not decoded when in DP mode + // so , first release from Deep Power Down mode or read signature + // DoRDP() ; + + // send request + CNTRPIPE_RQ rq ; + unsigned char vInstruction[8]; + unsigned long rc = 0; + int i; + + // first control packet + vInstruction[0] = read_id_code; + rq.Function = URB_FUNCTION_VENDOR_ENDPOINT ; + rq.Direction = VENDOR_DIRECTION_OUT ; + rq.Request = TRANSCEIVE ; + if(Is_NewUSBCommand(Index)) + { + rq.Value = RESULT_IN ; + rq.Index = 0 ; + } + else + { + rq.Value = RFU ; + rq.Index = RESULT_IN ; + } + rq.Length = 1; + + if(OutCtrlRequest( &rq, vInstruction, (unsigned long)1 , Index ) == SerialFlash_FALSE ) + return rc; //OutCtrlRequest() return error + + // second control packet : fetch data + memset(vInstruction, 0, sizeof(vInstruction)); + + rq.Function = URB_FUNCTION_VENDOR_ENDPOINT ; + rq.Direction = VENDOR_DIRECTION_IN ; + rq.Request = TRANSCEIVE ; + if(Is_NewUSBCommand(Index)) + { + rq.Value = 0x01 ; + rq.Index = 0 ; + } + else + { + rq.Value = CTRL_TIMEOUT ; + rq.Index = NO_REGISTER ; + } + rq.Length = out_data_size ; + + if(InCtrlRequest(&rq, vInstruction, (unsigned long)out_data_size, Index)==SerialFlash_FALSE) + return rc; + for(i=0; i +#include +#include + +#define DEDI_USB_DRIVER 1 + +#define URB_FUNCTION_VENDOR_DEVICE 0x0017 +#define URB_FUNCTION_VENDOR_INTERFACE 0x0018 +#define URB_FUNCTION_VENDOR_ENDPOINT 0x0019 +#define URB_FUNCTION_VENDOR_OTHER 0x0020 + +#define URB_FUNCTION_CLASS_DEVICE 0x001A +#define URB_FUNCTION_CLASS_INTERFACE 0x001B +#define URB_FUNCTION_CLASS_ENDPOINT 0x001C +#define URB_FUNCTION_CLASS_OTHER 0x001F + +#define PIPE_RESET 1 +#define ABORT_TRANSFER 0 + +#define VENDOR_DIRECTION_IN 1 +#define VENDOR_DIRECTION_OUT 0 + +#define DEFAULT_TIMEOUT 30000 + +static usb_dev_handle *dediprog_handle=NULL; +#define MAX_Dev_Index 10 + +typedef struct usb_device_entry { + struct usb_device usb_device_handler; + int valid; +}usb_device_entry_t; + +typedef struct { + unsigned short Function; + unsigned long Direction; + unsigned char Request; + unsigned short Value; + unsigned short Index; + unsigned long Length; +} CNTRPIPE_RQ, *PCNTRPIPE_RQ; + + +usb_device_entry_t usb_device_entry[MAX_Dev_Index]; + + +/* Set/clear LEDs on dediprog */ +#define PASS_ON (0 << 0) +#define PASS_OFF (1 << 0) +#define BUSY_ON (0 << 1) +#define BUSY_OFF (1 << 1) +#define ERROR_ON (0 << 2) +#define ERROR_OFF (1 << 2) + +int usb_driver_init(void); + +int usb_driver_release(void); + +int OutCtrlRequest( CNTRPIPE_RQ *rq, unsigned char *buf, unsigned long buf_size ,int Index ); + +int InCtrlRequest( CNTRPIPE_RQ *rq, unsigned char *buf, unsigned long buf_size, int Index ); + +int BulkPipeRead(unsigned char *pBuff, unsigned int timeOut, int Index); + +int dediprog_set_spi_voltage(int millivolt, int Index); +int dediprog_set_vpp_voltage(int volt); + + +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); + +#endif //DEDI_USB_DRIVER +