├── .gear ├── rules └── sf100linux.spec ├── .gitignore ├── 60-dediprog.rules ├── ChipInfoDb.dedicfg ├── ChipInfoDb.h ├── FlashCommand.c ├── FlashCommand.h ├── IntelHexFile.c ├── IntelHexFile.h ├── LICENSE ├── Macro.h ├── Makefile ├── MotorolaFile.c ├── MotorolaFile.h ├── README.md ├── SerialFlash.c ├── SerialFlash.h ├── board.c ├── board.h ├── dpcmd.c ├── dpcmd.h ├── parse.c ├── project.c ├── project.h ├── usbdriver.c └── usbdriver.h /.gear/rules: -------------------------------------------------------------------------------- 1 | spec: .gear/sf100linux.spec 2 | tar: . 3 | 4 | -------------------------------------------------------------------------------- /.gear/sf100linux.spec: -------------------------------------------------------------------------------- 1 | %define _unpackaged_files_terminate_build 1 2 | 3 | Name: sf100linux 4 | Version: 4.0.0 5 | Release: alt1 6 | 7 | Summary: Control software DediProg SF100 programmer 8 | License: %gpl2plus 9 | Group: Other 10 | Url: https://github.com/DediProgSW/SF100Linux 11 | 12 | BuildRequires(pre): rpm-build-licenses 13 | 14 | BuildRequires: libusb-devel 15 | 16 | Requires: libusb 17 | 18 | Source0: %name-%version.tar 19 | 20 | %description 21 | Linux software for Dediprog SF100 and SF600 SPI flash programmers 22 | 23 | %prep 24 | %setup -q 25 | 26 | %build 27 | %make 28 | 29 | %install 30 | mkdir -vp %buildroot%_bindir 31 | mkdir -vp %buildroot%_datadir/DediProg 32 | mkdir -vp %buildroot%_sysconfdir/udev/rules.d/ 33 | install -v -m 0755 dpcmd %buildroot%_bindir/dpcmd 34 | install -v -m 0644 ChipInfoDb.dedicfg %buildroot%_datadir/DediProg/ChipInfoDb.dedicfg 35 | install -v -m 0644 60-dediprog.rules %buildroot%_sysconfdir/udev/rules.d/60-dediprog.rules 36 | 37 | %files 38 | %_sysconfdir/udev/rules.d/60-dediprog.rules 39 | %_bindir/dpcmd 40 | %_datadir/DediProg/ChipInfoDb.dedicfg 41 | 42 | %changelog 43 | * Fri Aug 27 2021 Igor Chudov 4.0.0-alt1 44 | - Initial release 45 | 46 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.o 3 | .deps 4 | dpcmd 5 | -------------------------------------------------------------------------------- /60-dediprog.rules: -------------------------------------------------------------------------------- 1 | ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="dada", MODE="666", GROUP="plugdev" 2 | -------------------------------------------------------------------------------- /ChipInfoDb.dedicfg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DediProgSW/SF100Linux/135655bcff28d2bce209efde2220322cbaf448c3/ChipInfoDb.dedicfg -------------------------------------------------------------------------------- /ChipInfoDb.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef ChipInfo_H 4 | #define ChipInfo_H 5 | 6 | #include "Macro.h" 7 | 8 | #define NUMBER_OF_SUPPORTING_CHIPS 3 9 | 10 | struct m_code_api { 11 | int (*m_code_api_doRDSR)(unsigned char* cSR, int Index); 12 | int (*m_code_api_doWRSR)(unsigned char cSR, int Index); 13 | int (*m_code_api_doChipErase)(int Index); 14 | int (*m_code_api_doProgram)(void); 15 | int (*m_code_api_doRead)(char* name); 16 | int (*m_code_api_doSegmentErase)(void); 17 | }; 18 | 19 | bool Dedi_List_AllChip(void); 20 | int ChipInfoDbFindItem(CHIP_INFO ChipInfoDb[], int NumberOfItems, long JedecDeviceIDToFind); 21 | void ChipInfoDump(long JedecDeviceIDToFind); 22 | long ChipInfoDumpChipSizeInKByte(long Jedec); 23 | #if 0 24 | int Dedi_Search_Chip_Db(long RDIDCommand, long UniqueID, CHIP_INFO* Chip_Info, int search_all); 25 | 26 | #else 27 | 28 | int Dedi_Search_Chip_Db(char* TypeName, long RDIDCommand, long UniqueID, CHIP_INFO* Chip_Info, int search_all); 29 | #endif 30 | int Dedi_Search_Chip_Db_ByTypeName(char* TypeName, CHIP_INFO* Chip_Info); 31 | //FILE* openChipInfoDb(void); 32 | bool GetChipDbPath(char *Path); 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /FlashCommand.c: -------------------------------------------------------------------------------- 1 | 2 | /// CFlashCommand Implementations 3 | #include "FlashCommand.h" 4 | #include "Macro.h" 5 | #include "project.h" 6 | #include "usbdriver.h" 7 | #define SerialFlash_FALSE -1 8 | #define SerialFlash_TRUE 1 9 | 10 | extern bool Is_NewUSBCommand(int Index); 11 | 12 | int FlashCommand_TransceiveOut(unsigned char* v, int len, int has_result_in, int Index) 13 | { 14 | CNTRPIPE_RQ rq; 15 | 16 | rq.Function = URB_FUNCTION_VENDOR_ENDPOINT; 17 | rq.Direction = VENDOR_DIRECTION_OUT; 18 | rq.Request = TRANSCEIVE; 19 | if (Is_NewUSBCommand(Index)) { 20 | rq.Value = ((has_result_in == 1) ? RESULT_IN : NO_RESULT_IN); 21 | rq.Index = RFU; 22 | } else { 23 | rq.Value = RFU; 24 | rq.Index = ((has_result_in == 1) ? RESULT_IN : NO_RESULT_IN); 25 | } 26 | rq.Length = len; 27 | #if 0 28 | printf("len = %d",len); 29 | for (i=0 ; iend - AddrRange->start) >> divider; 121 | 122 | vInstruction[0] = (unsigned char)(pageNum & 0xff); // lowest byte of length : page number 123 | vInstruction[1] = (unsigned char)((pageNum >> 8) & 0xff); // highest byte of length: page number 124 | vInstruction[2] = (unsigned char)((pageNum >> 16) & 0xff); // reserved 125 | vInstruction[3] = modeWrite; // PAGE_PROGRAM, PAGE_WRITE, AAI_1_BYTE, AAI_2_BYTE, PP_128BYTE, PP_AT26DF041 126 | vInstruction[4] = WriteCom; 127 | 128 | if (Is_NewUSBCommand(Index)) { 129 | vInstruction[5] = 0; 130 | vInstruction[6] = (AddrRange->start & 0xff); 131 | vInstruction[7] = ((AddrRange->start >> 8) & 0xff); 132 | vInstruction[8] = ((AddrRange->start >> 16) & 0xff); 133 | vInstruction[9] = ((AddrRange->start >> 24) & 0xff); 134 | vInstruction[10] = (PageSize & 0xff); 135 | vInstruction[11] = ((PageSize >> 8) & 0xff); 136 | vInstruction[12] = ((PageSize >> 16) & 0xff); 137 | vInstruction[13] = ((PageSize >> 24) & 0xff); 138 | vInstruction[14] = (AddressMode & 0xff); 139 | rq.Value = 0; 140 | rq.Index = 0; 141 | rq.Length = (unsigned long)(15); 142 | } else { 143 | rq.Value = (unsigned short)(AddrRange->start & 0xffff); // 16 bits LSB 144 | rq.Index = (unsigned short)((AddrRange->start >> 16) & 0xffff); // 16 bits MSB 145 | rq.Length = (unsigned long)(5); 146 | } 147 | // send rq via control pipe 148 | return OutCtrlRequest(&rq, vInstruction, rq.Length, Index); 149 | } 150 | 151 | int FlashCommand_SendCommand_SetupPacketForAT45DBBulkWrite(struct CAddressRange* AddrRange, unsigned char modeWrite, unsigned char WriteCom, int Index) 152 | { 153 | /* modeWrite: 154 | 1: page-size = 256 155 | 2: page-size = 264 156 | 3: page-size = 512 157 | 4: page-size = 528 158 | 5: page-size = 1024 159 | 6: page-size = 1056 160 | */ 161 | size_t pageSize[7] = { 0, 256, 264, 512, 528, 1024, 1056 }; 162 | 163 | size_t pageNum = ((AddrRange->end - AddrRange->start) + pageSize[modeWrite] - 1) / pageSize[modeWrite]; 164 | // printf("modeWrite = %hhu\n",modeWrite); 165 | // printf("pageNum = %lu\n",pageNum); 166 | 167 | unsigned char vInstruction[10]; 168 | vInstruction[0] = (unsigned char)(pageNum & 0xff); // lowest byte of length : page number 169 | vInstruction[1] = (unsigned char)((pageNum >> 8) & 0xff); // highest byte of length: page number 170 | vInstruction[2] = (unsigned char)((pageNum >> 16) & 0xff); // reserved 171 | vInstruction[3] = modeWrite; 172 | vInstruction[4] = WriteCom; 173 | CNTRPIPE_RQ rq; 174 | rq.Function = URB_FUNCTION_VENDOR_ENDPOINT; 175 | rq.Direction = VENDOR_DIRECTION_OUT; 176 | rq.Request = ATMEL45_WRITE; 177 | 178 | if (Is_NewUSBCommand(Index)) { 179 | vInstruction[5] = 0; 180 | vInstruction[6] = (AddrRange->start & 0xff); 181 | vInstruction[7] = ((AddrRange->start >> 8) & 0xff); 182 | vInstruction[8] = ((AddrRange->start >> 16) & 0xff); 183 | vInstruction[9] = ((AddrRange->start >> 24) & 0xff); 184 | rq.Value = 0; 185 | rq.Index = 0; 186 | rq.Length = (unsigned long)(10); 187 | } else { 188 | rq.Value = (unsigned short)(AddrRange->start & 0xffff); // 16 bits LSB 189 | rq.Index = (unsigned short)((AddrRange->start >> 16) & 0xffff); // 16 bits MSB 190 | rq.Length = (unsigned long)(5); 191 | } 192 | 193 | // send rq via control pipe 194 | return OutCtrlRequest(&rq, vInstruction, rq.Length, Index); 195 | } 196 | 197 | int FlashCommand_SendCommand_SetupPacketForBulkRead(struct CAddressRange* AddrRange, unsigned char modeRead, unsigned char ReadCom, unsigned int AddrLen, unsigned int DummyLen, int Index) 198 | { 199 | unsigned char vInstruction[12]; 200 | CNTRPIPE_RQ rq; 201 | rq.Function = URB_FUNCTION_VENDOR_ENDPOINT; 202 | rq.Direction = VENDOR_DIRECTION_OUT; 203 | rq.Request = DTC_READ; 204 | 205 | // length in terms of 256 bytes 206 | size_t pageNum = AddrRange->length >> 9; 207 | 208 | 209 | vInstruction[0] = (unsigned char)(pageNum & 0xff); // lowest byte of length : page number 210 | vInstruction[1] = (unsigned char)((pageNum >> 8) & 0xff); // highest byte of length: page number 211 | vInstruction[2] = (unsigned char)((pageNum >> 16) & 0xff); // reserved 212 | vInstruction[3] = modeRead; // BULK_NORM_READ, BULK_FAST_READ 213 | vInstruction[4] = ReadCom; 214 | 215 | if (Is_NewUSBCommand(Index)) { 216 | vInstruction[5] = 0xFF; 217 | vInstruction[6] = (AddrRange->start & 0xff); 218 | vInstruction[7] = ((AddrRange->start >> 8) & 0xff); 219 | vInstruction[8] = ((AddrRange->start >> 16) & 0xff); 220 | vInstruction[9] = ((AddrRange->start >> 24) & 0xff); 221 | vInstruction[10] = (AddrLen & 0xff); 222 | vInstruction[11] = (DummyLen & 0xff); 223 | rq.Value = 0; 224 | rq.Index = 0; 225 | rq.Length = (unsigned long)(12); 226 | } else { 227 | rq.Value = (unsigned short)(AddrRange->start & 0xffff); // 16 bits LSB 228 | rq.Index = (unsigned short)((AddrRange->start >> 16) & 0xffff); // 16 bits MSB 229 | rq.Length = (unsigned long)(5); 230 | } 231 | 232 | // send rq via control pipe 233 | return OutCtrlRequest(&rq, vInstruction, rq.Length, Index); 234 | } 235 | 236 | int FlashCommand_SendCommand_SetupPacketForBulkReadNAND(unsigned int dwAddr, unsigned int PageNum, unsigned char modeRead,WORD pageSize, WORD blockPages, unsigned char ReadCom,unsigned char AddrLen, unsigned char ReadDummyLen,unsigned char nCA, int USBIndex) 237 | { 238 | unsigned char vInstruction[18]; 239 | vInstruction[0]=(dwAddr & 0xff) ; 240 | vInstruction[1]=((dwAddr>>8) & 0xff); 241 | vInstruction[2]=((dwAddr>>16) & 0xff); 242 | vInstruction[3]=((dwAddr>>24) & 0xff); 243 | 244 | //dwLength 245 | vInstruction[4]=((unsigned char)(PageNum & 0xff)); // lowest byte of length : page number 246 | vInstruction[5]=((unsigned char)( (PageNum >> 8) & 0xff)); // highest byte of length: page number 247 | vInstruction[6]=((unsigned char)( (PageNum >> 16) & 0xff) ); 248 | vInstruction[7]=((unsigned char)( (PageNum >> 24) & 0xff) ); 249 | 250 | //dwMode 251 | vInstruction[8]=(modeRead); 252 | vInstruction[9]=(modeRead>>8); 253 | 254 | //pagesize 255 | vInstruction[10]=((unsigned char)(pageSize)); 256 | vInstruction[11]=((unsigned char)(pageSize>>8)); 257 | 258 | //blockpages 259 | vInstruction[12]=((unsigned char)(blockPages)); 260 | vInstruction[13]=((unsigned char)(blockPages>>8)); 261 | 262 | vInstruction[14]=((unsigned char)(ReadCom));//cmd 263 | 264 | vInstruction[15]=((unsigned char)AddrLen);//addrLen 265 | 266 | vInstruction[16]=((unsigned char)(ReadDummyLen)); 267 | 268 | vInstruction[17]=((unsigned char)nCA); 269 | 270 | CNTRPIPE_RQ rq ; 271 | rq.Function = URB_FUNCTION_VENDOR_ENDPOINT ; 272 | rq.Direction = VENDOR_DIRECTION_OUT ; 273 | rq.Request = DTC_READ_NAND ; 274 | rq.Value = 0 ; 275 | rq.Index = 0 ; 276 | rq.Length = (unsigned long)(sizeof(vInstruction)) ;//40 277 | 278 | // send rq via control pipe 279 | return OutCtrlRequest(&rq, vInstruction,rq.Length,USBIndex); 280 | } 281 | 282 | bool FlashCommand_SendCommand_SetupPacketForBulkWriteNAND(unsigned int dwAddr, size_t dwLength,unsigned char modeWrite,WORD pageSize, WORD blockPages, unsigned char WriteCom,unsigned char AddrLen, unsigned char WriteDummyLen,unsigned char nCA, int USBIndex) 283 | { 284 | unsigned char vInstruction[40]={0}; 285 | //dwAddr; 286 | vInstruction[0]=(dwAddr & 0xff); 287 | vInstruction[1]=((dwAddr>>8) & 0xff); 288 | vInstruction[2]=((dwAddr>>16) & 0xff); 289 | vInstruction[3]=((dwAddr>>24) & 0xff); 290 | 291 | //dwLength 292 | vInstruction[4]=((unsigned char)(dwLength & 0xff)); // lowest byte of length : page number 293 | vInstruction[5]=((unsigned char)( (dwLength >> 8) & 0xff)); // highest byte of length: page number 294 | vInstruction[6]=((unsigned char)( (dwLength >> 16) & 0xff) ); 295 | vInstruction[7]=((unsigned char)( (dwLength >> 24) & 0xff) ); 296 | 297 | //dwMode 298 | vInstruction[8]=((unsigned char)modeWrite); 299 | vInstruction[9]=((unsigned char)(modeWrite>>8)); 300 | 301 | //pagesize 302 | vInstruction[10]=((unsigned char)pageSize); 303 | vInstruction[11]=((unsigned char)(pageSize>>8)); 304 | 305 | //blockpages 306 | vInstruction[12]=(blockPages); 307 | vInstruction[13]=((unsigned char)(blockPages>>8)); 308 | vInstruction[14]=(WriteCom);//cmd 309 | vInstruction[15]=(AddrLen);//addrLen 310 | vInstruction[16]=(4); 311 | vInstruction[17]=(nCA); 312 | 313 | CNTRPIPE_RQ rq ; 314 | 315 | rq.Function = URB_FUNCTION_VENDOR_ENDPOINT ; 316 | rq.Direction = VENDOR_DIRECTION_OUT ; 317 | rq.Request = WRITE_NAND ; 318 | rq.Value = 0 ; 319 | rq.Index = 0 ; 320 | rq.Length = sizeof(vInstruction); 321 | 322 | // send rq via control pipe 323 | return OutCtrlRequest(&rq, vInstruction,rq.Length,USBIndex); 324 | } 325 | 326 | -------------------------------------------------------------------------------- /FlashCommand.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef FLASHCOMMANDS 4 | #define FLASHCOMMANDS 5 | 6 | #include "Macro.h" 7 | 8 | #define FlashCommand_TRUE 1 9 | #define FlashCommand_FALSE 0 10 | 11 | int FlashCommand_TransceiveOut(unsigned char* v, int len, int has_result_in, int Index); 12 | 13 | int FlashCommand_TransceiveIn(unsigned char* v, int len, int Index); 14 | 15 | int FlashCommand_SendCommand_OutOnlyInstruction(unsigned char* v, int len, int Index); 16 | 17 | int FlashCommand_SendCommand_OutInstructionWithCS(unsigned char* v, int len, int Index); 18 | 19 | int FlashCommand_SendCommand_OneOutOneIn(unsigned char* vOut, int out_len, unsigned char* vIn, int in_len, int Index); 20 | 21 | int FlashCommand_SendCommand_SetupPacketForBulkWrite(struct CAddressRange* AddrRange, unsigned char modeWrite, unsigned char WriteCom, unsigned int PageSize, unsigned int AddressMode, int Index); 22 | 23 | int FlashCommand_SendCommand_SetupPacketForAT45DBBulkWrite(struct CAddressRange* AddrRange, unsigned char modeWrite, unsigned char WriteCom, int Index); 24 | 25 | int FlashCommand_SendCommand_SetupPacketForBulkRead(struct CAddressRange* AddrRange, unsigned char modeRead, unsigned char ReadCom, unsigned int AddrLen, unsigned int DummyLen, int Index); 26 | int FlashCommand_SendCommand_SetupPacketForBulkReadNAND(unsigned int dwAddr, unsigned int PageNum, unsigned char modeRead,WORD pageSize, WORD blockPages, unsigned char ReadCom,unsigned char AddrLen, unsigned char ReadDummyLen,unsigned char nCA, int USBIndex); 27 | bool FlashCommand_SendCommand_SetupPacketForBulkWriteNAND(unsigned int dwAddr, size_t dwLength,unsigned char modeWrite,WORD pageSize, WORD blockPages, unsigned char WriteCom,unsigned char AddrLen, unsigned char WriteDummyLen,unsigned char nCA, int USBIndex); 28 | 29 | 30 | #endif //FLASHCOMMANDS 31 | -------------------------------------------------------------------------------- /IntelHexFile.c: -------------------------------------------------------------------------------- 1 | #include "IntelHexFile.h" 2 | #include "project.h" 3 | #include 4 | #include 5 | #include 6 | #include 7 | extern unsigned char* pBufferforLoadedFile; 8 | extern unsigned long g_ulFileSize; 9 | /* 10 | * the choice for the total length (16) of a line, but the specification 11 | * can support an another value 12 | */ 13 | bool BinToHexFile(const char* filePath, unsigned char* vBuffer, unsigned long FileSize) 14 | { 15 | // +anderson_variable 06/10/11 /////////////////////////////////////// 16 | // unsigned char unch = 0x12; 17 | // int j=0; 18 | // int str1_cnt=0; 19 | // int str2_cnt=0; 20 | 21 | // CString str; 22 | // CString str1 = L""; 23 | // CString str2 = L""; 24 | // CString str_tmp = L""; 25 | // -anderson_variable 06/10/11 /////////////////////////////////////// 26 | FILE* FileOut; /* input files */ 27 | FileOut = fopen(filePath, "wt"); 28 | if (FileOut == NULL) 29 | return false; 30 | 31 | size_t i; 32 | t_one_line one_record; 33 | one_record.intel_adr = 0; 34 | one_record.intel_type = INTEL_DATA_TYPE; 35 | 36 | char buf[256] = { 0 }; 37 | 38 | int iULBA = (unsigned int)((FileSize >> 16) & 0xFFFF); 39 | unsigned int idx = 0; 40 | 41 | do // for(unsigned int idx = 0; idx < iULBA; ++idx) 42 | { 43 | // Extended Linear Address Record (32-bit format only) 44 | memset(buf, 0, sizeof(buf)); 45 | fprintf(FileOut, ":02000004%04X%02X\n", idx, (unsigned char)(0x100 - 0x06 - (idx & 0xFF) - ((idx >> 8) & 0xFF))); 46 | 47 | size_t len = iULBA ? 0x10000 : (FileSize & 0xFFFF); 48 | while (len > 0) { 49 | one_record.intel_lg_data = (LL_MAX_LINE > len) ? len : LL_MAX_LINE; 50 | memcpy(one_record.intel_data, vBuffer + one_record.intel_adr + (idx << 16), one_record.intel_lg_data); 51 | // copy(vBuffer + one_record.intel_adr + (idx<<16), 52 | // vBuffer + one_record.intel_adr + (idx<<16) + one_record.intel_lg_data, 53 | // one_record.intel_data) ; 54 | 55 | len -= one_record.intel_lg_data; 56 | 57 | one_record.intel_lrc = one_record.intel_lg_data; 58 | one_record.intel_lrc += ((one_record.intel_adr >> 8) & 0xff); 59 | one_record.intel_lrc += (one_record.intel_adr & 0xff); 60 | one_record.intel_lrc += one_record.intel_type; 61 | 62 | memset(buf, 0, sizeof(buf)); 63 | fprintf(FileOut, ":%02X%04X%02X", one_record.intel_lg_data, one_record.intel_adr, one_record.intel_type); 64 | 65 | for (i = 0; i < one_record.intel_lg_data; ++i) { 66 | memset(buf, 0, sizeof(buf)); 67 | fprintf(FileOut, "%02X", (one_record.intel_data[i] & 0xff)); 68 | one_record.intel_lrc += one_record.intel_data[i]; 69 | } 70 | 71 | memset(buf, 0, sizeof(buf)); 72 | fprintf(FileOut, "%02X\n", ((0x100 - one_record.intel_lrc) & 0xff)); 73 | one_record.intel_adr += one_record.intel_lg_data; 74 | } 75 | idx++; 76 | } while (iULBA--); 77 | fprintf(FileOut, ":00000001FF\n"); 78 | 79 | fclose(FileOut); 80 | 81 | return true; 82 | } 83 | 84 | bool HexFileToBin(const char* filePath, unsigned char* vOutData, unsigned long* FileSize, unsigned char PaddingByte) 85 | { 86 | FILE* Filin; /* input files */ 87 | 88 | /* size in bytes */ 89 | const long MEMORY_SIZE = 16 * 1024 * 1024; 90 | const long ADDRESS_MASK = 0x00FFFFFF; 91 | const int MAX_LINE_SIZE = 256; 92 | const int NO_ADDRESS_TYPE_SELECTED = 0; 93 | const int LINEAR_ADDRESS = 1; 94 | const int SEGMENTED_ADDRESS = 2; 95 | 96 | unsigned int Seg_Lin_Select = NO_ADDRESS_TYPE_SELECTED; 97 | 98 | const int CKS_8 = 0; 99 | 100 | /* line inputted from file */ 101 | char Line[MAX_LINE_SIZE]; 102 | 103 | /* flag that a file was read */ 104 | bool Enable_Checksum_Error = false; 105 | 106 | /* cmd-line parameter # */ 107 | unsigned char* p; 108 | unsigned int i; 109 | 110 | /* Application specific */ 111 | 112 | unsigned int Nb_Bytes; 113 | unsigned int First_Word, Address, Segment, Upper_Address; 114 | unsigned int Lowest_Address, Highest_Address, Starting_Address; 115 | unsigned int Phys_Addr, hType; 116 | unsigned int temp; 117 | 118 | bool Starting_Address_Setted = false; 119 | 120 | int temp2; 121 | 122 | unsigned char Data_Str[MAX_LINE_SIZE]; 123 | unsigned char Checksum = 0; 124 | 125 | unsigned short int wCKS; 126 | unsigned short int w; 127 | unsigned int Cks_Type = CKS_8; 128 | unsigned int Cks_Start, Cks_End, Cks_Addr, Cks_Value; 129 | bool Cks_range_set = false; 130 | bool Cks_Addr_set = false; 131 | 132 | /* Just a normal file name */ 133 | Filin = fopen(filePath, "r"); 134 | if (Filin == 0L) 135 | return false; 136 | 137 | /* allocate a buffer */ 138 | unsigned char* Memory_Block = (unsigned char*)malloc(MEMORY_SIZE); 139 | 140 | /* To begin, assume the lowest address is at the end of the memory. 141 | subsequent addresses will lower this number. At the end of the input 142 | file, this value will be the lowest address. */ 143 | Lowest_Address = MEMORY_SIZE - 1; 144 | Highest_Address = 0; 145 | 146 | bool boEndofFile = false; 147 | 148 | /* To begin, assume the lowest address is at the end of the memory. 149 | subsequent addresses will lower this number. At the end of the input 150 | file, this value will be the lowest address. */ 151 | Segment = 0; 152 | Upper_Address = 0; 153 | Lowest_Address = MEMORY_SIZE - 1; 154 | Highest_Address = 0; 155 | 156 | /* Now read the file & process the lines. */ 157 | do /* repeat until EOF(Filin) */ 158 | { 159 | /* Read a line from input file. */ 160 | if (fgets(Line, MAX_LINE_SIZE, Filin) == NULL) 161 | break; 162 | 163 | /* Remove carriage return/line feed at the end of line. */ 164 | i = strlen(Line) - 1; 165 | 166 | if (':' != Line[0] && boEndofFile == false) { 167 | free(Memory_Block); 168 | return false; // 0x0a != Line[0] && NULL != Line[0]) return false; 169 | } 170 | 171 | if (Line[i] == '\n') 172 | Line[i] = '\0'; 173 | 174 | /* Scan the first two bytes and nb of bytes. 175 | The two bytes are read in First_Word since it's use depend on the 176 | record type: if it's an extended address record or a data record. 177 | */ 178 | sscanf(Line, ":%2x%4x%2x%s", &Nb_Bytes, &First_Word, &hType, Data_Str); 179 | 180 | Checksum = Nb_Bytes + (First_Word >> 8) + (First_Word & 0xFF) + hType; 181 | 182 | p = Data_Str; 183 | 184 | /* If we're reading the last record, ignore it. */ 185 | switch (hType) { 186 | /* Data record */ 187 | case 0: 188 | Address = First_Word; 189 | 190 | if (Seg_Lin_Select == SEGMENTED_ADDRESS) 191 | Phys_Addr = (Segment << 4) + Address; 192 | else 193 | /* LINEAR_ADDRESS or NO_ADDRESS_TYPE_SELECTED 194 | Upper_Address = 0 as specified in the Intel spec. until an extended address 195 | record is read. */ 196 | Phys_Addr = ((Upper_Address << 16) & ADDRESS_MASK) + Address; 197 | 198 | /* Check that the physical address stays in the buffer's range. */ 199 | if ((Phys_Addr + Nb_Bytes) <= MEMORY_SIZE - 1) { 200 | /* Set the lowest address as base pointer. */ 201 | if (Phys_Addr < Lowest_Address) 202 | Lowest_Address = Phys_Addr; 203 | 204 | /* Same for the top address. */ 205 | temp = Phys_Addr + Nb_Bytes - 1; 206 | 207 | if (temp > Highest_Address) 208 | Highest_Address = temp; 209 | 210 | /* Read the Data bytes. */ 211 | /* Bytes are written in the Memory block even if checksum is wrong. */ 212 | if (Nb_Bytes == 0) { 213 | free(Memory_Block); 214 | return false; 215 | } 216 | for (i = Nb_Bytes; i > 0; i--) { 217 | sscanf((const char*)(p), "%2x", &temp2); 218 | p += 2; 219 | Memory_Block[Phys_Addr++] = temp2; 220 | Checksum = (Checksum + temp2) & 0xFF; 221 | }; 222 | 223 | /* Read the Checksum value. */ 224 | sscanf((const char*)(p), "%2x", &temp2); 225 | 226 | /* Verify Checksum value. */ 227 | Checksum = (Checksum + temp2) & 0xFF; 228 | 229 | if ((Checksum != 0) && Enable_Checksum_Error) { 230 | } 231 | } else { 232 | if (Seg_Lin_Select == SEGMENTED_ADDRESS) 233 | fprintf(stderr, "Data record skipped at %4X:%4X\n", Segment, Address); 234 | else 235 | fprintf(stderr, "Data record skipped at %8X\n", Phys_Addr); 236 | } 237 | 238 | break; 239 | 240 | /* End of file record */ 241 | case 1: 242 | /* Simply ignore checksum errors in this line. */ 243 | boEndofFile = true; 244 | break; 245 | 246 | /* Extended segment address record */ 247 | case 2: 248 | /* First_Word contains the offset. It's supposed to be 0000 so 249 | we ignore it. */ 250 | 251 | /* First extended segment address record ? */ 252 | if (Seg_Lin_Select == NO_ADDRESS_TYPE_SELECTED) 253 | Seg_Lin_Select = SEGMENTED_ADDRESS; 254 | 255 | /* Then ignore subsequent extended linear address records */ 256 | if (Seg_Lin_Select == SEGMENTED_ADDRESS) { 257 | sscanf((const char*)(p), "%4x%2x", &Segment, &temp2); 258 | 259 | /* Update the current address. */ 260 | Phys_Addr = (Segment << 4) & ADDRESS_MASK; 261 | 262 | /* Verify Checksum value. */ 263 | Checksum = (Checksum + (Segment >> 8) + (Segment & 0xFF) + temp2) & 0xFF; 264 | 265 | // if ((Checksum != 0) && Enable_Checksum_Error) 266 | // Status_Checksum_Error = true; 267 | } 268 | break; 269 | 270 | /* Start segment address record */ 271 | case 3: 272 | /* Nothing to be done since it's for specifying the starting address for 273 | execution of the binary code */ 274 | break; 275 | 276 | /* Extended linear address record */ 277 | case 4: 278 | /* First_Word contains the offset. It's supposed to be 0000 so 279 | we ignore it. */ 280 | 281 | /* First extended linear address record ? */ 282 | if (Seg_Lin_Select == NO_ADDRESS_TYPE_SELECTED) 283 | Seg_Lin_Select = LINEAR_ADDRESS; 284 | 285 | /* Then ignore subsequent extended segment address records */ 286 | if (Seg_Lin_Select == LINEAR_ADDRESS) { 287 | sscanf((const char*)(p), "%4x%2x", &Upper_Address, &temp2); 288 | 289 | /* Update the current address. */ 290 | Phys_Addr = Upper_Address << 4; 291 | 292 | /* Verify Checksum value. */ 293 | Checksum = (Checksum + (Upper_Address >> 8) + (Upper_Address & 0xFF) + temp2) & 0xFF; 294 | 295 | // if ((Checksum != 0) && Enable_Checksum_Error) 296 | // Status_Checksum_Error = true; 297 | } 298 | break; 299 | 300 | /* Start linear address record */ 301 | case 5: 302 | /* Nothing to be done since it's for specifying the starting address for 303 | execution of the binary code */ 304 | break; 305 | default: 306 | break; // 20040617+ Added to remove GNU compiler warning about label at end of compound statement 307 | } 308 | } while (!feof(Filin)); 309 | /*-----------------------------------------------------------------------------*/ 310 | 311 | // fprintf(stdout,"Lowest address = %08X\n",Lowest_Address); 312 | // fprintf(stdout,"Highest address = %08X\n",Highest_Address); 313 | // fprintf(stdout,"Pad Byte = %X\n", PadByte); 314 | 315 | wCKS = 0; 316 | if (!Cks_range_set) { 317 | Cks_Start = Lowest_Address; 318 | Cks_End = Highest_Address; 319 | } 320 | switch (Cks_Type) { 321 | case 0: 322 | 323 | for (i = Cks_Start; i <= Cks_End; i++) { 324 | wCKS += Memory_Block[i]; 325 | } 326 | 327 | // fprintf(stdout,"8-bit Checksum = %02X\n",wCKS & 0xff); 328 | if (Cks_Addr_set) { 329 | wCKS = Cks_Value - (wCKS - Memory_Block[Cks_Addr]); 330 | Memory_Block[Cks_Addr] = (unsigned char)(wCKS & 0xff); 331 | // fprintf(stdout,"Addr %08X set to %02X\n",Cks_Addr, wCKS & 0xff); 332 | } 333 | break; 334 | 335 | case 2: 336 | 337 | for (i = Cks_Start; i <= Cks_End; i += 2) { 338 | w = Memory_Block[i + 1] | ((unsigned short)Memory_Block[i] << 8); 339 | wCKS += w; 340 | } 341 | 342 | // fprintf(stdout,"16-bit Checksum = %04X\n",wCKS); 343 | if (Cks_Addr_set) { 344 | w = Memory_Block[Cks_Addr + 1] | ((unsigned short)Memory_Block[Cks_Addr] << 8); 345 | wCKS = Cks_Value - (wCKS - w); 346 | Memory_Block[Cks_Addr] = (unsigned char)(wCKS >> 8); 347 | Memory_Block[Cks_Addr + 1] = (unsigned char)(wCKS & 0xff); 348 | // fprintf(stdout,"Addr %08X set to %04X\n",Cks_Addr, wCKS); 349 | } 350 | break; 351 | 352 | case 1: 353 | 354 | for (i = Cks_Start; i <= Cks_End; i += 2) { 355 | w = Memory_Block[i] | ((unsigned short)Memory_Block[i + 1] << 8); 356 | wCKS += w; 357 | } 358 | 359 | // fprintf(stdout,"16-bit Checksum = %04X\n",wCKS); 360 | if (Cks_Addr_set) { 361 | w = Memory_Block[Cks_Addr] | ((unsigned short)Memory_Block[Cks_Addr + 1] << 8); 362 | wCKS = Cks_Value - (wCKS - w); 363 | Memory_Block[Cks_Addr + 1] = (unsigned char)(wCKS >> 8); 364 | Memory_Block[Cks_Addr] = (unsigned char)(wCKS & 0xff); 365 | // fprintf(stdout,"Addr %08X set to %04X\n",Cks_Addr, wCKS); 366 | } 367 | 368 | default:; 369 | } 370 | 371 | /* This starting address is for the binary file, 372 | 373 | ex.: if the first record is :nn010000ddddd... 374 | the data supposed to be stored at 0100 will start at 0000 in the binary file. 375 | 376 | Specifying this starting address will put FF bytes in the binary file so that 377 | the data supposed to be stored at 0100 will start at the same address in the 378 | binary file. 379 | */ 380 | 381 | if (Starting_Address_Setted) { 382 | Lowest_Address = Starting_Address; 383 | } 384 | 385 | if (pBufferforLoadedFile != NULL) 386 | free(pBufferforLoadedFile); 387 | // pBufferforLoadedFile=(unsigned char*)malloc(Highest_Address - Lowest_Address + 1); 388 | pBufferforLoadedFile = (unsigned char*)malloc(Highest_Address + 1); 389 | 390 | if (Lowest_Address < Highest_Address) { 391 | // memcpy(pBufferforLoadedFile,Memory_Block + Lowest_Address, Highest_Address - Lowest_Address + 1 ) ; 392 | // g_ulFileSize=(Highest_Address -Lowest_Address+ 1); ; 393 | memcpy(pBufferforLoadedFile, Memory_Block, Highest_Address + 1); 394 | g_ulFileSize = (Highest_Address + 1); 395 | } 396 | 397 | free(Memory_Block); 398 | return true; 399 | } 400 | -------------------------------------------------------------------------------- /IntelHexFile.h: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | /****INTEL HEX-RECORD FORMAT, copied from http://www.cs.net/lucid/intel.htm**** 4 | 5 | INTRODUCTION 6 | Intel's Hex-record format allows program or data files to be encoded in a 7 | printable (ASCII) format. This allows viewing of the object file with standard 8 | tools and easy file transfer from one computer to another, or between a host 9 | and target. An individual Hex-record is a single line in a file composed of 10 | many Hex-records. 11 | 12 | HEX-RECORD CONTENT 13 | Hex-Records are character strings made of several fields which specify the 14 | record type, record length, memory address, data, and checksum. Each byte of 15 | binary data is encoded as a 2-character hexadecimal number: the first ASCII 16 | character representing the high-order 4 bits, and the second the low-order 4 17 | bits of the byte. 18 | 19 | The 6 fields which comprise a Hex-record are defined as follows: 20 | Field Characters Description 21 | 1 Start code 1 An ASCII colon, ":". 22 | 2 Byte count 2 The count of the character pairs in the data field. 23 | 3 Address 4 The 2-byte address at which the data field is to be loaded into memory. 24 | 4 Type 2 00, 01, or 02. 25 | 5 Data 0-2n From 0 to n bytes of executable code, or memory loadable data. 26 | n is normally 20 hex (32 decimal) or less. 27 | 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. 28 | 29 | Each record may be terminated with a CR/LF/NULL. Accuracy of transmission is ensured by the byte count and checksum fields. 30 | 31 | HEX-RECORD TYPES 32 | There are three possible types of Hex-records. 33 | 00 34 | A record containing data and the 2-byte address at which the data is to reside. 35 | 01 36 | 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. 37 | 02 38 | A segment base address record. This type of record is ignored by Lucid programmers. 39 | 40 | 41 | HEX-RECORD EXAMPLE 42 | Following is a typical Hex-record module consisting of four data records and a termination record. 43 | 44 | :10010000214601360121470136007EFE09D2190140 45 | :100110002146017EB7C20001FF5F16002148011988 46 | :10012000194E79234623965778239EDA3F01B2CAA7 47 | :100130003F0156702B5E712B722B732146013421C7 48 | :00000001FF 49 | 50 | The first data record is explained as follows: 51 | : Start code. 52 | 53 | 10 Hex 10 (decimal 16), indicating 16 data character 54 | pairs, 16 bytes of binary data, in this record. 55 | 56 | 01 Four-character 2-byte address field: hex address 0100, 57 | 00 indicates location where the following data is to be loaded. 58 | 59 | 00 Record type indicating a data record. 60 | 61 | The next 16 character pairs are the ASCII bytes of the actual program data. 62 | 63 | 40 Checksum of the first Hex-record. 64 | 65 | 66 | The termination record is explained as follows: 67 | 68 | : Start code. 69 | 70 | 00 Byte count is zero, no data in termination record. 71 | 72 | 00 Four-character 2-byte address field, zeros. 73 | 00 74 | 75 | 01 Record type 01 is termination. 76 | 77 | FF Checksum of termination record. 78 | 79 | 80 | -------------------------------------------------------------------------------- 81 | 82 | [ Back to Data & Documentation ] [ Home ] 83 | -------------------------------------------------------------------------------- 84 | 85 | 86 | */ 87 | 88 | /* Intel Hex format specifications 89 | 90 | The 8-bit Intel Hex File Format is a printable ASCII format consisting of one 91 | or more data records followed by an end of file record. Each 92 | record consists of one line of information. Data records may appear in any 93 | order. Address and data values are represented as 2 or 4 hexadecimal 94 | digit values. 95 | 96 | Record Format 97 | :LLAAAARRDDDD......DDDDCC 98 | 99 | 100 | LL 101 | AAAA 102 | RR 103 | DD 104 | CC 105 | Length field. Number of data bytes. 106 | Address field. Address of first byte. 107 | Record type field. 00 for data and 01 for end of record. 108 | Data field. 109 | Checksum field. One's complement of length, address, record type and data 110 | fields modulo 256. 111 | CC = LL + AAAA + RR + all DD = 0 112 | 113 | Example: 114 | :06010000010203040506E4 115 | :00000001FF 116 | 117 | The first line in the above example Intel Hex file is a data record addressed 118 | at location 100H with data values 1 to 6. The second line is the end 119 | of file record, so that the LL field is 0 120 | 121 | */ 122 | 123 | #ifndef INTELHEXFILE_H 124 | #define INTELHEXFILE_H 125 | 126 | #include 127 | 128 | #define LL_MAX_LINE 16 129 | typedef struct { 130 | unsigned char intel_lg_data; 131 | unsigned short intel_adr; 132 | unsigned char intel_type; 133 | unsigned char intel_data[LL_MAX_LINE]; 134 | unsigned char intel_lrc; 135 | } t_one_line; 136 | 137 | #define INTEL_DATA_TYPE 0 138 | 139 | //save binary data in vBuffer to file in Intel Hex format 140 | bool BinToHexFile(const char* filePath, unsigned char* vBuffer, unsigned long FileSize); 141 | 142 | // read binary data from Intel Hex file 143 | bool HexFileToBin(const char* filePath, unsigned char* vOutData, unsigned long* FileSize, unsigned char PaddingByte); 144 | 145 | #endif // end of header file 146 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | {description} 294 | Copyright (C) {year} {fullname} 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | {signature of Ty Coon}, 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /Macro.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef _MACRO_H 4 | #define _MACRO_H 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | // new defined macros 12 | #define IS_NAND_FLASH {if()} 13 | //programmer info RQ 14 | #define PROGINFO_REQUEST 0x08 15 | #define SET_VCC 0x09 ///< set VCC 16 | #define SET_VPP 0x03 ///< set VPP 17 | //#define SET_CS 0x14 18 | //#define SET_IOMODE 0x15 19 | //#define SET_SPICLK 0x61 20 | //#define SET_HOLD 0x1D 21 | #define SET_SA 0x0A 22 | 23 | //first field of RQ 24 | #define OUT_REQUEST 0x42 25 | #define IN_REQUEST 0xC2 26 | 27 | //second field of RQ in case of bulk transfer 28 | //#define TRANSCEIVE 0x01 29 | //#define DTC_READ 0x20 30 | //#define WRITE 0x30 31 | //#define READ_EEPROM 0x05 32 | //#define WRITE_EEPROM 0x06 33 | // values of Request Field of a setup packet 34 | 35 | typedef unsigned short WORD; 36 | typedef unsigned char BYTE; 37 | typedef unsigned long DWORD; 38 | 39 | typedef struct FirmwareInfo { 40 | char Programmer[20]; 41 | char Version[10]; 42 | char FPGAVersion[10]; 43 | unsigned int dwSignature; 44 | unsigned int Rev[3]; 45 | unsigned int FirstIndex; 46 | unsigned int FirstSize; 47 | unsigned int SecondIndex; 48 | unsigned int SecondSize; 49 | } FW_INFO; 50 | 51 | typedef enum { 52 | TRANSCEIVE = 0x01, 53 | DTC_READ = 0x20, 54 | WRITE = 0x30, 55 | 56 | ATMEL45_WRITE = 0x31, 57 | 58 | READ_EEPROM = 0x05, 59 | WRITE_EEPROM = 0x06, 60 | GET_BUTTON_STATUS = 0x11, 61 | GET_UID = 0x12, 62 | SET_CS = 0x14, 63 | SET_IOMODE = 0x15, 64 | FW_UPDATE = 0x1A, 65 | FPGA_UPDATE = 0x1B, 66 | READ_FPGA_VERSION = 0x1C, 67 | SET_HOLD = 0x1D, 68 | DTC_READ_NAND = 0x40, 69 | WRITE_NAND = 0x50, 70 | MICRON_XIP_RESET =0x99, 71 | SET_SPICLK = 0x61, 72 | DOWNLOAD_PROJECT =0x63, 73 | GET_PROJECT_NAME =0x64, 74 | CHECK_SD_CARD = 0x65, 75 | READ_PROJECT =0x66, 76 | DL_IC_INFO_NAND =0x67, 77 | READ_IC_INFO_NAND =0x68, 78 | READ_ONBOARD_NAND =0x73, 79 | GET_FW_STATUS =0x9B, //0x9A: Set //0x9B:Get 80 | } USB_CMD; 81 | 82 | typedef struct ChipInfo { 83 | char TypeName[100]; 84 | char ICType[16]; 85 | size_t UniqueID; 86 | size_t ChipIDMask; 87 | char Class[100]; 88 | char Description[256]; 89 | 90 | char Manufacturer[100]; 91 | char ManufactureUrl[100]; 92 | char Voltage[20]; 93 | char Clock[20]; 94 | char ProgramIOMethod[20]; 95 | char type[16]; 96 | 97 | size_t ManufactureID; 98 | size_t JedecDeviceID; 99 | size_t AlternativeID; 100 | 101 | size_t ChipSizeInByte; 102 | size_t SectorSizeInByte; 103 | size_t PageSizeInByte; 104 | size_t BlockSizeInByte; 105 | 106 | size_t MaxErasableSegmentInByte; 107 | 108 | size_t AddrWidth; 109 | size_t ReadDummyLen; 110 | 111 | bool DualID; 112 | size_t VppSupport; 113 | bool MXIC_WPmode; 114 | size_t IDNumber; 115 | size_t RDIDCommand; 116 | size_t Timeout; 117 | size_t VoltageInMv; 118 | // SPI NAND 119 | size_t SpareSizeInByte;//NAND 120 | size_t nCA_Rd; 121 | size_t nCA_Wr; 122 | size_t DefaultDataUnitSize; 123 | size_t DefaultErrorBits; 124 | size_t BBMark; 125 | size_t SupportedProduct; 126 | size_t ECCParityGroup; 127 | size_t ECCProtectStartAddr; 128 | size_t ECCProtectDis; 129 | size_t ECCProtectLength; 130 | bool ECCEnable; 131 | 132 | bool QPIEnable; 133 | size_t ChipEraseTime; 134 | size_t EraseCmd; 135 | size_t ProgramCmd; 136 | size_t ReadCmd; 137 | size_t ProtectBlockMask; 138 | size_t UnlockCmd; 139 | size_t RDSRCnt; 140 | size_t WRSRCnt; 141 | size_t WRSRCmd; 142 | size_t RDSRCmd; 143 | size_t WRCRCmd; 144 | size_t RDCRCmd; 145 | size_t QEbitAddr; 146 | bool SupportLUT; 147 | 148 | } CHIP_INFO; 149 | #pragma pack(push,1) 150 | typedef struct spi_nand_info{ 151 | unsigned short Hearder;//A1A1 152 | unsigned short Version;//0x0001 153 | unsigned short Type;//0x0001 for spi nand 154 | unsigned short STsize;//size of this struct 155 | unsigned int ChipID; 156 | unsigned int ChipIDMask; 157 | unsigned short RealPagesize; //for real OP. include spare area size , when scanBB , this size not include spare area size 158 | unsigned short PagesPerBlock; 159 | unsigned int Blocks; 160 | //24 161 | 162 | unsigned int BlockIndex; 163 | unsigned int BlockCount; 164 | 165 | //32 166 | unsigned short EN_spareArea; 167 | unsigned short SPA_pagesize; //spare area pagesize 168 | unsigned short MA_pagesize; //main area pagesize 169 | 170 | unsigned char BeCmd; 171 | unsigned char RdCmd; 172 | unsigned char WrCmd; 173 | unsigned char AddrLen; 174 | unsigned char nCA_Rd; 175 | unsigned char nCA_Wr; 176 | unsigned char Dummy; 177 | //44 178 | 179 | unsigned short MaxERR_bits; 180 | unsigned short BBMark; 181 | unsigned char BB_BYTE_TYPE;//0:not skip, 0x11:~0xFF, 0x10:~0x00, 0x21: ~0xFFFF, 0x20:~0x0000 182 | unsigned char BBM_TYPE;//0:no BBM, 1: skip BB, 2:others 183 | 184 | unsigned short BBK_TOTAL;//only useful after BB scan. 185 | 186 | //52 187 | unsigned char StartBB; //set 0: no start BB,set 1, start BB scan. If ready, device will set 2. 188 | unsigned char UNprotect_type;// 1 enable. other default 189 | unsigned char En_internalECC;//0 disable, 1 enable. 0xff default 190 | //55 191 | unsigned int EraseStartBlock; 192 | unsigned int EraseEndBlock; 193 | //63 194 | unsigned char EraseMode;//0:not enable; 1: force erase; 2: skip bad block(must Start BB before) 195 | //64 196 | unsigned char EraseStatus;//0:Pass; 1: Fail 197 | 198 | unsigned char saveSTA; //enable save STA 199 | //66 200 | unsigned short rfu0; 201 | unsigned short perPageSizeForErrBit; 202 | unsigned char ReadSatus_mode;//1:w25N512G 203 | 204 | unsigned short VFMODE; //[3]==0:old:[3:0]MaxErrorBit, [15:4]:ErrorBit reset size; size={256xErrorBit[7:4]+ErrorBit[15:8]} 205 | //[3]==1:new: [15:8]Max Error Bit allowed 206 | //[2:0]==MODE 0:DS 1:DSDSDS..DS 2:DDDD...DSSSS...S 3:DDD...D 4: for internal ECC skip 207 | 208 | unsigned short VFCOFGL; //for mode 0,1,2,3: 209 | unsigned short VFCOFGH; //[31:16]: Data Unit size; 210 | //[15:0]: Ecc Unit size; 211 | //for mode 4: 212 | //[31:16]: User Data mask 213 | //[15:0]: Internal ECC address mask 214 | unsigned short staPVpagesize; 215 | unsigned int staPVpages; 216 | unsigned int staPVsize; 217 | unsigned char rfu[34]; 218 | unsigned short crc; 219 | }SELECT_SPI_NAND_INFO; 220 | #pragma pack(pop) 221 | 222 | struct EraseCommand 223 | { 224 | unsigned char ChipErase; 225 | unsigned char SectorErase; 226 | unsigned char DieErase; 227 | unsigned char RFU2; 228 | } ; 229 | struct ReadCommand 230 | { 231 | unsigned char SingleRead; 232 | unsigned char DualRead; 233 | unsigned char QuadRead; 234 | unsigned char RFU3; 235 | } ; 236 | struct ProgramCommand 237 | { 238 | unsigned char SingleProgram; 239 | unsigned char DualProgram; 240 | unsigned char QuadProgram; 241 | unsigned char RFU4; 242 | } ; 243 | 244 | struct CNANDContext 245 | { 246 | //bool is_S25FL128P_256KSectors; 247 | const unsigned short cbyRLine[5];// = {0x111,0x121,0x122,0x141,0x144}; 248 | const unsigned short cbyPLine[5] ;//= {0x111,0x111,0x111,0x141,0x144}; 249 | unsigned int realPageSize; 250 | unsigned int realSpareAreaSize; 251 | unsigned int realBlockSize; 252 | unsigned int realChipSize; 253 | struct EraseCommand EraseCmd; 254 | struct ReadCommand ReadCmd; 255 | struct ProgramCommand ProgramCmd; 256 | }; 257 | 258 | struct Block_Parameter 259 | { 260 | unsigned int block_sart; 261 | unsigned int block_cnt; 262 | unsigned int block_end; 263 | }; 264 | 265 | struct ProgrgmPatitionTable 266 | { 267 | unsigned int pt_cnt; 268 | struct Block_Parameter PT[]; 269 | }; 270 | 271 | struct BadBlockTable 272 | { 273 | unsigned short cnt; 274 | unsigned short bbt[255]; 275 | }; 276 | 277 | //third field of RQ 278 | #define CTRL_TIMEOUT 3000 ///< time out for control pipe or for firmwire 279 | 280 | // fourth field of RQ 281 | #define RESULT_IN 0x01 ///< result in or not 282 | #define NO_RESULT_IN 0x00 283 | #define GET_REGISTER 0x01 ///< get register value or not 284 | #define NO_REGISTER 0x00 285 | #define RFU 0x00 286 | 287 | // bulk write mode 288 | #define PAGE_PROGRAM 0x01 ///< pp via bulk pipes 289 | #define PAGE_WRITE 0x02 ///< pw via bulk pipes 290 | #define AAI_1_BYTE 0x03 291 | #define AAI_2_BYTE 0x04 292 | #define PP_128BYTE 0x05 293 | #define PP_AT26DF041 0x06 ///< PP AT26DF041 294 | #define PP_SB_FPGA 0x07 ///< Silicon Blue FPGA 295 | #define MODE_NUMONYX_PCM 0x08 ///< Mode_Numonyx_pcm 296 | #define PP_4ADR_256BYTE 0x09 297 | #define PP_32BYTE 0x0A 298 | #define PP_4ADDR_256BYTE_12 0x0B 299 | #define PP_4ADDR_256BYTE_MICROM 0x0C 300 | #define PP_4ADDR_256BYTE_S70FS01GS 0x0D 301 | #define PP_PROGRAM_DIE2 0x0E 302 | #define PP_PROGRAM_MX25L202XX 0x0F 303 | #define PP_PROGRAM_ANYSIZE_PAGESIZE 0x11 304 | 305 | // bulk read mode 306 | #define BULK_NORM_READ 0x01 ///< read via bulk pipes 307 | #define BULK_FAST_READ 0x02 ///< fast read via bulk pipes 308 | #define BULK_AT45xx_READ 0x03 ///< fast read via bulk pipes 309 | #define BULK_4BYTE_FAST_READ 0x04 ///< For size is bigger than 128Mb 310 | #define BULK_4BYTE_FAST_READ_MICRON 0x05 //for 0x0c 311 | #define BULK_FAST_READ_DIE2 0x06 ///< fast read via bulk pipes 312 | #define BULK_4BYTE_NORM_READ 0x07 //FW 7.2.26_FPGA_D 313 | #define BULK_QUAD_READ 0x09 //FW 7.2.29 314 | 315 | 316 | //for flash card 317 | #define POLLING 0x02 ///< polling 318 | #define SET_VPP 0x03 ///< set vpp 319 | #define VPP_OFF 0x00 ///< vpp value 320 | #define VPP_9V 0x01 321 | #define VPP_12V 0x02 322 | 323 | #define SET_TARGET_FLASH 0x04 ///< set target FLASH_TRAY 324 | #define APPLICATION_MEMORY_1 0x00 ///< application memory chip 1 325 | #define FLASH_CARD 0x01 ///< flash card 326 | #define APPLICATION_MEMORY_2 0x02 ///< application memory chip 2 327 | 328 | //for io & LED 329 | #define SET_IO 0x07 ///< request 330 | //IO number 331 | #define IO_1 0x01 332 | #define IO_2 0x02 333 | #define IO_3 0x04 334 | #define IO_4 0x08 335 | //led number 336 | #define LED_RED 0x01 337 | #define LED_GREEN 0x02 338 | #define LED_ORANGE 0x04 339 | 340 | #define SUPPORT_ST 341 | #define SUPPORT_SST 342 | #define SUPPORT_WINBOND 343 | #define SUPPORT_PMC 344 | #define SUPPORT_SPANSION 345 | #define SUPPORT_MACRONIX 346 | #define SUPPORT_EON 347 | #define SUPPORT_ATMEL 348 | #define SUPPORT_AMIC 349 | #define SUPPORT_ESMT 350 | #define SUPPORT_INTEL 351 | #define SUPPORT_SANYO 352 | #define SUPPORT_TSI 353 | #define SUPPORT_FREESCALE 354 | #define SUPPORT_SILICONBLUE 355 | #define SUPPORT_NANTRONICS 356 | #define SUPPORT_ATO 357 | #define SUPPORT_FIDELIX 358 | #define SUPPORT_FUDAN 359 | #define SUPPORT_GIGADEVICE 360 | // memory support list 361 | #ifdef SUPPORT_NANTRONICS 362 | #define SUPPORT_NANTRONICS_N25Sxx "N25Sxx" 363 | #endif 364 | 365 | #ifdef SUPPORT_ATO 366 | #define SUPPORT_ATO_ATO25Qxx "ATO25Qxx" 367 | #endif 368 | 369 | #ifdef SUPPORT_GIGADEVICE 370 | #define SUPPORT_GIGADEVICE_GD25SXXX_LARGE "GD25Sxxx_Large" 371 | #define SUPPORT_GIGADEVICE_GD5F1GQ4xCx "GD5F1GQ4xCx" 372 | #endif 373 | 374 | 375 | #ifdef SUPPORT_ST 376 | #define SUPPORT_ST_M25PExx "M25PExx" 377 | #define SUPPORT_ST_M25Pxx "M25Pxx" 378 | #define SUPPORT_ST_M25Pxx_Large "M25Pxx_Large" 379 | #define SUPPORT_ST_M45PExx "M45PExx" 380 | #define SUPPORT_NUMONYX_Alverstone "Alverstone" 381 | #define SUPPORT_NUMONYX_N25Qxxx_Large "N25Qxxx_Large" 382 | #define SUPPORT_NUMONYX_N25Qxxx_Large_2Die "N25Qxxx_Large_2Die" 383 | #define SUPPORT_NUMONYX_N25Qxxx_Large_4Die "N25Qxxx_Large_4Die" 384 | #endif 385 | 386 | #ifdef SUPPORT_SST 387 | #define SUPPORT_SST_25xFxxA "25xFxxA" 388 | #define SUPPORT_SST_25xFxxB "25xFxxB" 389 | #define SUPPORT_SST_25xFxxC "25xFxxC" 390 | #define SUPPORT_SST_25xFxx "25xFxx" 391 | #define SUPPORT_SST_26xFxxC "26VFxxC" 392 | #endif 393 | 394 | #ifdef SUPPORT_WINBOND 395 | #define SUPPORT_WINBOND_W25Bxx "W25Bxx" 396 | #define SUPPORT_WINBOND_W25Pxx "W25Pxx" 397 | #define SUPPORT_WINBOND_W25Pxx_Large "W25Pxx_Large" 398 | #define SUPPORT_WINBOND_W25Qxx_Large "W25Qxx_Large" 399 | #define SUPPORT_WINBOND_W25Xxx "W25Xxx" 400 | #define SUPPORT_WINBOND_W25Mxx_Large "W25Mxx_Large" 401 | #endif 402 | 403 | #ifdef SUPPORT_PMC 404 | #define SUPPORT_PMC_PM25LVxxx "PM25LVxxx" 405 | #define SUPPORT_PMC_PM25Wxxx "PM25Wxxx" 406 | #endif 407 | 408 | #ifdef SUPPORT_SPANSION 409 | #define SUPPORT_SPANSION_S25FLxx "S25FLxxx" 410 | #define SUPPORT_SPANSION_S25FLxx_Large "S25FLxxx_Large" 411 | #define SUPPORT_SPANSION_S25FLxxS_Large "S25FSxxxS_Large" 412 | #define SUPPORT_SPANSION_S25FLxxL_Large "S25FLxxxL_Large" 413 | #define SUPPORT_SPANSION_S70FSxx_Large "S70FSxxx_Large" 414 | #endif 415 | 416 | #ifdef SUPPORT_MACRONIX 417 | #define SUPPORT_MACRONIX_MX25Lxxx "MX25Lxxx" 418 | #define SUPPORT_MACRONIX_MX25Lxxx_Large "MX25Lxxx_Large" 419 | #define SUPPORT_MACRONIX_MX25Lxxx_PP32 "MX25Lxxx_PP32" 420 | #endif 421 | 422 | #ifdef SUPPORT_EON 423 | #define SUPPORT_EON_EN25Xxx "EN25Xxx" 424 | #define SUPPORT_EON_EN25QHxx_Large "EN25QHxx_Large" 425 | #endif 426 | 427 | #ifdef SUPPORT_ATMEL 428 | #define SUPPORT_ATMEL_AT26xxx "AT26xxx" 429 | #define SUPPORT_ATMEL_AT25Fxxx "AT25Fxxx" 430 | #define SUPPORT_ATMEL_AT25FSxxx "AT25FSxxx" 431 | #define SUPPORT_ATMEL_45DBxxxD "AT45DBxxxD" 432 | #define SUPPORT_ATMEL_45DBxxxB "AT45DBxxxB" 433 | #endif 434 | 435 | #ifdef SUPPORT_AMIC 436 | #define SUPPORT_AMIC_A25Lxxx "A25Lxxx" 437 | #define SUPPORT_AMIC_A25LQxxx "A25LQxxx" 438 | #endif 439 | 440 | #ifdef SUPPORT_ESMT 441 | #define SUPPORT_ESMT_F25Lxx "F25Lxx" 442 | #endif 443 | 444 | #ifdef SUPPORT_INTEL 445 | #define SUPPORT_INTEL_S33 "S33" 446 | #endif 447 | 448 | #ifdef SUPPORT_FREESCALE 449 | #define SUPPORT_FREESCALE_MCF "MCF" 450 | #endif 451 | 452 | #ifdef SUPPORT_SANYO 453 | #define SUPPORT_SANYO_LE25FWxxx "LE25FWxxx" 454 | #endif 455 | 456 | #ifdef SUPPORT_TSI 457 | #define SUPPORT_TSI_TS25Lxx "TS25Lxx" 458 | #define SUPPORT_TSI_TS25Lxx_0A "TS25Lxx_0A" 459 | #endif 460 | 461 | #ifdef SUPPORT_SILICONBLUE 462 | #define SUPPORT_SILICONBLUE_iCE65 "iCE65" 463 | #endif 464 | 465 | #ifdef SUPPORT_FIDELIX 466 | #define SUPPORT_FIDELIX_FM25Qxx "FM25Qxx" 467 | #endif 468 | 469 | #ifdef SUPPORT_FUDAN 470 | #define SUPPORT_FUDAN_FM25Fxx "FM25Fxx" 471 | #endif 472 | 473 | // for usb 474 | #define USB_TIMEOUT 800000 ///< time out value for usb EP2 475 | 476 | // for SR reads 477 | #define MAX_TRIALS 0x80000 478 | 479 | #define BIT0 0x01 480 | #define BIT1 0x02 481 | #define BIT2 0x04 482 | #define BIT3 0x08 483 | #define BIT4 0x10 484 | #define BIT5 0x20 485 | #define BIT6 0x40 486 | #define BIT7 0x80 487 | #define BIT8 0x100 488 | #define BIT9 0x200 489 | #define BIT10 0x400 490 | #define BIT11 0x800 491 | #define BIT12 0x1000 492 | #define BIT13 0x2000 493 | #define BIT14 0x4000 494 | #define BIT15 0x8000 495 | #define BIT16 0x10000 496 | #define BIT17 0x20000 497 | #define BIT18 0x40000 498 | 499 | 500 | #define ERASE BIT0 501 | #define PROGRAM BIT1 502 | #define VERIFY BIT2 503 | #define BLANK BIT3 504 | #define DETECT BIT4 505 | #define BATCH BIT5 506 | #define TYPE BIT6 507 | #define FSUM BIT7 508 | #define CSUM BIT8 509 | #define READ_TO_FILE BIT9 510 | #define BLINK BIT10 511 | #define DEVICE_ID BIT11 512 | #define LIST_TYPE BIT12 513 | #define LOADFILEWITHVERIFY BIT13 514 | #define CHECK_INFO BIT14 515 | #define SPECIAL_ERASE BIT15 516 | #define SPECIAL_PROGRAM BIT16 517 | #define SPECIAL_AUTO BIT17 518 | #define BATCH_WITH_FORCEERASE BIT18 519 | 520 | struct CAddressRange { 521 | size_t start; 522 | size_t end; 523 | size_t length; 524 | }; 525 | 526 | enum { 527 | SITE_NORMAL = 0, 528 | SITE_BUSY, 529 | SITE_ERROR, 530 | SITE_OK, 531 | }; 532 | 533 | enum { 534 | Seriase_45 = 0x08, 535 | Seriase_25 = 0x00, 536 | }; 537 | 538 | typedef enum { 539 | vccPOWEROFF = 0x00, 540 | 541 | vcc3_5V = 0x10, 542 | vcc2_5V = 0x11, 543 | vcc1_8V = 0x12, 544 | 545 | vccdo_nothing = 0xFF, 546 | 547 | } VCC_VALUE; 548 | 549 | typedef enum 550 | { 551 | IO_Single = 0x00, 552 | IO_Dual1 =0x01, 553 | IO_Dual2 =0x02,//sf600 not support 122 554 | IO_Quad1 =0x03, 555 | IO_Quad2 =0x04, 556 | IO_Quad3 =0x05, // Quad command 4-4-4 557 | IO_Octa1 =0x89, // Octal command for Macronix (888) 558 | IO_Octa2 =0x88, // Octal command for Micron (888) 559 | } IO_VALUE; 560 | 561 | 562 | enum { // value dedicated by the spec 563 | STARTUP_APPLI_SF_1 = 0, 564 | STARTUP_APPLI_CARD = 1, 565 | STARTUP_APPLI_SF_2 = 2, 566 | STARTUP_APPLI_SF_SKT = 3, 567 | 568 | STARTUP_SPECIFY_LATER = 0xFE, 569 | STARTUP_PREVIOUS = 0xFF 570 | }; 571 | 572 | enum { 573 | clk_24M = 0x00, 574 | clk_8M = 0x01, 575 | clk_12M = 0x02, 576 | clk_3M = 0x03, 577 | clk_2180K = 0x04, 578 | clk_1500K = 0x05, 579 | clk_750K = 0x06, 580 | clk_375K = 0x07, 581 | }; 582 | 583 | #endif //_MACRO_H 584 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of the DediProg project. 3 | # 4 | # 5 | 6 | # Make is silent per default, but 'make V=1' will show all compiler calls. 7 | Q:=@ 8 | ifneq ($(V),1) 9 | ifneq ($(Q),) 10 | .SILENT: 11 | endif 12 | endif 13 | 14 | PROGRAM = dpcmd 15 | CC ?= gcc 16 | PREFIX ?= /usr/local 17 | 18 | PKG_CONFIG ?= pkg-config 19 | 20 | CFLAGS ?= -O2 -Wall -std=gnu99 21 | CFLAGS += $(shell $(PKG_CONFIG) --cflags libusb-1.0 libxml-2.0) 22 | 23 | LDFLAGS ?= 24 | LDFLAGS += -lpthread 25 | LDFLAGS += $(shell $(PKG_CONFIG) --libs libusb-1.0 libxml-2.0) 26 | 27 | DEPDIR := .deps 28 | DEPFLAGS = -MT $@ -MMD -MP -MF $(DEPDIR)/$*.d 29 | 30 | SRCS = dpcmd.c usbdriver.c FlashCommand.c SerialFlash.c parse.c board.c project.c IntelHexFile.c MotorolaFile.c 31 | 32 | PROGRAMMER_OBJS := $(SRCS:%.c=%.o) 33 | 34 | all: $(PROGRAM) 35 | @printf "All done.\n" 36 | 37 | $(PROGRAM): $(PROGRAMMER_OBJS) 38 | @printf " LD $@\n" 39 | $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $^ $(LDFLAGS) 40 | 41 | %.o : %.c 42 | %.o : %.c $(DEPDIR)/%.d | $(DEPDIR) 43 | @printf " CC $@\n" 44 | $(CC) $(DEPFLAGS) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< 45 | 46 | $(DEPDIR): ; @mkdir -p $@ 47 | 48 | DEPFILES := $(SRCS:%.c=$(DEPDIR)/%.d) 49 | $(DEPFILES): 50 | 51 | include $(wildcard $(DEPFILES)) 52 | 53 | clean: 54 | rm -vf $(PROGRAM) $(PROGRAM).exe *.o 55 | rm -rvf $(DEPDIR) 56 | 57 | install: $(PROGRAM) 58 | [ $(shell id -u) -eq 0 ] || (echo "Error: install needs root privileges" && false) 59 | install -v -o 0 -g 0 -m 755 -d $(DESTDIR)$(PREFIX)/bin $(DESTDIR)$(PREFIX)/share/DediProg 60 | echo -n "install: " && install -v -o 0 -g 0 -m 0755 $(PROGRAM) $(DESTDIR)$(PREFIX)/bin/$(PROGRAM) 61 | ifneq ($(NOSTRIP),1) 62 | strip $(DESTDIR)$(PREFIX)/bin/$(PROGRAM) 63 | endif 64 | install -v -o 0 -g 0 -m 755 -d $(DESTDIR)$(PREFIX)/share/DediProg 65 | echo -n "install: " && install -v -o 0 -g 0 -m 0644 ChipInfoDb.dedicfg $(DESTDIR)$(PREFIX)/share/DediProg/ChipInfoDb.dedicfg 66 | install -v -o 0 -g 0 -m 755 -d $(DESTDIR)/etc/udev/rules.d 67 | echo -n "install: " && install -v -o 0 -g 0 -m 0644 60-dediprog.rules $(DESTDIR)/etc/udev/rules.d/60-dediprog.rules 68 | 69 | uninstall: 70 | [ $(shell id -u) -eq 0 ] || (echo "Error: uninstall needs root privileges" && false) 71 | rm -vf $(DESTDIR)$(PREFIX)/bin/$(PROGRAM) $(DESTDIR)$(PREFIX)/share/DediProg/ChipInfoDb.dedicfg $(DESTDIR)/etc/udev/rules.d/60-dediprog.rules 72 | [ -d "$(DESTDIR)$(PREFIX)/share/DediProg" ] && rmdir -vd $(DESTDIR)$(PREFIX)/share/DediProg || true 73 | 74 | # Run before every release / check-in to keep the source code tidy 75 | release: 76 | chmod 644 *.c *.h README.md Makefile LICENSE .gitignore ChipInfoDb.dedicfg 60-dediprog.rules 77 | clang-format -i -style=WebKit *.c *.h 78 | -------------------------------------------------------------------------------- /MotorolaFile.c: -------------------------------------------------------------------------------- 1 | //-------------------------------------------------------------------------------- 2 | //NAME 3 | //srec - S-record file and record format 4 | //DESCRIPTION 5 | 6 | //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. 7 | //The order of S-records within a file is of no significance and no particular order may be assumed. 8 | 9 | //The general format of an S-record follows: 10 | 11 | //+-------------------//------------------//-----------------------+ 12 | //| type | count | address | data | checksum | 13 | //+-------------------//------------------//-----------------------+ 14 | 15 | //type -- A char[2] field. These characters describe the type of record (S0, S1, S2, S3, S5, S7, S8, or S9). 16 | //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. 17 | 18 | //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. 19 | 20 | //data -- A char [0-64] field. These characters when paired and interpreted as hexadecimal values represent the memory loadable data or descriptive information. 21 | 22 | //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. 23 | 24 | //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. 25 | 26 | //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. 27 | 28 | //mname is char[20] and is the module name. 29 | //ver is char[2] and is the version number. 30 | //rev is char[2] and is the revision number. 31 | //description is char[0-36] and is a text comment. 32 | 33 | //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. 34 | //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. 35 | 36 | //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. 37 | 38 | //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. 39 | 40 | //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. 41 | 42 | //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. 43 | 44 | //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. 45 | 46 | //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. 47 | 48 | //EXAMPLE 49 | 50 | //Shown below is a typical S-record format file. 51 | 52 | //S00600004844521B 53 | //S1130000285F245F2212226A000424290008237C2A 54 | //S11300100002000800082629001853812341001813 55 | //S113002041E900084E42234300182342000824A952 56 | //S107003000144ED492 57 | //S5030004F8 58 | //S9030000FC 59 | //The file consists of one S0 record, four S1 records, one S5 record and an S9 record. 60 | 61 | //The S0 record is comprised as follows: 62 | 63 | //S0 S-record type S0, indicating it is a header record. 64 | //06 Hexadecimal 06 (decimal 6), indicating that six character pairs (or ASCII bytes) follow. 65 | //00 00 Four character 2-byte address field, zeroes in this example. 66 | 67 | //48 44 52 ASCII H, D, and R - "HDR". 68 | //1B The checksum. 69 | //The first S1 record is comprised as follows: 70 | //S1 S-record type S1, indicating it is a data record to be loaded at a 2-byte address. 71 | //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. 72 | //00 00 Four character 2-byte address field; hexidecimal address 0x0000, where the data which follows is to be loaded. 73 | //28 5F 24 5F 22 12 22 6A 00 04 24 29 00 08 23 7C Sixteen character pairs representing the actual binary data. 74 | //2A The checksum. 75 | //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. 76 | 77 | //The S5 record is comprised as follows: 78 | 79 | //S5 S-record type S5, indicating it is a count record indicating the number of S1 records 80 | //03 Hexadecimal 03 (decimal 3), indicating that three character pairs follow. 81 | //00 04 Hexadecimal 0004 (decimal 4), indicating that there are four data records previous to this record. 82 | //F8 The checksum. 83 | //The S9 record is comprised as follows: 84 | 85 | //S9 S-record type S9, indicating it is a termination record. 86 | //03 Hexadecimal 03 (decimal 3), indicating that three character pairs follow. 87 | //00 00 The address field, hexadecimal 0 (decimal 0) indicating the starting execution address. 88 | //FC The checksum. 89 | 90 | //-------------------------------------------------------------------------------- 91 | 92 | //Instructor Notes 93 | //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. 94 | //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. 95 | //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. 96 | //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), 97 | //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. 98 | #include "MotorolaFile.h" 99 | #include "project.h" 100 | #include 101 | #include 102 | #include 103 | #include 104 | 105 | extern unsigned char* pBufferforLoadedFile; 106 | extern unsigned long g_ulFileSize; 107 | 108 | bool S19FileToBin(const char* filePath, unsigned char* vData, unsigned long* FileSize, unsigned char PaddingByte) 109 | { 110 | FILE* Filin; /* input files */ 111 | 112 | /* size in bytes */ 113 | const long MEMORY_SIZE = 1024 * 1024 * 256; 114 | const long ADDRESS_MASK = 0xFFFFFFFF; 115 | const int MAX_LINE_SIZE = 512; 116 | 117 | const int CKS_8 = 0; 118 | 119 | int PadByte = PaddingByte; 120 | 121 | /* line inputted from file */ 122 | char Line[MAX_LINE_SIZE]; 123 | 124 | /* flag that a file was read */ 125 | bool Enable_Checksum_Error = false; 126 | 127 | /* cmd-line parameter # */ 128 | unsigned char* p; 129 | unsigned int i; 130 | 131 | /* Application specific */ 132 | 133 | unsigned int Nb_Bytes; 134 | unsigned int Address, Lowest_Address, Highest_Address, Starting_Address; 135 | unsigned int Phys_Addr, sType; 136 | unsigned int temp; 137 | 138 | bool Starting_Address_Setted = false; 139 | 140 | int temp2; 141 | 142 | unsigned char Data_Str[MAX_LINE_SIZE]; 143 | unsigned char Checksum = 0; 144 | 145 | unsigned short int wCKS; 146 | unsigned short int w; 147 | unsigned int Cks_Type = CKS_8; 148 | unsigned int Cks_Start, Cks_End, Cks_Addr, Cks_Value; 149 | bool Cks_range_set = false; 150 | bool Cks_Addr_set = false; 151 | 152 | /* Just a normal file name */ 153 | Filin = fopen(filePath, "rt"); 154 | if (Filin == 0L) 155 | return false; 156 | 157 | /* allocate a buffer */ 158 | unsigned char* Memory_Block = (unsigned char*)malloc(MEMORY_SIZE); 159 | memset(Memory_Block, PadByte, MEMORY_SIZE); 160 | 161 | /* To begin, assume the lowest address is at the end of the memory. 162 | subsequent addresses will lower this number. At the end of the input 163 | file, this value will be the lowest address. */ 164 | Lowest_Address = MEMORY_SIZE - 1; 165 | Highest_Address = 0; 166 | 167 | // int readCnt = 0 ; 168 | // int checkCnt = 0 ; 169 | 170 | /* Now read the file & process the lines. */ 171 | do /* repeat until EOF(Filin) */ 172 | { 173 | /* Read a line from input file. */ 174 | if (fgets(Line, MAX_LINE_SIZE, Filin) == NULL) 175 | break; 176 | 177 | /* Remove carriage return/line feed at the end of line. */ 178 | i = strlen(Line) - 1; 179 | 180 | if (Line[i] == '\n') 181 | Line[i] = '\0'; 182 | 183 | // check if this file is an S-file 184 | if ('S' != Line[0] && Line[0] != '\0') 185 | return false; 186 | 187 | /* Scan starting address and nb of bytes. */ 188 | /* Look at the record sType after the 'S' */ 189 | switch (Line[1]) { 190 | /* 16 bits address */ 191 | case '1': 192 | sscanf(Line, "S%1x%2x%4x%s", &sType, &Nb_Bytes, &Address, Data_Str); 193 | Checksum = Nb_Bytes + (Address >> 8) + (Address & 0xFF); 194 | 195 | /* Adjust Nb_Bytes for the number of data bytes */ 196 | Nb_Bytes = Nb_Bytes - 3; 197 | break; 198 | 199 | /* 24 bits address */ 200 | case '2': 201 | sscanf(Line, "S%1x%2x%6x%s", &sType, &Nb_Bytes, &Address, Data_Str); 202 | Checksum = Nb_Bytes + (Address >> 16) + (Address >> 8) + (Address & 0xFF); 203 | 204 | /* Adjust Nb_Bytes for the number of data bytes */ 205 | Nb_Bytes = Nb_Bytes - 4; 206 | break; 207 | 208 | /* 32 bits address */ 209 | case '3': 210 | sscanf(Line, "S%1x%2x%8x%s", &sType, &Nb_Bytes, &Address, Data_Str); 211 | Checksum = Nb_Bytes + (Address >> 24) + (Address >> 16) + (Address >> 8) + (Address & 0xFF); 212 | 213 | /* Adjust Nb_Bytes for the number of data bytes */ 214 | Nb_Bytes = Nb_Bytes - 5; 215 | break; 216 | 217 | default: 218 | break; // 20040617+ Added to remove GNU compiler warning about label at end of compound statement 219 | } 220 | 221 | p = Data_Str; 222 | 223 | /* If we're reading the last record, ignore it. */ 224 | switch (sType) { 225 | /* Data record */ 226 | case 1: 227 | case 2: 228 | case 3: 229 | Phys_Addr = Address & ADDRESS_MASK; 230 | 231 | /* Check that the physical address stays in the buffer's range. */ 232 | if ((Phys_Addr + Nb_Bytes) <= MEMORY_SIZE - 1) { 233 | /* Set the lowest address as base pointer. */ 234 | if (Phys_Addr < Lowest_Address) 235 | Lowest_Address = Phys_Addr; 236 | 237 | /* Same for the top address. */ 238 | temp = Phys_Addr + Nb_Bytes - 1; 239 | 240 | if (temp > Highest_Address) 241 | Highest_Address = temp; 242 | 243 | /* Read the Data bytes. */ 244 | for (i = Nb_Bytes; i > 0; i--) { 245 | sscanf((const char*)(p), "%2x", &temp2); 246 | p += 2; 247 | Memory_Block[Phys_Addr++] = temp2; 248 | Checksum = (Checksum + temp2) & 0xFF; 249 | }; 250 | 251 | /* Read the Checksum value. */ 252 | sscanf((const char*)(p), "%2x", &temp2); 253 | 254 | /* Verify Checksum value. */ 255 | Checksum = (0xFF - Checksum) & 0xFF; 256 | 257 | if ((temp2 != Checksum) && Enable_Checksum_Error) { 258 | } 259 | } else { 260 | //fprintf(stderr,"Data record skipped at %8X\n",Phys_Addr); 261 | } 262 | break; 263 | 264 | /* Ignore all other records */ 265 | default: 266 | break; // 20040617+ Added to remove GNU compiler warning about label at end of compound statement 267 | } 268 | } while (!feof(Filin)); 269 | fclose(Filin); 270 | /*-----------------------------------------------------------------------------*/ 271 | 272 | // fprintf(stdout,"Lowest address = %08X\n",Lowest_Address); 273 | // fprintf(stdout,"Highest address = %08X\n",Highest_Address); 274 | // fprintf(stdout,"Pad Byte = %X\n", PadByte); 275 | 276 | wCKS = 0; 277 | if (!Cks_range_set) { 278 | Cks_Start = Lowest_Address; 279 | Cks_End = Highest_Address; 280 | } 281 | switch (Cks_Type) { 282 | case 0: 283 | 284 | for (i = Cks_Start; i <= Cks_End; i++) { 285 | wCKS += Memory_Block[i]; 286 | } 287 | 288 | //fprintf(stdout,"8-bit Checksum = %02X\n",wCKS & 0xff); 289 | if (Cks_Addr_set) { 290 | wCKS = Cks_Value - (wCKS - Memory_Block[Cks_Addr]); 291 | Memory_Block[Cks_Addr] = (unsigned char)(wCKS & 0xff); 292 | //fprintf(stdout,"Addr %08X set to %02X\n",Cks_Addr, wCKS & 0xff); 293 | } 294 | break; 295 | 296 | case 2: 297 | 298 | for (i = Cks_Start; i <= Cks_End; i += 2) { 299 | w = Memory_Block[i + 1] | ((unsigned short)Memory_Block[i] << 8); 300 | wCKS += w; 301 | } 302 | 303 | //fprintf(stdout,"16-bit Checksum = %04X\n",wCKS); 304 | if (Cks_Addr_set) { 305 | w = Memory_Block[Cks_Addr + 1] | ((unsigned short)Memory_Block[Cks_Addr] << 8); 306 | wCKS = Cks_Value - (wCKS - w); 307 | Memory_Block[Cks_Addr] = (unsigned char)(wCKS >> 8); 308 | Memory_Block[Cks_Addr + 1] = (unsigned char)(wCKS & 0xff); 309 | //fprintf(stdout,"Addr %08X set to %04X\n",Cks_Addr, wCKS); 310 | } 311 | break; 312 | 313 | case 1: 314 | 315 | for (i = Cks_Start; i <= Cks_End; i += 2) { 316 | w = Memory_Block[i] | ((unsigned short)Memory_Block[i + 1] << 8); 317 | wCKS += w; 318 | } 319 | 320 | //fprintf(stdout,"16-bit Checksum = %04X\n",wCKS); 321 | if (Cks_Addr_set) { 322 | w = Memory_Block[Cks_Addr] | ((unsigned short)Memory_Block[Cks_Addr + 1] << 8); 323 | wCKS = Cks_Value - (wCKS - w); 324 | Memory_Block[Cks_Addr + 1] = (unsigned char)(wCKS >> 8); 325 | Memory_Block[Cks_Addr] = (unsigned char)(wCKS & 0xff); 326 | //fprintf(stdout,"Addr %08X set to %04X\n",Cks_Addr, wCKS); 327 | } 328 | 329 | default: 330 | break; 331 | } 332 | 333 | if (Starting_Address_Setted) { 334 | Lowest_Address = Starting_Address; 335 | } 336 | 337 | if (pBufferforLoadedFile != NULL) 338 | free(pBufferforLoadedFile); 339 | // pBufferforLoadedFile=(unsigned char*)malloc(Highest_Address-Lowest_Address+1); 340 | // g_ulFileSize=Highest_Address -Lowest_Address+ 1; 341 | // memcpy(pBufferforLoadedFile,Memory_Block+Lowest_Address,Highest_Address-Lowest_Address+1); 342 | pBufferforLoadedFile = (unsigned char*)malloc(Highest_Address + 1); 343 | g_ulFileSize = Highest_Address + 1; 344 | memcpy(pBufferforLoadedFile, Memory_Block, Highest_Address + 1); 345 | 346 | free(Memory_Block); 347 | return true; 348 | } 349 | 350 | bool BinToS19File(const char* filePath, unsigned char* vData, unsigned long FileSize) 351 | { 352 | //ANSI only 353 | FILE* FileOut; /* input files */ 354 | FileOut = fopen(filePath, "wt"); 355 | if (FileOut == NULL) 356 | return false; 357 | 358 | int i; 359 | int chksum; 360 | int total = 0; 361 | int addr = 0x00000000; 362 | long l1total = FileSize; 363 | unsigned char recbuf[32]; 364 | char s19buf[128]; 365 | 366 | while (l1total >= 32) { 367 | // copy data 368 | total = 32; 369 | memcpy(recbuf, vData + addr, total); 370 | 371 | chksum = total + 5; /* total bytes in this record */ 372 | chksum += addr & 0xff; 373 | chksum += (addr >> 8) & 0xff; 374 | chksum += (addr >> 16) & 0xff; 375 | chksum += (addr >> 24) & 0xff; 376 | 377 | fprintf(FileOut, "S3"); 378 | fprintf(FileOut, "%02X%08X", total + 5, addr); 379 | 380 | memset(s19buf, 0, sizeof(s19buf)); 381 | for (i = 0; i < total; i++) { 382 | chksum += recbuf[i]; 383 | sprintf(s19buf + 2 * i, "%02X", (recbuf[i] & 0xff)); 384 | } 385 | fprintf(FileOut, "%s", s19buf); 386 | 387 | memset(s19buf, 0, sizeof(s19buf)); 388 | chksum = ~chksum; /* one's complement */ 389 | fprintf(FileOut, "%02X\n", (chksum & 0xff)); 390 | 391 | addr += 32; 392 | l1total -= 32; 393 | } 394 | if (l1total) { 395 | total = l1total; 396 | memcpy(recbuf, vData + addr, total); 397 | 398 | chksum = total + 5; /* total bytes in this record */ 399 | chksum += addr & 0xff; 400 | chksum += (addr >> 8) & 0xff; 401 | chksum += (addr >> 16) & 0xff; 402 | chksum += (addr >> 24) & 0xff; 403 | 404 | fprintf(FileOut, "S3"); /* record header preamble */ 405 | fprintf(FileOut, "%02X%08X", total + 5, addr); 406 | 407 | memset(s19buf, 0, sizeof(s19buf)); 408 | for (i = 0; i < total; i++) { 409 | chksum += recbuf[i]; 410 | sprintf(s19buf + 2 * i, "%02X", (recbuf[i] & 0xff)); 411 | } 412 | fprintf(FileOut, "%s", s19buf); 413 | 414 | memset(s19buf, 0, sizeof(s19buf)); 415 | chksum = ~chksum; /* one's complement */ 416 | fprintf(FileOut, "%02X\n", (chksum & 0xff)); 417 | 418 | addr += l1total; 419 | } 420 | 421 | fclose(FileOut); 422 | return true; 423 | } 424 | -------------------------------------------------------------------------------- /MotorolaFile.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef _MOTOROLA_FILE_H 4 | #define _MOTOROLA_FILE_H 5 | 6 | #include 7 | 8 | bool S19FileToBin(const char* filePath, unsigned char* vData, unsigned long* FileSize, unsigned char PaddingByte); 9 | bool BinToS19File(const char* filePath, unsigned char* vData, unsigned long FileSize); 10 | 11 | #endif //_MOTOROLA_FILE_H 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SF100Linux 2 | Linux software for Dediprog SF100 and SF600 SPI flash programmers 3 | 4 | ## Building 5 | To compile the project, first install required dependencies: 6 | - libusb-1.0 7 | - libxml-2.0 8 | - pkg-config - won't link to libusb without this package 9 | 10 | Change to the directory where the sources are located and build using make: 11 | ```bash 12 | $ cd SF100Linux 13 | $ make 14 | ``` 15 | or use 16 | ```bash 17 | $ make install 18 | ``` 19 | 20 | The resulting binary should be called `dpcmd` and located in the root of the 21 | source tree. There is no install target at the moment. 22 | 23 | ## Usage 24 | Most basic usage is writing a whole image file to a flash chip: 25 | ```bash 26 | $ ./dpcmd --auto image.bin --verify 27 | ``` 28 | 29 | This will automatically detect the chip, read out the chip contents, replace 30 | the ones that differ and perform a read and verification after writing. 31 | 32 | For more advanced usage see `dpcmd --help`. 33 | -------------------------------------------------------------------------------- /SerialFlash.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef SERIALFLASHS 4 | #define SERIALFLASHS 5 | 6 | #include "Macro.h" 7 | #include 8 | 9 | #define SerialFlash_FALSE -1 10 | #define SerialFlash_TRUE 1 11 | 12 | enum //list of all chip-specific instruction, for ST serial flash 13 | { 14 | WREN = 0x06, // Write Enable 15 | WRDI = 0x04, // Write Disable 16 | RDIDJ = 0x9F, //RDIDJ // Read Jedec ID , except 80 17 | RDSR = 0x05, // Read Status Register 18 | WRSR = 0x01, // Write Status Register 19 | READ = 0x03, // Byte Read 20 | FREAD = 0x0B, // Fast Read 21 | PP = 0x02, // Page Program 22 | SE = 0xD8, // Sector Erase 23 | CHIP_ERASE = 0xC7, //CHIP_ERASE // Bulk (or Chip) Erase 24 | DP = 0xB9, // Deep Power Down 25 | RDP = 0xAB, //RES // Release Deep Power Down 26 | RES = 0xAB, //RES // RDP and read signature 27 | RDSCUR = 0x2B, 28 | GBULK = 0x98, 29 | EN4B = 0xB7, 30 | EXIT4B = 0xE9, 31 | }; 32 | 33 | int SerialFlash_doWRSR(unsigned char cSR, int Index); 34 | 35 | int SerialFlash_doRDSR(unsigned char* cSR, int Index); 36 | 37 | void S70FSxxx_Large_waitForWEL(bool die1, int Index); 38 | int S70FSxxx_Large_doRDSR1V(bool die1, unsigned char* cSR, int Index); 39 | int S70FSxxx_Large_doRDCR2V(bool die1, unsigned char* cSR, int Index); 40 | void SerialFlash_waitForWEL(int Index); 41 | bool S70FSxxx_Large_waitForWIP(bool die1, int Index); 42 | bool SerialFlash_waitForWIP(int Index); 43 | 44 | int SerialFlash_doWREN(int Index); 45 | 46 | int SerialFlash_doWRDI(int Index); 47 | 48 | int SerialFlash_protectBlock(int bProtect, int Index); 49 | 50 | int SerialFlash_EnableQuadIO(int bEnable, int boRW, int Index); 51 | 52 | int SerialFlash_Enable4ByteAddrMode(int bEnable, int Index); 53 | 54 | int SerialFlash_rangeBlankCheck(struct CAddressRange* Range, int Index); 55 | 56 | int SerialFlash_rangeProgram(struct CAddressRange* AddrRange, unsigned char* vData, int Index); 57 | int SerialFlash_rangeRead(struct CAddressRange* AddrRange, unsigned char* vData, int Index); 58 | 59 | int SerialFlash_DoPolling(int Index); 60 | 61 | int SerialFlash_is_good(); 62 | int SerialFlash_batchErase_W25Mxx_Large(uintptr_t* vAddrs, size_t AddrSize, int Index); 63 | int SerialFlash_batchErase(uintptr_t* vAddrs, size_t AddrSize, int Index); 64 | 65 | int SerialFlash_rangeErase(unsigned char cmd, size_t sectionSize, struct CAddressRange* AddrRange, int Index); 66 | 67 | bool SerialFlash_chipErase(int Index); 68 | int SerialFlash_DieErase(int Index); 69 | 70 | int SerialFlash_bulkPipeProgram(struct CAddressRange* AddrRange, unsigned char* vData, unsigned char modeWrite, unsigned char WriteCom, int Index); 71 | 72 | int SerialFlash_bulkPipeProgram_twoDie(struct CAddressRange* AddrRange, unsigned char* vData, unsigned char modeWrite, unsigned char WriteCom, int Index); 73 | 74 | int SerialFlash_bulkPipeRead(struct CAddressRange* AddrRange, unsigned char* vData, unsigned char modeRead, unsigned char ReadCom, int Index); 75 | 76 | int SerialFlash_bulkPipeRead_Micron_4die(struct CAddressRange* AddrRange, unsigned char* vData, unsigned char modeRead, unsigned char ReadCom, int Index); 77 | 78 | int SerialFlash_bulkPipeRead_twoDie(struct CAddressRange* AddrRange, unsigned char* vData, unsigned char modeRead, unsigned char ReadCom, int Index); 79 | 80 | int SerialFlash_bulkPipeProgram_Micron_4Die(struct CAddressRange* AddrRange, unsigned char* vData, unsigned char modeRead, unsigned char ReadCom, int Index); 81 | bool SerialFlash_doSelectDie(unsigned char dieNum,int Index); 82 | void SerialFlash_SetCancelOperationFlag(); 83 | 84 | void SerialFlash_ClearCancelOperationFlag(); 85 | 86 | int SerialFlash_readSR(unsigned char* cSR, int Index); 87 | 88 | int SerialFlash_writeSR(unsigned char cSR, int Index); 89 | 90 | int SerialFlash_is_protectbits_set(int Index); 91 | bool SST25xFxxA_protectBlock(int bProtect, int Index); 92 | bool SST25xFxx_protectBlock(int bProtect, int Index); 93 | bool AT25FSxxx_protectBlock(int bProtect, int Index); 94 | bool CEN25QHxx_LargeEnable4ByteAddrMode(bool Enable4Byte, int Index); 95 | bool CN25Qxxx_LargeRDFSR(unsigned char* cSR, int Index); 96 | bool CN25Qxxx_LargeEnable4ByteAddrMode(bool Enable4Byte, int Index); 97 | bool CN25Qxxx_MutipleDIe_LargeWREAR(unsigned char cSR, int Index); 98 | bool CN25Qxxx_MutipleDIe_LargeRDEAR(unsigned char* cSR, int Index); 99 | bool CN25Qxxx_Large_doRDVCR(unsigned char* ucVCR, int Index); 100 | bool CN25Qxxx_Large_doWRVCR(unsigned char ucVCR, int Index); 101 | bool CN25Qxxx_Large_doRDENVCR(unsigned char* ucENVCR, int Index); 102 | bool CN25Qxxx_Large_doWRENVCR(unsigned char ucENVCR, int Index); 103 | bool CS25FLxx_LargeEnable4ByteAddrMode(bool Enable4Byte, int Index); 104 | bool CN25Qxxx_Large_4Die_WREAR(unsigned char cSR,int Index); 105 | bool CN25Qxxx_Large_4Die_RDEAR(unsigned char* cEAR,int Index); 106 | size_t GetChipSize(void); 107 | size_t GetPageSize(void); 108 | bool SerialFlash_StartofOperation(int Index); 109 | bool SerialFlash_EndofOperation(int Index); 110 | bool DownloadICInfoForNand(DWORD dwInfoLen, int USBIndex);//SF700 111 | bool Nand_ReadICInfo(SELECT_SPI_NAND_INFO *nandInfo, unsigned short *BBT, unsigned short *BBT_Cnt, int USBIndex); 112 | bool SPINAND_ScanBadBlock( unsigned short *BBT, unsigned short *BBT_Cnt, int USBIndex); 113 | bool SF_Nand_HSBSet( int Index); 114 | bool SPINAND_chipErase(int USBIndex); 115 | bool SPINAND_ProtectBlock(bool bProtect,int USBIndex); 116 | void DownloadICInfo(bool isErase, int USBIndex); 117 | bool SPINAND_RangeBlankCheck(const struct CAddressRange* Range,int USBIndex); 118 | bool SPINAND_RangeProgram(const struct CAddressRange* Range,int USBIndex); 119 | bool SPINAND_BlockProgram(const DWORD dwAddr, const unsigned char *pData, unsigned char modeWrite,unsigned char WriteCom,int USBIndex); 120 | bool SPINAND_EnableInternalECC(bool is_ENECC,int USBIndex); 121 | bool Nand_CaculateErrorBit(unsigned char *pData, unsigned char *pFile, unsigned int ptr_size); 122 | bool SPINAND_RangeVerify( const struct CAddressRange* AddrRange,int USBIndex); 123 | bool Nand_bulkPipeRead(const struct CAddressRange* AddrRange, unsigned char* pBuff,unsigned char modeRead,unsigned char ReadCom,int USBIndex); 124 | bool SPINAND_RangeRead(const struct CAddressRange* Range,unsigned char *pBuff, int USBIndex); 125 | bool SPINand_SpecialErase(unsigned int BlockIndex, unsigned int BlockCnt, int USBIndex); 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | #endif //SERIALFLASHS 134 | -------------------------------------------------------------------------------- /board.c: -------------------------------------------------------------------------------- 1 | #include "board.h" 2 | #include "FlashCommand.h" 3 | #include "project.h" 4 | #include "usbdriver.h" 5 | #include 6 | #define SerialFlash_FALSE -1 7 | #define SerialFlash_TRUE 1 8 | #define min(a, b) (a > b ? b : a) 9 | 10 | volatile bool g_bIsSF600[16] = {false}; 11 | volatile bool g_bIsSF700[16] = {false}; 12 | volatile bool g_bIsSF600PG2[16] = {false}; 13 | extern char g_board_type[8]; 14 | extern char g_FPGA_ver[8]; 15 | extern char g_FW_ver[10]; 16 | extern char g_HW_ver[8]; 17 | extern int g_firmversion; 18 | extern unsigned int g_IO1Select; 19 | extern unsigned int g_IO4Select; 20 | extern unsigned int g_Vcc; 21 | extern bool Is_NewUSBCommand(int Index); 22 | // extern int is_SF100nBoardVersionGreaterThan_5_2_0(int Index); 23 | // extern int is_SF600nBoardVersionGreaterThan_6_9_0(int Index); 24 | 25 | bool ReadSF700AndSF600PG2SN(unsigned char* Data, int Index) 26 | { 27 | CNTRPIPE_RQ rq; 28 | unsigned char vBuffer[6]; 29 | 30 | rq.Function = URB_FUNCTION_VENDOR_ENDPOINT; 31 | rq.Direction = VENDOR_DIRECTION_OUT; 32 | rq.Request = 0x71; 33 | rq.Value = 0; 34 | rq.Index = 0; 35 | rq.Length = 6; 36 | 37 | 38 | vBuffer[0]=0; 39 | vBuffer[1]=0; 40 | vBuffer[2]=0; 41 | vBuffer[3]=2; 42 | vBuffer[4]=0; 43 | vBuffer[5]=0; 44 | 45 | //must read twice 46 | if (OutCtrlRequest(&rq, vBuffer, 6, Index) == SerialFlash_FALSE) 47 | return false; 48 | //first 49 | unsigned char vBufferSN[512]; 50 | BulkPipeRead(vBufferSN, USB_TIMEOUT, Index); 51 | 52 | if (OutCtrlRequest(&rq, vBuffer, 6, Index) == SerialFlash_FALSE) 53 | return false; 54 | //second 55 | BulkPipeRead(vBufferSN, USB_TIMEOUT, Index); 56 | 57 | memcpy(Data, vBufferSN, 16); 58 | return true; 59 | } 60 | bool ReadOnBoardFlash(unsigned char* Data, bool ReadUID, int Index) 61 | { 62 | CNTRPIPE_RQ rq; 63 | unsigned char vBuffer[16]; 64 | 65 | rq.Function = URB_FUNCTION_VENDOR_ENDPOINT; 66 | rq.Direction = VENDOR_DIRECTION_IN; 67 | rq.Request = 0x05; 68 | if (Is_NewUSBCommand(Index)) { 69 | rq.Value = ReadUID; 70 | rq.Index = 0; 71 | } else { 72 | rq.Value = 0x00; 73 | rq.Index = ReadUID; 74 | } 75 | rq.Length = 16; 76 | 77 | if (InCtrlRequest(&rq, vBuffer, 16, Index) == SerialFlash_FALSE) { 78 | return false; 79 | } 80 | memcpy(Data, vBuffer, 16); 81 | return true; 82 | } 83 | 84 | void QueryBoard(int Index) 85 | { 86 | // printf("QueryBoard\n"); 87 | return; 88 | if (!Is_usbworking(Index)) { 89 | printf("Do not find SFxx programmer!!\n"); 90 | return; 91 | } 92 | 93 | CNTRPIPE_RQ rq; 94 | unsigned char vBuffer[32]; 95 | 96 | rq.Function = URB_FUNCTION_VENDOR_ENDPOINT; 97 | rq.Direction = VENDOR_DIRECTION_IN; 98 | rq.Request = PROGINFO_REQUEST; 99 | rq.Value = RFU; 100 | rq.Index = 0x00; 101 | rq.Length = (unsigned long)32; 102 | memset(vBuffer, '\0', 32); 103 | 104 | if (InCtrlRequest(&rq, vBuffer, 32, Index) == SerialFlash_FALSE) { 105 | printf("send fail\n"); 106 | return; 107 | } 108 | 109 | memcpy(g_board_type, &vBuffer[0], 8); 110 | } 111 | 112 | unsigned int GetFPGAVersion(int Index) 113 | { 114 | if ((strstr(g_board_type, "SF600PG2") == NULL)&& (strstr(g_board_type, "SF600") == NULL) && (strstr(g_board_type, "SF700") == NULL)) 115 | return -1; 116 | CNTRPIPE_RQ rq; 117 | 118 | unsigned int uiFPGAver = 0; 119 | unsigned char vDataPack[2]; 120 | 121 | rq.Function = URB_FUNCTION_VENDOR_ENDPOINT; 122 | rq.Direction = VENDOR_DIRECTION_IN; 123 | rq.Request = 0x1C; 124 | rq.Value = RFU; 125 | rq.Index = 0; 126 | rq.Length = 2; 127 | 128 | if (InCtrlRequest(&rq, vDataPack, 2, Index) == SerialFlash_FALSE) { 129 | return -1; 130 | } 131 | 132 | uiFPGAver = ((unsigned int)vDataPack[1] << 8 | vDataPack[0]); 133 | return uiFPGAver; 134 | } 135 | 136 | bool SetIO(unsigned char ioState, int Index) 137 | { 138 | CNTRPIPE_RQ rq; 139 | unsigned char vDataPack; // 1 bytes, in fact no needs 140 | 141 | rq.Function = URB_FUNCTION_VENDOR_ENDPOINT; 142 | rq.Direction = VENDOR_DIRECTION_OUT; 143 | rq.Request = SET_IO; 144 | 145 | if (Is_NewUSBCommand(Index)) { 146 | rq.Value = (ioState & 0x0F) | 0x70; 147 | rq.Index = 0; 148 | } else { 149 | rq.Value = ioState; 150 | rq.Index = 0x07; 151 | } 152 | rq.Length = 0; 153 | 154 | if (OutCtrlRequest(&rq, &vDataPack, 0, Index) == SerialFlash_FALSE) { 155 | return false; 156 | } 157 | 158 | return true; 159 | } 160 | 161 | bool SetTargetFlash(unsigned char StartupMode, int Index) 162 | { 163 | CNTRPIPE_RQ rq; 164 | unsigned char vInstruction; 165 | 166 | rq.Function = URB_FUNCTION_VENDOR_ENDPOINT; 167 | rq.Direction = VENDOR_DIRECTION_OUT; 168 | rq.Request = SET_TARGET_FLASH; 169 | rq.Value = StartupMode; 170 | rq.Index = 0; 171 | rq.Length = 0; 172 | 173 | if (OutCtrlRequest(&rq, &vInstruction, 0, Index) == SerialFlash_FALSE) { 174 | return false; 175 | } 176 | 177 | return true; 178 | } 179 | 180 | bool SetLEDProgBoard(size_t Color, int Index) 181 | { 182 | //printf("\n===>board.c ---- SetLEDProgBoard(Color=%ld,SetLEDProgBoard=%d)\n",Color,Index); 183 | if (!Is_usbworking(Index)) { 184 | return false; 185 | } 186 | 187 | CNTRPIPE_RQ rq; 188 | unsigned char vBuffer[16]; 189 | 190 | rq.Function = URB_FUNCTION_VENDOR_ENDPOINT; 191 | rq.Direction = VENDOR_DIRECTION_OUT; 192 | rq.Request = SET_IO; 193 | if (Is_NewUSBCommand(Index)) { 194 | rq.Value = Color | (g_IO1Select << 1); 195 | rq.Value = (rq.Value & 0xFFF7) | (g_IO4Select << 3); 196 | //rq.Value = (Color & 0xFFF7) | (g_IO1Select << 1) | (g_IO4Select << 3); 197 | rq.Index = 0; 198 | } else { 199 | rq.Value = 0x09; 200 | rq.Index = Color >> 8; // LED 0:ON 1:OFF Bit0:Green Bit1:Orange Bit2:Red 201 | } 202 | rq.Length = 0; 203 | 204 | if (OutCtrlRequest(&rq, vBuffer, 0, Index) == SerialFlash_FALSE) { 205 | return false; 206 | } 207 | 208 | return true; 209 | } 210 | bool SetGreenLEDOn(bool boOn, int Index) 211 | { 212 | return SetLEDProgBoard(boOn ? 0x0609 : 0x0709, Index); 213 | } 214 | 215 | bool SetOrangeLEDOn(bool boOn, int Index) 216 | { 217 | return SetLEDProgBoard(boOn ? 0x0509 : 0x0709, Index); 218 | } 219 | 220 | bool SetRedLEDOn(bool boOn, int Index) 221 | { 222 | return SetLEDProgBoard(boOn ? 0x0309 : 0x0709, Index); 223 | } 224 | 225 | bool SetLEDOnOff(size_t Color, int Index) 226 | { 227 | bool result = true; 228 | switch (Color) { 229 | case SITE_ERROR: 230 | result &= SetRedLEDOn(true, Index); 231 | break; 232 | case SITE_BUSY: 233 | result &= SetOrangeLEDOn(true, Index); 234 | break; 235 | case SITE_OK: 236 | result &= SetGreenLEDOn(true, Index); 237 | break; 238 | case SITE_NORMAL: 239 | result &= SetLEDProgBoard(0x0709, Index); // Turn off LED 240 | break; 241 | } 242 | return result; 243 | } 244 | 245 | bool SetCS(size_t value, int Index) 246 | { 247 | if (!Is_usbworking(Index)) { 248 | return false; 249 | } 250 | 251 | CNTRPIPE_RQ rq; 252 | unsigned char vBuffer; 253 | rq.Function = URB_FUNCTION_VENDOR_ENDPOINT; 254 | rq.Direction = VENDOR_DIRECTION_OUT; 255 | rq.Request = SET_CS; 256 | rq.Value = value; // 12MHz 257 | rq.Index = RFU; 258 | rq.Length = 0; 259 | 260 | if (OutCtrlRequest(&rq, &vBuffer, 0, Index) == SerialFlash_FALSE) { 261 | return false; 262 | } 263 | 264 | return true; 265 | } 266 | 267 | bool SetIOModeToSF600(size_t value, int Index) 268 | { 269 | if (!Is_usbworking(Index)) { 270 | return false; 271 | } 272 | 273 | CNTRPIPE_RQ rq; 274 | unsigned char vBuffer; 275 | rq.Function = URB_FUNCTION_VENDOR_ENDPOINT; 276 | rq.Direction = VENDOR_DIRECTION_OUT; 277 | rq.Request = SET_IOMODE; 278 | rq.Value = value; 279 | rq.Index = RFU; 280 | rq.Length = 0; 281 | 282 | if (OutCtrlRequest(&rq, &vBuffer, 0, Index) == SerialFlash_FALSE) { 283 | return false; 284 | } 285 | 286 | return true; 287 | } 288 | 289 | bool BlinkProgBoard(bool boIsV5, int Index) 290 | { 291 | if (!Is_usbworking(Index)) { 292 | return false; 293 | } 294 | 295 | SetGreenLEDOn(true, Index); 296 | 297 | Sleep(500); 298 | 299 | SetGreenLEDOn(false, Index); 300 | 301 | return true; 302 | } 303 | 304 | bool LeaveSF600Standalone(bool Enable, int Index) 305 | { 306 | if (!Is_usbworking(Index)) { 307 | return false; 308 | } 309 | 310 | CNTRPIPE_RQ rq; 311 | unsigned char vBuffer; 312 | rq.Function = URB_FUNCTION_VENDOR_ENDPOINT; 313 | rq.Direction = VENDOR_DIRECTION_OUT; 314 | rq.Request = SET_SA; 315 | rq.Value = Enable; 316 | rq.Index = RFU; 317 | rq.Length = 0; 318 | 319 | if (OutCtrlRequest(&rq, &vBuffer, 0, Index) == SerialFlash_FALSE) { 320 | return false; 321 | } 322 | Sleep(100); 323 | return true; 324 | } 325 | 326 | bool SetSPIClockValue(unsigned short v, int Index) 327 | { 328 | if (!Is_usbworking(Index)) 329 | return false; 330 | 331 | // send request 332 | CNTRPIPE_RQ rq; 333 | unsigned char vBuffer; 334 | rq.Function = URB_FUNCTION_VENDOR_ENDPOINT; 335 | rq.Direction = VENDOR_DIRECTION_OUT; 336 | rq.Request = SET_SPICLK; 337 | rq.Value = v; 338 | rq.Index = RFU; 339 | rq.Length = 0; 340 | 341 | if (OutCtrlRequest(&rq, &vBuffer, 0, Index) == SerialFlash_FALSE) 342 | return false; 343 | 344 | return true; 345 | } 346 | 347 | bool SetIOMOdeValue(int Index) 348 | { 349 | if (strstr(g_board_type, "SF100")) 350 | return true; 351 | if (!Is_usbworking(Index)) 352 | return false; 353 | 354 | // send request 355 | CNTRPIPE_RQ rq; 356 | unsigned char vBuffer; 357 | rq.Function = URB_FUNCTION_VENDOR_ENDPOINT; 358 | rq.Direction = VENDOR_DIRECTION_OUT; 359 | rq.Request = SET_IOMODE; 360 | rq.Value = 0;//single IO 361 | rq.Index = RFU; 362 | rq.Length = 0; 363 | 364 | if (OutCtrlRequest(&rq, &vBuffer, 0, Index) == SerialFlash_FALSE) 365 | return false; 366 | Sleep(200); 367 | return true; 368 | } 369 | 370 | unsigned int ReadUID(int Index) 371 | { 372 | if (!Is_usbworking(Index)) { 373 | return false; 374 | } 375 | unsigned int dwUID = 0; 376 | unsigned char vUID[16]; 377 | 378 | if (is_SF700_Or_SF600PG2(Index)) { 379 | if (ReadSF700AndSF600PG2SN(vUID, Index) == false) 380 | return false; 381 | 382 | 383 | dwUID = (unsigned int)vUID[2] << 16 | (unsigned int)vUID[1] << 8 | vUID[0]; 384 | return dwUID; 385 | 386 | } 387 | 388 | if ((g_bIsSF600[Index] == true) ) { 389 | if (ReadOnBoardFlash(vUID, false, Index) == false) 390 | return false; 391 | if (g_bIsSF600[Index] == true) 392 | dwUID = (unsigned int)vUID[0] << 16 | (unsigned int)vUID[1] << 8 | vUID[2]; 393 | else 394 | dwUID = (unsigned int)vUID[2] << 16 | (unsigned int)vUID[1] << 8 | vUID[0]; 395 | return dwUID; 396 | } 397 | 398 | CNTRPIPE_RQ rq; 399 | unsigned char vBuffer[3]; 400 | 401 | // read 402 | rq.Function = URB_FUNCTION_VENDOR_OTHER; 403 | rq.Direction = VENDOR_DIRECTION_IN; 404 | rq.Request = 0x7; 405 | rq.Value = 0; 406 | rq.Index = 0xEF00; 407 | rq.Length = 3; 408 | 409 | if (InCtrlRequest(&rq, vBuffer, 3, Index) == SerialFlash_FALSE) { 410 | return false; 411 | } 412 | 413 | dwUID = (unsigned int)vBuffer[0] << 16 | (unsigned int)vBuffer[1] << 8 | vBuffer[2]; 414 | return dwUID; 415 | } 416 | 417 | bool SetSPIClockDefault(int Index) 418 | { 419 | if (!Is_usbworking(Index)) 420 | return false; 421 | // send request 422 | CNTRPIPE_RQ rq; 423 | unsigned char vBuffer; 424 | rq.Function = URB_FUNCTION_VENDOR_ENDPOINT; 425 | rq.Direction = VENDOR_DIRECTION_OUT; 426 | rq.Request = SET_SPICLK; 427 | rq.Value = 0x02; // 12MHz 428 | rq.Index = 0; 429 | rq.Length = 0; 430 | 431 | if (OutCtrlRequest(&rq, &vBuffer, 0, Index) == SerialFlash_FALSE) { 432 | printf("Set SPI clock error\n"); 433 | return false; 434 | } 435 | 436 | return true; 437 | } 438 | 439 | bool SetVpp4IAP(bool bOn, int Index) 440 | { 441 | if (!Is_usbworking(Index)) 442 | return false; 443 | // send request 444 | CNTRPIPE_RQ rq; 445 | unsigned char vBuffer; 446 | 447 | rq.Function = URB_FUNCTION_VENDOR_OTHER; 448 | rq.Direction = VENDOR_DIRECTION_IN; 449 | rq.Request = bOn ? 0x0 : 0x01; 450 | rq.Value = 0; 451 | rq.Index = 0; 452 | rq.Length = 0x01; 453 | 454 | if (OutCtrlRequest(&rq, &vBuffer, 1, Index) == SerialFlash_FALSE) { 455 | return false; 456 | } 457 | 458 | Sleep(200); 459 | return true; 460 | } 461 | 462 | bool UnlockRASS(int Index) 463 | { 464 | if (!Is_usbworking(Index)) 465 | return false; 466 | 467 | // send request 468 | CNTRPIPE_RQ rq; 469 | unsigned char vBuffer; 470 | 471 | rq.Function = URB_FUNCTION_VENDOR_OTHER; 472 | rq.Direction = VENDOR_DIRECTION_IN; 473 | rq.Request = 0x03; 474 | rq.Value = 0; 475 | rq.Index = 0; 476 | rq.Length = 0x01; 477 | 478 | if (OutCtrlRequest(&rq, &vBuffer, 1, Index) == SerialFlash_FALSE) { 479 | return false; 480 | } 481 | return true; 482 | } 483 | 484 | unsigned char ReadManufacturerID(int Index) 485 | { 486 | if (!Is_usbworking(Index)) 487 | return false; 488 | 489 | if ((g_bIsSF600[Index] == true) || is_SF700_Or_SF600PG2(Index) == true) { 490 | unsigned char vUID[16]; 491 | if (ReadOnBoardFlash(vUID, false, Index) == false) 492 | return false; 493 | return vUID[3]; 494 | } 495 | 496 | CNTRPIPE_RQ rq; 497 | unsigned char vBuffer; 498 | 499 | // read 500 | rq.Function = URB_FUNCTION_VENDOR_OTHER; 501 | rq.Direction = VENDOR_DIRECTION_IN; 502 | rq.Request = 0x7; 503 | rq.Value = 0; 504 | rq.Index = 0xEF03; 505 | rq.Length = 1; 506 | 507 | if (InCtrlRequest(&rq, &vBuffer, 1, Index) == SerialFlash_FALSE) { 508 | return false; 509 | } 510 | return vBuffer; 511 | } 512 | 513 | bool EraseST7Sectors(bool bSect1, int Index) 514 | { 515 | if (!Is_usbworking(Index)) 516 | return false; 517 | 518 | // send request 519 | CNTRPIPE_RQ rq; 520 | unsigned char vBuffer; 521 | 522 | rq.Function = URB_FUNCTION_VENDOR_OTHER; 523 | rq.Direction = VENDOR_DIRECTION_IN; 524 | rq.Request = bSect1 ? 0x04 : 0x05; 525 | rq.Value = 0; 526 | rq.Index = 0; 527 | rq.Length = 0x01; 528 | 529 | if (OutCtrlRequest(&rq, &vBuffer, 1, Index) == SerialFlash_FALSE) { 530 | return false; 531 | } 532 | return true; 533 | } 534 | 535 | bool ProgramSectors(const char* sFilePath, bool bSect1, int Index) 536 | { 537 | const unsigned int iSect1StartAddr = 0xE000; 538 | const unsigned int iSect2StartAddr = 0x8000; 539 | const unsigned int iSect1Size = 0x1000; 540 | const unsigned int iSect2Size = 0x6000; 541 | 542 | unsigned char* pBuffer = NULL; 543 | unsigned char* pTmp = NULL; 544 | FW_INFO fw_info; 545 | FILE* pFile; 546 | size_t lSize; 547 | unsigned char Data; 548 | 549 | unsigned int iStartAddr = bSect1 ? iSect1StartAddr : iSect2StartAddr; 550 | unsigned int Size, tmp; 551 | unsigned int uiIndex = 0; 552 | 553 | // prog sectors 554 | CNTRPIPE_RQ rq; 555 | 556 | pFile = fopen(sFilePath, "rb"); 557 | if (pFile == NULL) { 558 | printf("Can not open %s \n", sFilePath); 559 | return false; 560 | } 561 | 562 | fseek(pFile, 0, SEEK_SET); 563 | lSize = fread((unsigned char*)&fw_info, 1, sizeof(FW_INFO), pFile); 564 | if (lSize != sizeof(FW_INFO)) 565 | printf("Possible read length error %s\n", sFilePath); 566 | 567 | if (bSect1 == true) { 568 | Size = iSect1Size; 569 | uiIndex = fw_info.FirstIndex; 570 | } else { 571 | Size = iSect2Size; 572 | uiIndex = fw_info.SecondIndex; 573 | } 574 | 575 | pBuffer = (unsigned char*)malloc(Size); 576 | memset(pBuffer, 0xFF, Size); 577 | fseek(pFile, uiIndex, SEEK_SET); 578 | lSize = fread(pBuffer, 1, Size, pFile); 579 | if (lSize != Size) 580 | printf("Possible read length error %s\n", sFilePath); 581 | 582 | fclose(pFile); 583 | pTmp = pBuffer; 584 | 585 | while (Size) { 586 | tmp = min(Size, 0x100); 587 | /// receive page 588 | rq.Function = URB_FUNCTION_VENDOR_OTHER; 589 | rq.Direction = VENDOR_DIRECTION_OUT; 590 | rq.Request = 0x1; 591 | rq.Value = 0; 592 | rq.Index = 0; 593 | rq.Length = 0x100; /// plage size for ST7 Iap prog 594 | 595 | if (OutCtrlRequest(&rq, pTmp, tmp, Index) == SerialFlash_FALSE) { 596 | free(pBuffer); 597 | return false; 598 | } 599 | 600 | /// program page 601 | rq.Function = URB_FUNCTION_VENDOR_OTHER; 602 | rq.Direction = VENDOR_DIRECTION_IN; 603 | rq.Request = 0x8; 604 | rq.Value = 0; 605 | rq.Index = iStartAddr & 0xFFFF; ///< ConvLongToInt(lngST7address Mod &H10000) 606 | rq.Length = 0x1; 607 | iStartAddr += 0x100; 608 | 609 | if (OutCtrlRequest(&rq, &Data, 1, Index) == SerialFlash_FALSE) { 610 | free(pBuffer); 611 | return false; 612 | } 613 | Size -= tmp; 614 | pTmp += tmp; 615 | } 616 | 617 | free(pBuffer); 618 | return true; 619 | } 620 | 621 | bool UpdateChkSum(int Index) 622 | { 623 | if (!Is_usbworking(Index)) 624 | return false; 625 | 626 | CNTRPIPE_RQ rq; 627 | unsigned char vBuffer[2]; 628 | 629 | // send to calculate checksum 630 | rq.Function = URB_FUNCTION_VENDOR_OTHER; 631 | rq.Direction = VENDOR_DIRECTION_IN; 632 | rq.Request = 0x9; 633 | rq.Value = 0; 634 | rq.Index = 0; 635 | rq.Length = 2; 636 | 637 | if (OutCtrlRequest(&rq, vBuffer, 2, Index) == SerialFlash_FALSE) { 638 | return false; 639 | } 640 | 641 | return true; 642 | } 643 | 644 | bool WriteUID(unsigned int dwUID, int Index) 645 | { 646 | if (!Is_usbworking(Index)) 647 | return false; 648 | 649 | if ((g_bIsSF600[Index] == true) || is_SF700_Or_SF600PG2(Index) == true) 650 | return true; 651 | 652 | CNTRPIPE_RQ rq; 653 | unsigned char Data; 654 | 655 | // read 656 | rq.Function = URB_FUNCTION_VENDOR_OTHER; 657 | rq.Direction = VENDOR_DIRECTION_IN; 658 | rq.Request = 0x6; 659 | rq.Value = (unsigned char)(dwUID >> 16); 660 | rq.Index = 0xEF00; 661 | rq.Length = 1; 662 | 663 | if (InCtrlRequest(&rq, &Data, 1, Index) == SerialFlash_FALSE) { 664 | return false; 665 | } 666 | 667 | rq.Index = 0xEF01; 668 | rq.Value = (unsigned char)(dwUID >> 8); 669 | 670 | if (InCtrlRequest(&rq, &Data, 1, Index) == SerialFlash_FALSE) { 671 | return false; 672 | } 673 | 674 | rq.Index = 0xEF02; 675 | rq.Value = (unsigned char)(dwUID); 676 | 677 | if (!InCtrlRequest(&rq, &Data, 1, Index)) { 678 | return false; 679 | } 680 | 681 | return true; 682 | } 683 | 684 | bool WriteManufacturerID(unsigned char ManuID, int Index) 685 | { 686 | if (!Is_usbworking(Index)) 687 | return false; 688 | 689 | if ((g_bIsSF600[Index] == true) || is_SF700_Or_SF600PG2(Index) == true) 690 | return true; 691 | 692 | CNTRPIPE_RQ rq; 693 | unsigned char Data; 694 | 695 | // read 696 | rq.Function = URB_FUNCTION_VENDOR_OTHER; 697 | rq.Direction = VENDOR_DIRECTION_IN; 698 | rq.Request = 0x6; 699 | rq.Value = ManuID; 700 | rq.Index = 0xEF03; 701 | rq.Length = 1; 702 | 703 | if (InCtrlRequest(&rq, &Data, 1, Index) == SerialFlash_FALSE) { 704 | return false; 705 | } 706 | 707 | return true; 708 | } 709 | 710 | bool ReadMemOnST7(unsigned int iAddr, int Index) 711 | { 712 | if (!Is_usbworking(Index)) 713 | return false; 714 | 715 | CNTRPIPE_RQ rq; 716 | unsigned char vBuffer[2]; 717 | 718 | // read 719 | rq.Function = URB_FUNCTION_VENDOR_OTHER; 720 | rq.Direction = VENDOR_DIRECTION_IN; 721 | rq.Request = 0x7; 722 | rq.Value = 0; 723 | rq.Index = iAddr & 0xFFFF; 724 | rq.Length = 2; 725 | 726 | if (OutCtrlRequest(&rq, vBuffer, 2, Index) == SerialFlash_FALSE) { 727 | return false; 728 | } 729 | 730 | return true; 731 | } 732 | 733 | bool UpdateSF600Firmware(const char* sFolder, int Index) 734 | { 735 | bool boResult = true; 736 | unsigned char vUID[16]; 737 | unsigned int dwUID; 738 | 739 | if (ReadOnBoardFlash(vUID, false, Index) == false) 740 | return false; 741 | dwUID = (unsigned int)vUID[0] << 16 | (unsigned int)vUID[1] << 8 | vUID[2]; 742 | boResult &= UpdateSF600Flash(sFolder, Index); 743 | Sleep(200); 744 | boResult &= UpdateSF600Flash_FPGA(sFolder, Index); 745 | Sleep(1000); 746 | WriteSF600UID(dwUID, vUID[3], Index); 747 | return boResult; 748 | } 749 | 750 | bool WriteSF600UID(unsigned int dwUID, unsigned char ManuID, int Index) 751 | { 752 | CNTRPIPE_RQ rq; 753 | unsigned char vBuffer[16]; 754 | 755 | // first control packet 756 | rq.Function = URB_FUNCTION_VENDOR_ENDPOINT; 757 | rq.Direction = VENDOR_DIRECTION_OUT; 758 | rq.Request = WRITE_EEPROM; 759 | rq.Value = 0; 760 | rq.Index = 0; 761 | rq.Length = 16; 762 | 763 | vBuffer[0] = (unsigned char)(dwUID >> 16); 764 | vBuffer[1] = (unsigned char)(dwUID >> 8); 765 | vBuffer[2] = (unsigned char)(dwUID); 766 | vBuffer[3] = ManuID; 767 | 768 | if (!OutCtrlRequest(&rq, vBuffer, 16, Index)) 769 | return false; 770 | 771 | return true; 772 | } 773 | bool CheckSDCard(int Index) 774 | { 775 | CNTRPIPE_RQ rq; 776 | unsigned char vBuffer; 777 | 778 | // first control packet 779 | rq.Function = URB_FUNCTION_VENDOR_ENDPOINT; 780 | rq.Direction = VENDOR_DIRECTION_IN; 781 | rq.Request = CHECK_SD_CARD; 782 | rq.Value = 0; 783 | rq.Index = 0; 784 | rq.Length = 1; 785 | 786 | if (!OutCtrlRequest(&rq, &vBuffer, 1, Index)) 787 | return false; 788 | if (vBuffer == 0) 789 | return false; 790 | return true; 791 | } 792 | 793 | bool GetFirmwareVer(int Index) 794 | { 795 | 796 | CNTRPIPE_RQ rq; 797 | unsigned char vBuffer[32]; 798 | unsigned int BufferSize =32; 799 | 800 | if((g_bIsSF600[Index] == false) && (is_SF700_Or_SF600PG2(Index) == false)) 801 | BufferSize = 16; 802 | 803 | // first control packet 804 | rq.Function = URB_FUNCTION_VENDOR_ENDPOINT; 805 | rq.Direction = VENDOR_DIRECTION_IN; 806 | rq.Request = PROGINFO_REQUEST; 807 | rq.Value = 0; 808 | rq.Index = 0; 809 | rq.Length = BufferSize; 810 | 811 | if (!OutCtrlRequest(&rq, vBuffer, BufferSize, Index)) 812 | return false; 813 | 814 | if (!Is_usbworking(Index)) { 815 | printf("Do not find SFxx programmer!!\n"); 816 | return false; 817 | } 818 | 819 | memcpy(g_board_type, &vBuffer[0], 8); 820 | 821 | if (strstr(g_board_type, "SF600PG2") != NULL) 822 | { 823 | memcpy(g_FW_ver, &vBuffer[12], 9); 824 | memcpy(g_HW_ver, &vBuffer[25], 5); 825 | } 826 | else 827 | { 828 | memcpy(g_FW_ver, &vBuffer[10], 7); 829 | if (strstr(g_board_type, "SF600") != NULL) 830 | memcpy(g_HW_ver, &vBuffer[20], 4); 831 | if (strstr(g_board_type, "SF700") != NULL) 832 | memcpy(g_HW_ver, &vBuffer[21], 4); 833 | } 834 | 835 | 836 | return true; 837 | } 838 | 839 | bool EncrypFirmware(unsigned char* vBuffer, unsigned int Size, int Index) 840 | { 841 | unsigned char vUID[16]; 842 | unsigned int i = 0; 843 | if (ReadOnBoardFlash(vUID, false, Index) == false) 844 | return false; 845 | for (i = 0; i < 16; i++) 846 | vBuffer[i] = vBuffer[i] ^ vUID[i]; 847 | 848 | for (; i < Size; i++) 849 | vBuffer[i] = vBuffer[i] ^ vBuffer[i - 16]; 850 | return true; 851 | } 852 | 853 | bool UpdateSF600Flash(const char* sFilePath, int Index) 854 | { 855 | CNTRPIPE_RQ rq; 856 | unsigned char* pBuffer; 857 | int pagenum = 0; 858 | unsigned int dwsize = 0; 859 | FW_INFO fw_info; 860 | FILE* pFile; 861 | size_t lSize; 862 | int i = 0; 863 | 864 | pFile = fopen(sFilePath, "rb"); 865 | if (pFile == NULL) { 866 | printf("Can not open %s \n", sFilePath); 867 | return false; 868 | } 869 | 870 | fseek(pFile, 0, SEEK_SET); 871 | lSize = fread((unsigned char*)&fw_info, 1, sizeof(FW_INFO), pFile); 872 | if (lSize != sizeof(FW_INFO)) 873 | printf("Possible read length error %s\n", sFilePath); 874 | pBuffer = (unsigned char*)malloc(fw_info.FirstSize); 875 | fseek(pFile, fw_info.FirstIndex, SEEK_SET); 876 | lSize = fread(pBuffer, 1, fw_info.FirstSize, pFile); 877 | if (lSize != fw_info.FirstSize) 878 | printf("Possible read length error %s\n", sFilePath); 879 | fclose(pFile); 880 | 881 | EncrypFirmware(pBuffer, fw_info.FirstSize, Index); 882 | 883 | if (Is_NewUSBCommand(Index)) { // for win8.1 884 | rq.Function = URB_FUNCTION_VENDOR_ENDPOINT; 885 | rq.Direction = VENDOR_DIRECTION_OUT; 886 | rq.Request = 0x1A; 887 | rq.Value = 0; 888 | rq.Index = 0; 889 | rq.Length = 6; 890 | 891 | unsigned char Package[6]; 892 | Package[0] = pBuffer[0]; 893 | Package[1] = pBuffer[1]; 894 | Package[2] = (fw_info.FirstSize & 0xff); 895 | Package[3] = ((fw_info.FirstSize >> 8) & 0xff); 896 | Package[4] = ((fw_info.FirstSize >> 16) & 0xff); 897 | Package[5] = ((fw_info.FirstSize >> 24) & 0xff); 898 | 899 | if (!OutCtrlRequest(&rq, Package, 6, Index)) { 900 | free(pBuffer); 901 | return false; 902 | } 903 | } else { 904 | rq.Function = URB_FUNCTION_VENDOR_ENDPOINT; 905 | rq.Direction = VENDOR_DIRECTION_OUT; 906 | rq.Request = 0x1A; 907 | rq.Value = (unsigned short)(fw_info.FirstSize & 0xffff); 908 | rq.Index = (unsigned short)((fw_info.FirstSize >> 16) & 0xffff); 909 | rq.Length = 0; 910 | 911 | if (!OutCtrlRequest(&rq, pBuffer, 0, Index)) { 912 | free(pBuffer); 913 | return false; 914 | } 915 | } 916 | 917 | pagenum = (fw_info.FirstSize >> 9) + ((fw_info.FirstSize % (1 << 9)) ? 1 : 0); 918 | dwsize = fw_info.FirstSize; 919 | 920 | for (i = 0; i < pagenum; i++) { 921 | BulkPipeWrite((pBuffer + (i << 9)), min(512, dwsize), USB_TIMEOUT, Index); 922 | dwsize -= 512; 923 | } 924 | 925 | free(pBuffer); 926 | return true; 927 | } 928 | 929 | bool UpdateSF600Flash_FPGA(const char* sFilePath, int Index) 930 | { 931 | CNTRPIPE_RQ rq; 932 | unsigned char* pBuffer; 933 | int pagenum = 0; 934 | unsigned int dwsize = 0; 935 | FW_INFO fw_info; 936 | FILE* pFile; 937 | size_t lSize; 938 | int i = 0; 939 | 940 | pFile = fopen(sFilePath, "rb"); 941 | if (pFile == NULL) { 942 | printf("Can not open %s \n", sFilePath); 943 | return false; 944 | } 945 | 946 | fseek(pFile, 0, SEEK_SET); 947 | lSize = fread((unsigned char*)&fw_info, 1, sizeof(FW_INFO), pFile); 948 | if (lSize != sizeof(FW_INFO)) 949 | printf("Possible read length error %s\n", sFilePath); 950 | 951 | pBuffer = (unsigned char*)malloc(fw_info.SecondSize); 952 | fseek(pFile, fw_info.SecondIndex, SEEK_SET); 953 | lSize = fread(pBuffer, 1, fw_info.SecondSize, pFile); 954 | if (lSize != fw_info.SecondSize) 955 | printf("Possible read length error %s\n", sFilePath); 956 | 957 | fclose(pFile); 958 | 959 | if (EncrypFirmware(pBuffer, fw_info.SecondSize, Index) == false) 960 | return false; 961 | 962 | if (Is_NewUSBCommand(Index)) { // for win8.1 963 | rq.Function = URB_FUNCTION_VENDOR_ENDPOINT; 964 | rq.Direction = VENDOR_DIRECTION_OUT; 965 | rq.Request = 0x1B; 966 | rq.Value = 0; // static_cast(vBuffer.size() & 0xffff) ; 967 | rq.Index = 0; // static_cast((vBuffer.size() >> 16) & 0xffff) ; 968 | rq.Length = 4; 969 | 970 | unsigned char Package[4]; 971 | Package[0] = (fw_info.SecondSize & 0xff); 972 | Package[1] = ((fw_info.SecondSize >> 8) & 0xff); 973 | Package[2] = ((fw_info.SecondSize >> 16) & 0xff); 974 | Package[3] = ((fw_info.SecondSize >> 24) & 0xff); 975 | 976 | if (!OutCtrlRequest(&rq, Package, 4, Index)) { 977 | free(pBuffer); 978 | return false; 979 | } 980 | } else { 981 | rq.Function = URB_FUNCTION_VENDOR_ENDPOINT; 982 | rq.Direction = VENDOR_DIRECTION_OUT; 983 | rq.Request = 0x1B; 984 | rq.Value = (unsigned short)(fw_info.SecondSize & 0xffff); 985 | rq.Index = (unsigned short)((fw_info.SecondSize >> 16) & 0xffff); 986 | rq.Length = 0; 987 | 988 | if (!OutCtrlRequest(&rq, pBuffer, 0, Index)) { 989 | free(pBuffer); 990 | return false; 991 | } 992 | } 993 | 994 | pagenum = (fw_info.SecondSize >> 9) + ((fw_info.SecondSize % (1 << 9)) ? 1 : 0); 995 | dwsize = fw_info.SecondSize; 996 | 997 | for (i = 0; i < pagenum; i++) { 998 | BulkPipeWrite(pBuffer + (i << 9), min(512, dwsize), USB_TIMEOUT, Index); 999 | dwsize -= 512; 1000 | } 1001 | return true; 1002 | } 1003 | 1004 | bool UpdateFirmware(const char* sFolder, int Index) 1005 | { 1006 | bool bResult = true; 1007 | unsigned int UID = 0; 1008 | unsigned char ManID = 0; 1009 | // read status 1010 | if ((g_bIsSF600[Index] == true) || (is_SF700_Or_SF600PG2(Index) == true)) 1011 | return UpdateSF600Firmware(sFolder, Index); 1012 | 1013 | dediprog_set_spi_voltage(g_Vcc, Index); 1014 | 1015 | if (g_firmversion > 0x040107) // 4.1.7 1016 | bResult &= SetSPIClockDefault(Index); 1017 | 1018 | bResult &= SetVpp4IAP(true, Index); 1019 | bResult &= UnlockRASS(Index); 1020 | 1021 | UID = ReadUID(Index); 1022 | ManID = ReadManufacturerID(Index); 1023 | 1024 | // erase & program sector 1 1025 | bResult &= EraseST7Sectors(true, Index); 1026 | bResult &= ProgramSectors(sFolder, true, Index); 1027 | // erase & program sector 2 1028 | bResult &= EraseST7Sectors(false, Index); 1029 | bResult &= ProgramSectors(sFolder, false, Index); 1030 | 1031 | // calculate and read back checksum 1032 | bResult &= UpdateChkSum(Index); 1033 | 1034 | bResult &= WriteUID(UID, Index); 1035 | bResult &= WriteManufacturerID(ManID, Index); 1036 | bResult &= SetVpp4IAP(false, Index); 1037 | 1038 | // read back checksum 1039 | bResult &= ReadMemOnST7(0xEFFE, Index); 1040 | return bResult; 1041 | } 1042 | 1043 | void SendFFSequence(int Index) 1044 | { 1045 | unsigned char v[4] = { 0xff, 0xff, 0xff, 0xff }; 1046 | FlashCommand_SendCommand_OutOnlyInstruction(v, 4, Index); 1047 | } 1048 | -------------------------------------------------------------------------------- /board.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef _BOARD_H 4 | #define _BOARD_H 5 | 6 | #include 7 | #include 8 | 9 | void SendFFSequence(int Index); 10 | void QueryBoard(int Index); 11 | unsigned int GetFPGAVersion(int Index); 12 | bool SetIO(unsigned char ioState, int Index); 13 | bool SetTargetFlash(unsigned char StartupMode, int Index); 14 | bool SetLEDProgBoard(size_t Clolor, int Index); 15 | bool SetGreenLEDOn(bool boOn, int Index); 16 | bool SetOrangeLEDOn(bool boOn, int Index); 17 | bool SetRedLEDOn(bool boOn, int Index); 18 | bool SetLEDOnOff(size_t Color, int Index); 19 | bool SetCS(size_t value, int Index); 20 | bool SetIOModeToSF600(size_t value, int Index); 21 | bool BlinkProgBoard(bool boIsV5, int Index); 22 | bool LeaveSF600Standalone(bool Enable, int Index); 23 | bool SetIOMOdeValue(int Index); 24 | bool SetSPIClockValue(unsigned short v, int Index); 25 | unsigned int ReadUID(int Index); 26 | bool SetSPIClockDefault(int Index); 27 | bool EraseST7Sectors(bool bSect1, int Index); 28 | bool ProgramSectors(const char* sFilePath, bool bSect1, int Index); 29 | bool UpdateChkSum(int Index); 30 | bool WriteUID(unsigned int dwUID, int Index); 31 | bool WriteManufacturerID(unsigned char ManuID, int Index); 32 | bool EncrypFirmware(unsigned char* vBuffer, unsigned int Size, int Index); 33 | bool UpdateSF600Flash(const char* sFilePath, int Index); 34 | bool WriteSF600UID(unsigned int dwUID, unsigned char ManuID, int Index); 35 | bool UpdateSF600Flash_FPGA(const char* sFilePath, int Index); 36 | bool UpdateSF600Firmware(const char* sFolder, int Index); 37 | bool UpdateFirmware(const char* sFolder, int Index); 38 | bool GetFirmwareVer(int Index); 39 | bool CheckSDCard(int Index); 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /dpcmd.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef _DPCMD_H 4 | #define _DPCMD_H 5 | 6 | #include 7 | 8 | enum ErrorCode { 9 | EXCODE_PASS, 10 | EXCODE_FAIL_USB, 11 | EXCODE_FAIL_ERASE, 12 | EXCODE_FAIL_PROG, 13 | EXCODE_FAIL_VERIFY, 14 | EXCODE_FAIL_LOADFILEWITHVERIFY, 15 | EXCODE_FAIL_READ, 16 | EXCODE_FAIL_BLANK, // 7 17 | EXCODE_FAIL_BATCH, 18 | EXCODE_FAIL_CHKSUM, 19 | EXCODE_FAIL_IDENTIFY, 20 | EXCODE_FAIL_UPDATE_FW, 21 | EXCODE_FAIL_OTHERS, 22 | }; 23 | 24 | int Sequence(); 25 | void cli_classic_usage(bool IsShowExample); 26 | bool InitProject(void); 27 | void CloseProject(void); 28 | bool DetectChip(void); 29 | void SetVpp(int Index); 30 | void SetSPIIOMode(int Index); 31 | void SetSPIClock(int Index); 32 | void SetVcc(int Index); 33 | int SetVppVoltage(int vol,int Index); 34 | int do_loadFile(void); 35 | int do_loadFileWithVerify(void); 36 | void BlinkProgrammer(void); 37 | void ListSFSerialID(void); 38 | void do_BlankCheck(void); 39 | void do_Erase(void); 40 | void do_Program(void); 41 | void do_Read(void); 42 | void do_DisplayOrSave(void); 43 | void SaveProgContextChanges(void); 44 | void do_Auto(void); 45 | void do_Verify(void); 46 | void do_ReadSR(int Index); 47 | void do_RawInstructions(int Index); 48 | void do_RawInstructinos_2(int outDLen, char* para, int Index); 49 | void RawInstructions(int Index); 50 | bool BlankCheck(void); 51 | bool Erase(void); 52 | bool Program(void); 53 | bool Read(void); 54 | bool Auto(void); 55 | bool Verify(void); 56 | bool LoadFileWithVerify(void); 57 | bool CalChecksum(void); 58 | int Handler(); 59 | bool ListTypes(void); 60 | bool CheckProgrammerInfo(void); 61 | void GetLogPath(char* path); 62 | bool Wait(const char* strOK, const char* strFail); 63 | void ExitProgram(void); 64 | int FirmwareUpdate(); 65 | void sin_handler(int sig); 66 | void FillNANDContext(void); 67 | bool ScanBB(void); 68 | void do_ScanBB(void); 69 | void do_NANDSpecialErase(void); 70 | bool SpecialErase(void); 71 | 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /parse.c: -------------------------------------------------------------------------------- 1 | #include "ChipInfoDb.h" 2 | #include "project.h" 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #ifdef __FreeBSD__ 10 | #include 11 | #endif 12 | 13 | #define pathbufsize 1024 14 | #define testbufsize 256 15 | #define linebufsize 512 16 | #define filebufsize 1024 * 1024 17 | #define min(a, b) (((a) > (b)) ? (b) : (a)) 18 | #define max(a, b) (((a) > (b)) ? (a) : (b)) 19 | 20 | //using namespace pugi; 21 | //xml_document doc; 22 | #if 1 23 | bool GetChipDbPath(char *Path) 24 | { 25 | FILE* fp = NULL; 26 | 27 | if(Path == NULL) 28 | return false; 29 | 30 | memset(Path, 0, linebufsize); 31 | if (readlink("/proc/self/exe", Path, 512) != -1) { 32 | dirname(Path); 33 | strcat(Path, "/ChipInfoDb.dedicfg"); 34 | if ((fp = fopen(Path, "rt")) == NULL) { 35 | // ChipInfoDb.dedicfg not in program directory 36 | dirname(Path); 37 | dirname(Path); 38 | strcat(Path, "/share/DediProg/ChipInfoDb.dedicfg"); 39 | // printf("%s\n",Path); 40 | if ((fp = fopen(Path, "rt")) == NULL) 41 | { 42 | fprintf(stderr, "Error opening file: %s\n", Path); 43 | return false; 44 | } 45 | } 46 | if(fp) 47 | fclose(fp); 48 | //printf("\r\n%s\r\n", Path); 49 | return true; 50 | } 51 | return false; 52 | } 53 | 54 | 55 | int Dedi_Search_Chip_Db(char* chTypeName, long RDIDCommand, 56 | long UniqueID, 57 | CHIP_INFO* Chip_Info, 58 | int search_all) 59 | { 60 | int found_flag = 0; 61 | char file_path[linebufsize]; 62 | int detectICNum = 0; 63 | char strTypeName[32][100]; 64 | CHIP_INFO Chip_Info_temp; 65 | xmlDocPtr doc; 66 | xmlNodePtr cur_node; 67 | xmlChar *chip_attribute; 68 | 69 | for (int i = 0; i < 32; i++) 70 | memset(strTypeName[i], '\0', 100); 71 | 72 | memset(chTypeName, '\0', 1024); 73 | 74 | memset(Chip_Info->TypeName, '\0', sizeof(Chip_Info->TypeName)); //strlen(Chip_Info->TypeName)=0 75 | 76 | if (GetChipDbPath(file_path) == false) 77 | { 78 | return 1; 79 | } 80 | 81 | doc = xmlParseFile(file_path); 82 | cur_node = xmlDocGetRootElement(doc); // DediProgChipDatabase 83 | cur_node = cur_node->children->next; //Portofolio 84 | cur_node = cur_node->children->next; //Chip 85 | //printf("UniqueID=0x%08X\n", UniqueID); 86 | while (cur_node != NULL) { 87 | if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"Chip"))) { 88 | 89 | if (found_flag == 1) { 90 | found_flag = 0; 91 | 92 | if (strlen(Chip_Info->TypeName) == 0) 93 | *Chip_Info = Chip_Info_temp; //first chip info 94 | detectICNum++; 95 | memset(&Chip_Info_temp, 0, sizeof(CHIP_INFO)); 96 | } 97 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"TypeName"); 98 | if(chip_attribute){ 99 | 100 | strcpy(Chip_Info_temp.TypeName, (char*)chip_attribute); 101 | } 102 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ICType"); 103 | if(chip_attribute){ 104 | 105 | strcpy(Chip_Info_temp.ICType, (char*)chip_attribute); 106 | } 107 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"Class"); 108 | if(chip_attribute){ 109 | strcpy(Chip_Info_temp.Class, (char*)chip_attribute); 110 | } 111 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"Manufacturer"); 112 | if(chip_attribute){ 113 | strcpy(Chip_Info_temp.Manufacturer, (char*)chip_attribute); 114 | } 115 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"UniqueID"); 116 | if(chip_attribute){ 117 | Chip_Info_temp.UniqueID = strtol((char*)chip_attribute, NULL, 16);; 118 | } 119 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"Voltage"); 120 | if(chip_attribute){ 121 | strcpy(Chip_Info_temp.Voltage, (char*)chip_attribute); 122 | if (strstr((char *)chip_attribute, "3.3V") != NULL) 123 | Chip_Info_temp.VoltageInMv = 3300; 124 | else if (strstr((char *)chip_attribute, "2.5V") != NULL) 125 | Chip_Info_temp.VoltageInMv = 2500; 126 | else if (strstr((char *)chip_attribute, "1.8V") != NULL) 127 | Chip_Info_temp.VoltageInMv = 1800; 128 | else 129 | Chip_Info_temp.VoltageInMv = 3300; 130 | } 131 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"JedecDeviceID"); 132 | if(chip_attribute){ 133 | Chip_Info_temp.JedecDeviceID = strtol((char*)chip_attribute, NULL, 16); 134 | if ((UniqueID == Chip_Info_temp.JedecDeviceID)) { 135 | found_flag = 1; 136 | 137 | strcpy(strTypeName[detectICNum], Chip_Info_temp.TypeName); 138 | strcat(chTypeName, " "); 139 | strcat(chTypeName, strTypeName[detectICNum]); 140 | } 141 | } 142 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ChipSizeInKByte"); 143 | if(chip_attribute){ 144 | Chip_Info_temp.ChipSizeInByte = strtol((char*)chip_attribute, NULL, 10) * 1024; 145 | } 146 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"SectorSizeInByte"); 147 | if(chip_attribute){ 148 | Chip_Info_temp.SectorSizeInByte = strtol((char*)chip_attribute, NULL, 10); 149 | } 150 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"BlockSizeInByte"); 151 | if(chip_attribute){ 152 | Chip_Info_temp.BlockSizeInByte = strtol((char*)chip_attribute, NULL, 10); 153 | } 154 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"PageSizeInByte"); 155 | if(chip_attribute){ 156 | Chip_Info_temp.PageSizeInByte = strtol((char*)chip_attribute, NULL, 10); 157 | } 158 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"AddrWidth"); 159 | if(chip_attribute){ 160 | Chip_Info_temp.AddrWidth = strtol((char*)chip_attribute, NULL, 10); 161 | } 162 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ReadDummyLen"); 163 | if(chip_attribute){ 164 | Chip_Info_temp.ReadDummyLen = strtol((char*)chip_attribute, NULL, 10); 165 | } 166 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ReadDummyLen"); 167 | if(chip_attribute){ 168 | Chip_Info_temp.ReadDummyLen = strtol((char*)chip_attribute, NULL, 10); 169 | } 170 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"IDNumber"); 171 | if(chip_attribute){ 172 | Chip_Info_temp.IDNumber = strtol((char*)chip_attribute, NULL, 10); 173 | } 174 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"VppSupport"); 175 | if(chip_attribute){ 176 | Chip_Info_temp.VppSupport = strtol((char*)chip_attribute, NULL, 10); 177 | } 178 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"RDIDCommand"); 179 | if(chip_attribute){ 180 | Chip_Info_temp.RDIDCommand = strtol((char*)chip_attribute, NULL, 16); 181 | } 182 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"Timeout"); 183 | if(chip_attribute){ 184 | Chip_Info_temp.Timeout = strtol((char*)chip_attribute, NULL, 16); 185 | } 186 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"MXIC_WPmode"); 187 | if(chip_attribute){ 188 | if (strstr((char*)chip_attribute, "true") != NULL) 189 | Chip_Info_temp.MXIC_WPmode = true; 190 | else 191 | Chip_Info_temp.MXIC_WPmode = false; 192 | } 193 | //SPI NAND 194 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"SpareSizeInByte"); 195 | if(chip_attribute){ 196 | Chip_Info_temp.SpareSizeInByte = (strtol((char*)chip_attribute, NULL, 16)/*&0xFFFF*/); 197 | //printf("SpareSizeInByte=%ld\n",Chip_Info_temp.SpareSizeInByte); 198 | } 199 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"nCA_Rd"); 200 | if(chip_attribute){ 201 | Chip_Info_temp.nCA_Rd = strtol((char*)chip_attribute, NULL, 10); 202 | } 203 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"nCA_Wr"); 204 | if(chip_attribute){ 205 | Chip_Info_temp.nCA_Wr = strtol((char*)chip_attribute, NULL, 10); 206 | } 207 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ReadDummyLen"); 208 | if(chip_attribute){ 209 | Chip_Info_temp.ReadDummyLen = strtol((char*)chip_attribute, NULL, 10); 210 | } 211 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"DefaultDataUnitSize"); 212 | if(chip_attribute){ 213 | Chip_Info_temp.DefaultDataUnitSize = strtol((char*)chip_attribute, NULL, 10); 214 | } 215 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"DefaultErrorBits"); 216 | if(chip_attribute){ 217 | Chip_Info_temp.DefaultErrorBits = strtol((char*)chip_attribute, NULL, 10); 218 | } 219 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"BBMark"); 220 | if(chip_attribute){ 221 | Chip_Info_temp.BBMark = strtol((char*)chip_attribute, NULL, 10); 222 | } 223 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"SupportedProduct"); 224 | if(chip_attribute){ 225 | Chip_Info_temp.SupportedProduct = strtol((char*)chip_attribute, NULL, 16); 226 | } 227 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ECCParityGroup"); 228 | if(chip_attribute){ 229 | Chip_Info_temp.ECCParityGroup = strtol((char*)chip_attribute, NULL, 10); 230 | } 231 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ECCProtectStartAddr"); 232 | if(chip_attribute){ 233 | Chip_Info_temp.ECCProtectStartAddr = strtol((char*)chip_attribute, NULL, 16); 234 | } 235 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ECCProtectDis"); 236 | if(chip_attribute){ 237 | Chip_Info_temp.ECCProtectDis = strtol((char*)chip_attribute, NULL, 16); 238 | } 239 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ECCProtectLength"); 240 | if(chip_attribute){ 241 | Chip_Info_temp.ECCProtectLength = strtol((char*)chip_attribute, NULL, 10); 242 | } 243 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ECCEnable"); 244 | if(chip_attribute){ 245 | if (strstr((char*)chip_attribute, "true") != NULL) 246 | Chip_Info_temp.ECCEnable = true; 247 | else 248 | Chip_Info_temp.ECCEnable = false; 249 | } 250 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"QPIEnable"); 251 | if(chip_attribute){ 252 | if (strstr((char*)chip_attribute, "true") != NULL) 253 | Chip_Info_temp.QPIEnable = true; 254 | else 255 | Chip_Info_temp.QPIEnable = false; 256 | } 257 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ChipEraseTime"); 258 | if(chip_attribute){ 259 | Chip_Info_temp.ChipEraseTime = strtol((char*)chip_attribute, NULL, 16); 260 | } 261 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"EraseCmd"); 262 | if(chip_attribute){ 263 | Chip_Info_temp.EraseCmd = strtol((char*)chip_attribute, NULL, 16); 264 | } 265 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ProgramCmd"); 266 | if(chip_attribute){ 267 | Chip_Info_temp.ProgramCmd = strtol((char*)chip_attribute, NULL, 16); 268 | } 269 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ReadCmd"); 270 | if(chip_attribute){ 271 | Chip_Info_temp.ReadCmd = strtol((char*)chip_attribute, NULL, 16); 272 | } 273 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ProtectBlockMask"); 274 | if(chip_attribute){ 275 | Chip_Info_temp.ProtectBlockMask = strtol((char*)chip_attribute, NULL, 16); 276 | } 277 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"UnlockCmd"); 278 | if(chip_attribute){ 279 | Chip_Info_temp.UnlockCmd = strtol((char*)chip_attribute, NULL, 16); 280 | } 281 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"RDSRCnt"); 282 | if(chip_attribute){ 283 | Chip_Info_temp.RDSRCnt = strtol((char*)chip_attribute, NULL, 16); 284 | } 285 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"WRSRCnt"); 286 | if(chip_attribute){ 287 | Chip_Info_temp.WRSRCnt = strtol((char*)chip_attribute, NULL, 16); 288 | } 289 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"WRSRCmd"); 290 | if(chip_attribute){ 291 | Chip_Info_temp.WRSRCmd = strtol((char*)chip_attribute, NULL, 16); 292 | } 293 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"WRCRCmd"); 294 | if(chip_attribute){ 295 | Chip_Info_temp.WRCRCmd = strtol((char*)chip_attribute, NULL, 16); 296 | } 297 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"RDSRCmd"); 298 | if(chip_attribute){ 299 | Chip_Info_temp.RDSRCmd = strtol((char*)chip_attribute, NULL, 16); 300 | } 301 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"RDCRCmd"); 302 | if(chip_attribute){ 303 | Chip_Info_temp.RDCRCmd = strtol((char*)chip_attribute, NULL, 16); 304 | } 305 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"QEbitAddr"); 306 | if(chip_attribute){ 307 | Chip_Info_temp.QEbitAddr = strtol((char*)chip_attribute, NULL, 16); 308 | } 309 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ChipIDMask"); 310 | if(chip_attribute){ 311 | Chip_Info_temp.ChipIDMask = strtol((char*)chip_attribute, NULL, 16); 312 | } 313 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"SupportLUT"); 314 | if(chip_attribute){ 315 | if (strstr((char*)chip_attribute, "true") != NULL) 316 | Chip_Info_temp.SupportLUT = true; 317 | else 318 | Chip_Info_temp.SupportLUT = false; 319 | } 320 | 321 | xmlFree(chip_attribute); 322 | } 323 | cur_node = cur_node->next; 324 | } 325 | 326 | xmlFreeDoc(doc); 327 | if(detectICNum) 328 | found_flag=1; 329 | Chip_Info->MaxErasableSegmentInByte = max(Chip_Info->SectorSizeInByte, Chip_Info->BlockSizeInByte); 330 | /*Read into the buffer contents within thr file stream*/ 331 | return found_flag; 332 | } 333 | 334 | int Dedi_Search_Chip_Db_ByTypeName(char* TypeName, CHIP_INFO* Chip_Info) 335 | { 336 | int found_flag = 0; 337 | char file_path[linebufsize]; 338 | CHIP_INFO Chip_Info_temp; 339 | xmlDocPtr doc; 340 | xmlNodePtr cur_node; 341 | xmlChar *chip_attribute; 342 | 343 | if (GetChipDbPath(file_path) == false) 344 | { 345 | return 1; 346 | } 347 | 348 | 349 | doc = xmlParseFile(file_path); 350 | cur_node = xmlDocGetRootElement(doc); // DediProgChipDatabase 351 | cur_node = cur_node->children->next; //Portofolio 352 | cur_node = cur_node->children->next; //C 353 | // data_temp = file_buf; 354 | /*Read into the buffer contents within thr file stream*/ 355 | while (cur_node != NULL) { 356 | if (found_flag == 1) { 357 | if (strlen(Chip_Info->TypeName) == 0) 358 | *Chip_Info = Chip_Info_temp; //first chip info 359 | 360 | break; 361 | } 362 | 363 | if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"Chip"))) { 364 | 365 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"TypeName"); 366 | 367 | if(chip_attribute){ 368 | 369 | if (!xmlStrcmp(chip_attribute, (const xmlChar *)TypeName)) { 370 | found_flag = 1; 371 | //printf("chip name=%s\n",chip_attribute); 372 | } else 373 | found_flag = 0; 374 | memset(&Chip_Info_temp, 0, sizeof(CHIP_INFO)); 375 | strcpy(Chip_Info_temp.TypeName, (char*)chip_attribute); 376 | 377 | } 378 | } 379 | if(found_flag == 0) 380 | { 381 | cur_node = cur_node->next; 382 | continue; 383 | }else { 384 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"Class"); 385 | if(chip_attribute){ 386 | strcpy(Chip_Info_temp.Class, (char*)chip_attribute); 387 | //printf("Class: %s\n", chip_attribute); 388 | } 389 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"Manufacturer"); 390 | if(chip_attribute){ 391 | strcpy(Chip_Info_temp.Manufacturer, (char*)chip_attribute); 392 | //printf("Manufacturer: %s\n", chip_attribute); 393 | } 394 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"UniqueID"); 395 | if(chip_attribute){ 396 | Chip_Info_temp.UniqueID = strtol((char*)chip_attribute, NULL, 16);; 397 | //printf("UniqueID: %s\n", chip_attribute); 398 | } 399 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"Voltage"); 400 | if(chip_attribute){ 401 | //printf("Voltage: %s\n", chip_attribute); 402 | if (strstr((char *)chip_attribute, "3.3V") == 0) 403 | Chip_Info_temp.VoltageInMv = 3300; 404 | else if (strstr((char *)chip_attribute, "2.5V") == 0) 405 | Chip_Info_temp.VoltageInMv = 2500; 406 | else if (strstr((char *)chip_attribute, "1.8V") == 0) 407 | Chip_Info_temp.VoltageInMv = 1800; 408 | else 409 | Chip_Info_temp.VoltageInMv = 3300; 410 | } 411 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"JedecDeviceID"); 412 | if(chip_attribute){ 413 | Chip_Info_temp.JedecDeviceID = strtol((char*)chip_attribute, NULL, 16); 414 | //printf("JedecDeviceID: %s\n", chip_attribute); 415 | } 416 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ChipSizeInKByte"); 417 | if(chip_attribute){ 418 | Chip_Info_temp.ChipSizeInByte = strtol((char*)chip_attribute, NULL, 10) * 1024; 419 | //printf("ChipSizeInKByte: %s\n", chip_attribute); 420 | } 421 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"SectorSizeInByte"); 422 | if(chip_attribute){ 423 | Chip_Info_temp.SectorSizeInByte = strtol((char*)chip_attribute, NULL, 10); 424 | //printf("SectorSizeInKByte: %s\n", chip_attribute); 425 | } 426 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"BlockSizeInByte"); 427 | if(chip_attribute){ 428 | Chip_Info_temp.BlockSizeInByte = strtol((char*)chip_attribute, NULL, 10); 429 | //printf("BlockSizeInByte: %s\n", chip_attribute); 430 | } 431 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"PageSizeInByte"); 432 | if(chip_attribute){ 433 | Chip_Info_temp.PageSizeInByte = strtol((char*)chip_attribute, NULL, 10); 434 | //printf("PageSizeInByte: %s\n", chip_attribute); 435 | } 436 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"AddrWidth"); 437 | if(chip_attribute){ 438 | Chip_Info_temp.AddrWidth = strtol((char*)chip_attribute, NULL, 10); 439 | //printf("AddrWidth: %s\n", chip_attribute); 440 | } 441 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ReadDummyLen"); 442 | if(chip_attribute){ 443 | Chip_Info_temp.ReadDummyLen = strtol((char*)chip_attribute, NULL, 10); 444 | //printf("ReadDummyLen: %s\n", chip_attribute); 445 | } 446 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ReadDummyLen"); 447 | if(chip_attribute){ 448 | Chip_Info_temp.ReadDummyLen = strtol((char*)chip_attribute, NULL, 10); 449 | //printf("ReadDummyLen: %s\n", chip_attribute); 450 | } 451 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"IDNumber"); 452 | if(chip_attribute){ 453 | Chip_Info_temp.IDNumber = strtol((char*)chip_attribute, NULL, 10); 454 | //printf("IDNumber: %s\n", chip_attribute); 455 | } 456 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"VppSupport"); 457 | if(chip_attribute){ 458 | Chip_Info_temp.VppSupport = strtol((char*)chip_attribute, NULL, 10); 459 | //printf("VppSupport: %s\n", chip_attribute); 460 | } 461 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"RDIDCommand"); 462 | if(chip_attribute){ 463 | Chip_Info_temp.RDIDCommand = strtol((char*)chip_attribute, NULL, 16); 464 | //printf("RDIDCommand: %s\n", chip_attribute); 465 | } 466 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"Timeout"); 467 | if(chip_attribute){ 468 | Chip_Info_temp.Timeout = strtol((char*)chip_attribute, NULL, 16); 469 | //printf("Timeout: %s\n", chip_attribute); 470 | } 471 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"MXIC_WPmode"); 472 | if(chip_attribute){ 473 | if (strstr((char*)chip_attribute, "true") != NULL) 474 | Chip_Info_temp.MXIC_WPmode = true; 475 | else 476 | Chip_Info_temp.MXIC_WPmode = false; 477 | //printf("MXIC_WPmode: %s\n", chip_attribute); 478 | } 479 | //SPI NAND 480 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"SpareSizeInByte"); 481 | if(chip_attribute){ 482 | Chip_Info_temp.SpareSizeInByte = strtol((char*)chip_attribute, NULL, 16); 483 | } 484 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"nCA_Rd"); 485 | if(chip_attribute){ 486 | Chip_Info_temp.nCA_Rd = strtol((char*)chip_attribute, NULL, 10); 487 | } 488 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"nCA_Wr"); 489 | if(chip_attribute){ 490 | Chip_Info_temp.nCA_Wr = strtol((char*)chip_attribute, NULL, 10); 491 | } 492 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ReadDummyLen"); 493 | if(chip_attribute){ 494 | Chip_Info_temp.ReadDummyLen = strtol((char*)chip_attribute, NULL, 10); 495 | } 496 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"DefaultDataUnitSize"); 497 | if(chip_attribute){ 498 | Chip_Info_temp.DefaultDataUnitSize = strtol((char*)chip_attribute, NULL, 10); 499 | } 500 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"DefaultErrorBits"); 501 | if(chip_attribute){ 502 | Chip_Info_temp.DefaultErrorBits = strtol((char*)chip_attribute, NULL, 10); 503 | } 504 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"BBMark"); 505 | if(chip_attribute){ 506 | Chip_Info_temp.BBMark = strtol((char*)chip_attribute, NULL, 10); 507 | } 508 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"SupportedProduct"); 509 | if(chip_attribute){ 510 | Chip_Info_temp.SupportedProduct = strtol((char*)chip_attribute, NULL, 16); 511 | } 512 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ECCParityGroup"); 513 | if(chip_attribute){ 514 | Chip_Info_temp.ECCParityGroup = strtol((char*)chip_attribute, NULL, 10); 515 | } 516 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ECCProtectStartAddr"); 517 | if(chip_attribute){ 518 | Chip_Info_temp.ECCProtectStartAddr = strtol((char*)chip_attribute, NULL, 16); 519 | } 520 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ECCProtectDis"); 521 | if(chip_attribute){ 522 | Chip_Info_temp.ECCProtectDis = strtol((char*)chip_attribute, NULL, 16); 523 | } 524 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ECCProtectLength"); 525 | if(chip_attribute){ 526 | Chip_Info_temp.ECCProtectLength = strtol((char*)chip_attribute, NULL, 10); 527 | } 528 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ECCEnable"); 529 | if(chip_attribute){ 530 | if (strstr((char*)chip_attribute, "true") != NULL) 531 | Chip_Info_temp.ECCEnable = true; 532 | else 533 | Chip_Info_temp.ECCEnable = false; 534 | } 535 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"QPIEnable"); 536 | if(chip_attribute){ 537 | if (strstr((char*)chip_attribute, "true") != NULL) 538 | Chip_Info_temp.QPIEnable = true; 539 | else 540 | Chip_Info_temp.QPIEnable = false; 541 | } 542 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ChipEraseTime"); 543 | if(chip_attribute){ 544 | Chip_Info_temp.ChipEraseTime = strtol((char*)chip_attribute, NULL, 16); 545 | } 546 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"EraseCmd"); 547 | if(chip_attribute){ 548 | Chip_Info_temp.EraseCmd = strtol((char*)chip_attribute, NULL, 16); 549 | } 550 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ProgramCmd"); 551 | if(chip_attribute){ 552 | Chip_Info_temp.ProgramCmd = strtol((char*)chip_attribute, NULL, 16); 553 | } 554 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ReadCmd"); 555 | if(chip_attribute){ 556 | Chip_Info_temp.ReadCmd = strtol((char*)chip_attribute, NULL, 16); 557 | } 558 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"ProtectBlockMask"); 559 | if(chip_attribute){ 560 | Chip_Info_temp.ProtectBlockMask = strtol((char*)chip_attribute, NULL, 16); 561 | } 562 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"UnlockCmd"); 563 | if(chip_attribute){ 564 | Chip_Info_temp.UnlockCmd = strtol((char*)chip_attribute, NULL, 16); 565 | } 566 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"RDSRCnt"); 567 | if(chip_attribute){ 568 | Chip_Info_temp.RDSRCnt = strtol((char*)chip_attribute, NULL, 16); 569 | } 570 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"WRSRCnt"); 571 | if(chip_attribute){ 572 | Chip_Info_temp.WRSRCnt = strtol((char*)chip_attribute, NULL, 16); 573 | } 574 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"WRSRCmd"); 575 | if(chip_attribute){ 576 | Chip_Info_temp.WRSRCmd = strtol((char*)chip_attribute, NULL, 16); 577 | } 578 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"WRCRCmd"); 579 | if(chip_attribute){ 580 | Chip_Info_temp.WRCRCmd = strtol((char*)chip_attribute, NULL, 16); 581 | } 582 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"RDSRCmd"); 583 | if(chip_attribute){ 584 | Chip_Info_temp.RDSRCmd = strtol((char*)chip_attribute, NULL, 16); 585 | } 586 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"RDCRCmd"); 587 | if(chip_attribute){ 588 | Chip_Info_temp.RDCRCmd = strtol((char*)chip_attribute, NULL, 16); 589 | } 590 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"QEbitAddr"); 591 | if(chip_attribute){ 592 | Chip_Info_temp.QEbitAddr = strtol((char*)chip_attribute, NULL, 16); 593 | } 594 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"SupportLUT"); 595 | if(chip_attribute){ 596 | if (strstr((char*)chip_attribute, "true") != NULL) 597 | Chip_Info_temp.SupportLUT = true; 598 | else 599 | Chip_Info_temp.SupportLUT = false; 600 | } 601 | } 602 | xmlFree(chip_attribute); 603 | } 604 | 605 | xmlFreeDoc(doc); 606 | Chip_Info->MaxErasableSegmentInByte = max(Chip_Info->SectorSizeInByte, Chip_Info->BlockSizeInByte); 607 | 608 | if (found_flag == 0) { 609 | Chip_Info->TypeName[0] = 0; 610 | Chip_Info->UniqueID = 0; 611 | } 612 | return found_flag; /*Executed without errors*/ 613 | } 614 | 615 | 616 | bool Dedi_List_AllChip(void) 617 | { 618 | char file_path[linebufsize]; 619 | char Type[256] = { 0 }; 620 | xmlDocPtr doc; 621 | xmlNodePtr cur_node; 622 | xmlChar *chip_attribute; 623 | 624 | if (GetChipDbPath(file_path) == false) 625 | { 626 | return 1; 627 | } 628 | 629 | doc = xmlParseFile(file_path); 630 | cur_node = xmlDocGetRootElement(doc); // DediProgChipDatabase 631 | cur_node = cur_node->children->next; //Portofolio 632 | cur_node = cur_node->children->next; //C 633 | // data_temp = file_buf; 634 | /*Read into the buffer contents within thr file stream*/ 635 | while (cur_node != NULL) { 636 | if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"Chip"))) { 637 | 638 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"TypeName"); 639 | if(chip_attribute){ 640 | strcpy(Type, (char*)chip_attribute); 641 | //printf("TypeName: %s\n", chip_attribute); 642 | } 643 | chip_attribute = xmlGetProp(cur_node, (const xmlChar *)"Manufacturer"); 644 | if(chip_attribute){ 645 | printf("%s\t\tby %s\n", Type, (char*)chip_attribute); 646 | } 647 | xmlFree(chip_attribute); 648 | } 649 | cur_node = cur_node->next; 650 | } 651 | 652 | xmlFreeDoc(doc); 653 | 654 | return true; 655 | 656 | } 657 | 658 | #else 659 | FILE* openChipInfoDb(void) 660 | { 661 | FILE* fp = NULL; 662 | char Path[linebufsize]; 663 | 664 | memset(Path, 0, linebufsize); 665 | if (readlink("/proc/self/exe", Path, 512) != -1) { 666 | dirname(Path); 667 | strcat(Path, "/ChipInfoDb.dedicfg"); 668 | // printf("%s\n",Path); 669 | if ((fp = fopen(Path, "rt")) == NULL) { 670 | // ChipInfoDb.dedicfg not in program directory 671 | dirname(Path); 672 | dirname(Path); 673 | strcat(Path, "/share/DediProg/ChipInfoDb.dedicfg"); 674 | // printf("%s\n",Path); 675 | if ((fp = fopen(Path, "rt")) == NULL) 676 | fprintf(stderr, "Error opening file: %s\n", Path); 677 | } 678 | } 679 | 680 | //xml_parse_result result = doc.load_file( Path ); 681 | //if ( result.status != xml_parse_status::status_ok ) 682 | // return; 683 | 684 | return fp; 685 | } 686 | 687 | long fsize(FILE* fp) 688 | { 689 | long prev = ftell(fp); 690 | fseek(fp, 0L, SEEK_END); 691 | long sz = ftell(fp); 692 | fseek(fp, prev, SEEK_SET); // go back to where we were 693 | return sz; 694 | } 695 | 696 | int Dedi_Search_Chip_Db(char* chTypeName, long RDIDCommand, 697 | long UniqueID, 698 | CHIP_INFO* Chip_Info, 699 | int search_all) 700 | { 701 | 702 | FILE* fp; /*Declare file pointer variable*/ 703 | int found_flag = 0; 704 | char file_line_buf[linebufsize], *tok, *file_buf, test[testbufsize]; 705 | char* pch; 706 | long sz = 0; 707 | int detectICNum = 0; 708 | char strTypeName[32][100]; 709 | CHIP_INFO Chip_Info_temp; 710 | 711 | for (int i = 0; i < 32; i++) 712 | memset(strTypeName[i], '\0', 100); 713 | 714 | memset(chTypeName, '\0', 1024); 715 | 716 | memset(Chip_Info->TypeName, '\0', linebufsize); //strlen(Chip_Info->TypeName)=0 717 | 718 | if ((fp = openChipInfoDb()) == NULL) 719 | return 1; 720 | sz = fsize(fp); 721 | file_buf = (char*)malloc(sz); 722 | 723 | memset(file_buf, '\0', sz); 724 | /*Read into the buffer contents within thr file stream*/ 725 | 726 | while (fgets(file_line_buf, linebufsize, fp) != NULL) { 727 | pch = strstr(file_line_buf, "TypeName"); 728 | //printf("ile_line_buf=%s",file_line_buf) ; 729 | if (pch != NULL) { 730 | if (found_flag == 1) { 731 | found_flag = 0; 732 | 733 | if (strlen(Chip_Info->TypeName) == 0) 734 | *Chip_Info = Chip_Info_temp; //first chip info 735 | } 736 | // break; 737 | 738 | memset(test, '\0', testbufsize); 739 | strcpy(test, pch + strlen("TypeName")); 740 | tok = strtok(test, "\"= \t"); 741 | Chip_Info_temp.TypeName[0] = '\0'; 742 | Chip_Info_temp.Class[0] = '\0'; 743 | Chip_Info_temp.UniqueID = 0; 744 | Chip_Info_temp.Description[0] = '\0'; 745 | Chip_Info_temp.Manufacturer[0] = '\0'; 746 | Chip_Info_temp.ManufactureUrl[0] = '\0'; 747 | Chip_Info_temp.ProgramIOMethod[0] = '\0'; 748 | Chip_Info_temp.Voltage[0] = '\0'; 749 | Chip_Info_temp.Clock[0] = '\0'; 750 | Chip_Info_temp.ManufactureID = 0; 751 | Chip_Info_temp.JedecDeviceID = 0; 752 | Chip_Info_temp.AlternativeID = 0; 753 | Chip_Info_temp.ChipSizeInByte = 0; 754 | Chip_Info_temp.SectorSizeInByte = 0; 755 | Chip_Info_temp.BlockSizeInByte = 0; 756 | Chip_Info_temp.PageSizeInByte = 0; 757 | Chip_Info_temp.AddrWidth = 0; 758 | Chip_Info_temp.ReadDummyLen = 0; 759 | Chip_Info_temp.IDNumber = 0; 760 | Chip_Info_temp.RDIDCommand = 0; 761 | Chip_Info_temp.MaxErasableSegmentInByte = 0; 762 | Chip_Info_temp.DualID = false; 763 | Chip_Info_temp.VppSupport = 0; 764 | Chip_Info_temp.MXIC_WPmode = false; 765 | Chip_Info_temp.Timeout = 0; 766 | // end of struct init 767 | strcpy(Chip_Info_temp.TypeName, tok); 768 | 769 | continue; 770 | } 771 | 772 | pch = strstr(file_line_buf, "Class"); 773 | if (pch != NULL) { 774 | memset(test, '\0', testbufsize); 775 | strcpy(test, pch + strlen("Class")); 776 | tok = strtok(test, "\"= \t"); 777 | //printf("Class = %s\n",tok); 778 | strcpy(Chip_Info_temp.Class, tok); 779 | continue; 780 | } 781 | pch = strstr(file_line_buf, "UniqueID"); 782 | if (pch != NULL) { 783 | memset(test, '\0', testbufsize); 784 | strcpy(test, pch + strlen("UniqueID")); 785 | tok = strtok(test, "\"= \t"); 786 | //printf("UniqueID = 0x%lx\n",strtol(tok,NULL,16)); 787 | Chip_Info_temp.UniqueID = strtol(tok, NULL, 16); 788 | if ((UniqueID == Chip_Info_temp.UniqueID)) { 789 | //found_flag = 1; 790 | //detectICNum++; 791 | } 792 | 793 | continue; 794 | } 795 | pch = strstr(file_line_buf, "Manufacturer"); 796 | if (pch != NULL) { 797 | memset(test, '\0', testbufsize); 798 | strcpy(test, pch + strlen("Manufacturer")); 799 | tok = strtok(test, "\"= \t"); 800 | //printf("Manufacturer = %s\n",tok); 801 | strcpy(Chip_Info_temp.Manufacturer, tok); 802 | continue; 803 | } 804 | pch = strstr(file_line_buf, "Voltage"); 805 | if (pch != NULL) { 806 | memset(test, '\0', testbufsize); 807 | strcpy(test, pch + strlen("Voltage")); 808 | tok = strtok(test, "\"= \t"); 809 | if (strcmp(tok, "3.3V") == 0) 810 | Chip_Info_temp.VoltageInMv = 3300; 811 | else if (strcmp(tok, "2.5V") == 0) 812 | Chip_Info_temp.VoltageInMv = 2500; 813 | else if (strcmp(tok, "1.8V") == 0) 814 | Chip_Info_temp.VoltageInMv = 1800; 815 | else 816 | Chip_Info_temp.VoltageInMv = 3300; 817 | continue; 818 | } 819 | pch = strstr(file_line_buf, "JedecDeviceID"); 820 | if (pch != NULL) { 821 | memset(test, '\0', testbufsize); 822 | strcpy(test, pch + strlen("JedecDeviceID")); 823 | tok = strtok(test, "\"= \t"); 824 | //printf("JedecDeviceID = 0x%lx\n",strtol(tok,NULL,16)); 825 | Chip_Info_temp.JedecDeviceID = strtol(tok, NULL, 16); 826 | if ((UniqueID == Chip_Info_temp.JedecDeviceID)) { 827 | found_flag = 1; 828 | 829 | strcpy(strTypeName[detectICNum], Chip_Info_temp.TypeName); 830 | //printf("strTypeName[%d] = %s\n",detectICNum,strTypeName[detectICNum]); 831 | strcat(chTypeName, " "); 832 | strcat(chTypeName, strTypeName[detectICNum]); 833 | detectICNum++; 834 | } 835 | continue; 836 | } 837 | pch = strstr(file_line_buf, "ChipSizeInKByte"); 838 | if (pch != NULL) { 839 | memset(test, '\0', testbufsize); 840 | strcpy(test, pch + strlen("ChipSizeInKByte")); 841 | tok = strtok(test, "\"= \t"); 842 | //printf("ChipSizeInKByte = %ld\n",strtol(tok,NULL,10)); 843 | Chip_Info_temp.ChipSizeInByte = strtol(tok, NULL, 10) * 1024; 844 | continue; 845 | } 846 | pch = strstr(file_line_buf, "SectorSizeInByte"); 847 | if (pch != NULL) { 848 | memset(test, '\0', testbufsize); 849 | strcpy(test, pch + strlen("SectorSizeInByte")); 850 | tok = strtok(test, "\"= \t"); 851 | //printf("SectorSizeInByte = %ld\n",strtol(tok,NULL,10)); 852 | Chip_Info_temp.SectorSizeInByte = strtol(tok, NULL, 10); 853 | continue; 854 | } 855 | pch = strstr(file_line_buf, "BlockSizeInByte"); 856 | if (pch != NULL) { 857 | memset(test, '\0', testbufsize); 858 | strcpy(test, pch + strlen("BlockSizeInByte")); 859 | tok = strtok(test, "\"= \t"); 860 | //printf("BlockSizeInByte = %ld\n",strtol(tok,NULL,10)); 861 | Chip_Info_temp.BlockSizeInByte = strtol(tok, NULL, 10); 862 | continue; 863 | } 864 | pch = strstr(file_line_buf, "PageSizeInByte"); 865 | if (pch != NULL) { 866 | memset(test, '\0', testbufsize); 867 | strcpy(test, pch + strlen("PageSizeInByte")); 868 | tok = strtok(test, "\"= \t"); 869 | //printf("PageSizeInByte = %ld\n",strtol(tok,NULL,10)); 870 | Chip_Info_temp.PageSizeInByte = strtol(tok, NULL, 10); 871 | continue; 872 | } 873 | pch = strstr(file_line_buf, "AddrWidth"); 874 | if (pch != NULL) { 875 | memset(test, '\0', testbufsize); 876 | strcpy(test, pch + strlen("AddrWidth")); 877 | tok = strtok(test, "\"= \t"); 878 | //printf("AddrWidth = %ld\n",strtol(tok,NULL,10)); 879 | Chip_Info_temp.AddrWidth = strtol(tok, NULL, 10); 880 | continue; 881 | } 882 | pch = strstr(file_line_buf, "ReadDummyLen"); 883 | if (pch != NULL) { 884 | memset(test, '\0', testbufsize); 885 | strcpy(test, pch + strlen("ReadDummyLen")); 886 | tok = strtok(test, "\"= \t"); 887 | //printf("ReadDummyLen = %ld\n",strtol(tok,NULL,10)); 888 | Chip_Info_temp.ReadDummyLen = strtol(tok, NULL, 10); 889 | continue; 890 | } 891 | pch = strstr(file_line_buf, "IDNumber"); 892 | if (pch != NULL) { 893 | memset(test, '\0', testbufsize); 894 | strcpy(test, pch + strlen("IDNumber")); 895 | tok = strtok(test, "\"= \t"); 896 | //printf("IDNumber = %ld\n",strtol(tok,NULL,10)); 897 | Chip_Info_temp.IDNumber = strtol(tok, NULL, 10); 898 | continue; 899 | } 900 | pch = strstr(file_line_buf, "VppSupport"); 901 | if (pch != NULL) { 902 | memset(test, '\0', testbufsize); 903 | strcpy(test, pch + strlen("VppSupport")); 904 | tok = strtok(test, "\"= \t"); 905 | //printf("IDNumber = %ld\n",strtol(tok,NULL,10)); 906 | Chip_Info_temp.VppSupport = strtol(tok, NULL, 10); 907 | continue; 908 | } 909 | pch = strstr(file_line_buf, "RDIDCommand"); 910 | if (pch != NULL) { 911 | memset(test, '\0', testbufsize); 912 | strcpy(test, pch + strlen("RDIDCommand")); 913 | tok = strtok(test, "\"= \t"); 914 | //printf("RDIDCommand = %ld\n",strtol(tok,NULL,10)); 915 | Chip_Info_temp.RDIDCommand = strtol(tok, NULL, 16); 916 | continue; 917 | } 918 | pch = strstr(file_line_buf, "Timeout"); 919 | if (pch != NULL) { 920 | memset(test, '\0', testbufsize); 921 | strcpy(test, pch + strlen("Timeout")); 922 | tok = strtok(test, "\"= \t"); 923 | //printf("Timeout = %ld\n",strtol(tok,NULL,10)); 924 | Chip_Info_temp.Timeout = strtol(tok, NULL, 16); 925 | continue; 926 | } 927 | pch = strstr(file_line_buf, "MXIC_WPmode"); 928 | if (pch != NULL) { 929 | memset(test, '\0', testbufsize); 930 | strcpy(test, pch + strlen("MXIC_WPmode")); 931 | tok = strtok(test, "\"= \t"); 932 | if (strstr(tok, "true") != NULL) 933 | Chip_Info_temp.MXIC_WPmode = true; 934 | else 935 | Chip_Info_temp.MXIC_WPmode = false; 936 | // starting checking input data 937 | } 938 | pch = strstr(file_line_buf, "Portofolio"); //end 939 | if (pch != NULL) { 940 | if (detectICNum) 941 | found_flag = 1; 942 | } 943 | 944 | } /*Continue until EOF is encoutered*/ 945 | 946 | fclose(fp); /*Close file*/ 947 | Chip_Info->MaxErasableSegmentInByte = max(Chip_Info->SectorSizeInByte, Chip_Info->BlockSizeInByte); 948 | 949 | free(file_buf); 950 | return found_flag; /*Executed without errors*/ 951 | } /*End main*/ 952 | 953 | int Dedi_Search_Chip_Db_ByTypeName(char* TypeName, CHIP_INFO* Chip_Info) 954 | { 955 | //printf("Dedi_Search_Chip_Db_ByTypeName = %s\n",TypeName); 956 | FILE* fp; /*Declare file pointer variable*/ 957 | int found_flag = 0, i; 958 | char file_line_buf[linebufsize], *tok, *file_buf, test[testbufsize]; 959 | char* pch; 960 | long sz = 0; 961 | char Type[256] = { 0 }; 962 | 963 | for (i = 0; i < strlen(TypeName); i++) 964 | TypeName[i] = toupper(TypeName[i]); 965 | 966 | if ((fp = openChipInfoDb()) == NULL) 967 | return 0; 968 | 969 | sz = fsize(fp); 970 | file_buf = (char*)malloc(sz); 971 | memset(file_buf, '\0', sz); 972 | // data_temp = file_buf; 973 | /*Read into the buffer contents within thr file stream*/ 974 | while (fgets(file_line_buf, linebufsize, fp) != NULL) { 975 | pch = strstr(file_line_buf, "TypeName"); 976 | if (pch != NULL) { 977 | if (found_flag == 1) 978 | break; 979 | memset(test, '\0', testbufsize); 980 | strcpy(test, pch + strlen("TypeName")); 981 | tok = strtok(test, "\"= \t"); 982 | strcpy(Type, tok); 983 | for (i = 0; i < strlen(Type); i++) 984 | Type[i] = toupper(tok[i]); 985 | 986 | if (strcmp(Type, TypeName) == 0) { 987 | found_flag = 1; 988 | Chip_Info->TypeName[0] = '\0'; 989 | Chip_Info->Class[0] = '\0'; 990 | Chip_Info->UniqueID = 0; 991 | Chip_Info->Description[0] = '\0'; 992 | Chip_Info->Manufacturer[0] = '\0'; 993 | Chip_Info->ManufactureUrl[0] = '\0'; 994 | Chip_Info->ProgramIOMethod[0] = '\0'; 995 | Chip_Info->Voltage[0] = '\0'; 996 | Chip_Info->Clock[0] = '\0'; 997 | Chip_Info->ManufactureID = 0; 998 | Chip_Info->JedecDeviceID = 0; 999 | Chip_Info->AlternativeID = 0; 1000 | Chip_Info->ChipSizeInByte = 0; 1001 | Chip_Info->SectorSizeInByte = 0; 1002 | Chip_Info->BlockSizeInByte = 0; 1003 | Chip_Info->PageSizeInByte = 0; 1004 | Chip_Info->AddrWidth = 0; 1005 | Chip_Info->ReadDummyLen = 0; 1006 | Chip_Info->IDNumber = 0; 1007 | Chip_Info->RDIDCommand = 0; 1008 | Chip_Info->MaxErasableSegmentInByte = 0; 1009 | Chip_Info->DualID = false; 1010 | Chip_Info->VppSupport = 0; 1011 | Chip_Info->MXIC_WPmode = false; 1012 | Chip_Info->Timeout = 0; 1013 | // end of struct init 1014 | strcpy(Chip_Info->TypeName, tok); 1015 | } else 1016 | found_flag = 0; 1017 | } 1018 | 1019 | if (found_flag == 0) 1020 | continue; 1021 | 1022 | pch = strstr(file_line_buf, "Class"); 1023 | if (pch != NULL) { 1024 | memset(test, '\0', testbufsize); 1025 | strcpy(test, pch + strlen("Class")); 1026 | tok = strtok(test, "\"= \t"); 1027 | // printf("Class = %s\n",tok); 1028 | strcpy(Chip_Info->Class, tok); 1029 | continue; 1030 | } 1031 | pch = strstr(file_line_buf, "UniqueID"); 1032 | if (pch != NULL) { 1033 | memset(test, '\0', testbufsize); 1034 | strcpy(test, pch + strlen("UniqueID")); 1035 | tok = strtok(test, "\"= \t"); 1036 | // printf("UniqueID = 0x%lx\n",strtol(tok,NULL,16)); 1037 | Chip_Info->UniqueID = strtol(tok, NULL, 16); 1038 | continue; 1039 | } 1040 | pch = strstr(file_line_buf, "Manufacturer"); 1041 | if (pch != NULL) { 1042 | memset(test, '\0', testbufsize); 1043 | strcpy(test, pch + strlen("Manufacturer")); 1044 | tok = strtok(test, "\"= \t"); 1045 | // printf("Manufacturer = %s\n",tok); 1046 | strcpy(Chip_Info->Manufacturer, tok); 1047 | continue; 1048 | } 1049 | pch = strstr(file_line_buf, "Voltage"); 1050 | if (pch != NULL) { 1051 | memset(test, '\0', testbufsize); 1052 | strcpy(test, pch + strlen("Voltage")); 1053 | tok = strtok(test, "\"= \t"); 1054 | // printf("Voltage = %s\n",tok); 1055 | if (strcmp(tok, "3.3V") == 0) 1056 | Chip_Info->VoltageInMv = 3300; 1057 | else if (strcmp(tok, "2.5V") == 0) 1058 | Chip_Info->VoltageInMv = 2500; 1059 | else if (strcmp(tok, "1.8V") == 0) 1060 | Chip_Info->VoltageInMv = 1800; 1061 | else 1062 | Chip_Info->VoltageInMv = 3300; 1063 | continue; 1064 | } 1065 | pch = strstr(file_line_buf, "JedecDeviceID"); 1066 | if (pch != NULL) { 1067 | memset(test, '\0', testbufsize); 1068 | strcpy(test, pch + strlen("JedecDeviceID")); 1069 | tok = strtok(test, "\"= \t"); 1070 | // printf("JedecDeviceID = 0x%lx\n",strtol(tok,NULL,16)); 1071 | Chip_Info->JedecDeviceID = strtol(tok, NULL, 16); 1072 | continue; 1073 | } 1074 | pch = strstr(file_line_buf, "ChipSizeInKByte"); 1075 | if (pch != NULL) { 1076 | memset(test, '\0', testbufsize); 1077 | strcpy(test, pch + strlen("ChipSizeInKByte")); 1078 | tok = strtok(test, "\"= \t"); 1079 | // printf("ChipSizeInKByte = %ld\n",strtol(tok,NULL,10)); 1080 | Chip_Info->ChipSizeInByte = strtol(tok, NULL, 10) * 1024; 1081 | continue; 1082 | } 1083 | pch = strstr(file_line_buf, "SectorSizeInByte"); 1084 | if (pch != NULL) { 1085 | memset(test, '\0', testbufsize); 1086 | strcpy(test, pch + strlen("SectorSizeInByte")); 1087 | tok = strtok(test, "\"= \t"); 1088 | // printf("SectorSizeInByte = %ld\n",strtol(tok,NULL,10)); 1089 | Chip_Info->SectorSizeInByte = strtol(tok, NULL, 10); 1090 | continue; 1091 | } 1092 | pch = strstr(file_line_buf, "BlockSizeInByte"); 1093 | if (pch != NULL) { 1094 | memset(test, '\0', testbufsize); 1095 | strcpy(test, pch + strlen("BlockSizeInByte")); 1096 | tok = strtok(test, "\"= \t"); 1097 | // printf("BlockSizeInByte = %ld\n",strtol(tok,NULL,10)); 1098 | Chip_Info->BlockSizeInByte = strtol(tok, NULL, 10); 1099 | continue; 1100 | } 1101 | pch = strstr(file_line_buf, "PageSizeInByte"); 1102 | if (pch != NULL) { 1103 | memset(test, '\0', testbufsize); 1104 | strcpy(test, pch + strlen("PageSizeInByte")); 1105 | tok = strtok(test, "\"= \t"); 1106 | // printf("PageSizeInByte = %ld\n",strtol(tok,NULL,10)); 1107 | Chip_Info->PageSizeInByte = strtol(tok, NULL, 10); 1108 | continue; 1109 | } 1110 | pch = strstr(file_line_buf, "AddrWidth"); 1111 | if (pch != NULL) { 1112 | memset(test, '\0', testbufsize); 1113 | strcpy(test, pch + strlen("AddrWidth")); 1114 | tok = strtok(test, "\"= \t"); 1115 | // printf("AddrWidth = %ld\n",strtol(tok,NULL,10)); 1116 | Chip_Info->AddrWidth = strtol(tok, NULL, 10); 1117 | continue; 1118 | } 1119 | pch = strstr(file_line_buf, "ReadDummyLen"); 1120 | if (pch != NULL) { 1121 | memset(test, '\0', testbufsize); 1122 | strcpy(test, pch + strlen("ReadDummyLen")); 1123 | tok = strtok(test, "\"= \t"); 1124 | //printf("ReadDummyLen = %ld\n",strtol(tok,NULL,10)); 1125 | Chip_Info->ReadDummyLen = strtol(tok, NULL, 10); 1126 | continue; 1127 | } 1128 | pch = strstr(file_line_buf, "IDNumber"); 1129 | if (pch != NULL) { 1130 | memset(test, '\0', testbufsize); 1131 | strcpy(test, pch + strlen("IDNumber")); 1132 | tok = strtok(test, "\"= \t"); 1133 | // printf("IDNumber = %ld\n",strtol(tok,NULL,10)); 1134 | Chip_Info->IDNumber = strtol(tok, NULL, 10); 1135 | continue; 1136 | } 1137 | pch = strstr(file_line_buf, "VppSupport"); 1138 | if (pch != NULL) { 1139 | memset(test, '\0', testbufsize); 1140 | strcpy(test, pch + strlen("VppSupport")); 1141 | tok = strtok(test, "\"= \t"); 1142 | // printf("IDNumber = %ld\n",strtol(tok,NULL,10)); 1143 | Chip_Info->VppSupport = strtol(tok, NULL, 10); 1144 | continue; 1145 | } 1146 | pch = strstr(file_line_buf, "RDIDCommand"); 1147 | if (pch != NULL) { 1148 | memset(test, '\0', testbufsize); 1149 | strcpy(test, pch + strlen("RDIDCommand")); 1150 | tok = strtok(test, "\"= \t"); 1151 | Chip_Info->RDIDCommand = strtol(tok, NULL, 16); 1152 | continue; 1153 | } 1154 | pch = strstr(file_line_buf, "Timeout"); 1155 | if (pch != NULL) { 1156 | memset(test, '\0', testbufsize); 1157 | strcpy(test, pch + strlen("Timeout")); 1158 | tok = strtok(test, "\"= \t"); 1159 | Chip_Info->Timeout = strtol(tok, NULL, 16); 1160 | continue; 1161 | } 1162 | pch = strstr(file_line_buf, "MXIC_WPmode"); 1163 | if (pch != NULL) { 1164 | memset(test, '\0', testbufsize); 1165 | strcpy(test, pch + strlen("MXIC_WPmode")); 1166 | tok = strtok(test, "\"= \t"); 1167 | if (strstr(tok, "true") != NULL) 1168 | Chip_Info->MXIC_WPmode = true; 1169 | else 1170 | Chip_Info->MXIC_WPmode = false; 1171 | // starting checking input data 1172 | continue; 1173 | } 1174 | } /*Continue until EOF is encoutered*/ 1175 | fclose(fp); /*Close file*/ 1176 | Chip_Info->MaxErasableSegmentInByte = max(Chip_Info->SectorSizeInByte, Chip_Info->BlockSizeInByte); 1177 | 1178 | if (found_flag == 0) { 1179 | Chip_Info->TypeName[0] = 0; 1180 | Chip_Info->UniqueID = 0; 1181 | } 1182 | free(file_buf); 1183 | return found_flag; /*Executed without errors*/ 1184 | } 1185 | 1186 | bool Dedi_List_AllChip(void) 1187 | { 1188 | 1189 | FILE* fp; /*Declare file pointer variable*/ 1190 | char file_line_buf[linebufsize], *tok, *file_buf, test[testbufsize]; 1191 | char* pch; 1192 | char TypeName[100], Manufacturer[100]; 1193 | long sz = 0; 1194 | 1195 | if ((fp = openChipInfoDb()) == NULL) 1196 | return false; 1197 | sz = fsize(fp); 1198 | file_buf = (char*)malloc(sz); 1199 | memset(file_buf, '\0', sz); 1200 | /*Read into the buffer contents within thr file stream*/ 1201 | while (fgets(file_line_buf, linebufsize, fp) != NULL) { 1202 | pch = strstr(file_line_buf, "TypeName"); 1203 | if (pch != NULL) { 1204 | memset(test, '\0', testbufsize); 1205 | strcpy(test, pch + strlen("TypeName")); 1206 | tok = strtok(test, "\"= \t"); 1207 | // end of struct init 1208 | TypeName[0] = '\0'; 1209 | Manufacturer[0] = '\0'; 1210 | strcpy(TypeName, tok); 1211 | continue; 1212 | } 1213 | pch = strstr(file_line_buf, "Manufacturer"); 1214 | if (pch != NULL) { 1215 | memset(test, '\0', testbufsize); 1216 | strcpy(test, pch + strlen("Manufacturer")); 1217 | tok = strtok(test, "\"= \t"); 1218 | // printf("Manufacturer = %s\n",tok); 1219 | strcpy(Manufacturer, tok); 1220 | if (TypeName[0] != '\0' && Manufacturer[0] != '\0') 1221 | printf("%s\t\tby %s\n", TypeName, Manufacturer); 1222 | } 1223 | } /*Continue until EOF is encoutered*/ 1224 | fclose(fp); /*Close file*/ 1225 | return true; 1226 | 1227 | } /*End main*/ 1228 | 1229 | #endif 1230 | /***********************PARSE.TXT (CONTENT)**********************/ 1231 | /* "Move each word to the next line" */ 1232 | /***********************PARSE.EXE (OUTPUT)***********************/ 1233 | /* C:\>parse */ 1234 | /* Enter filename: parse.txt */ 1235 | /* */ 1236 | /* Move */ 1237 | /* each */ 1238 | /* word */ 1239 | /* to */ 1240 | /* the */ 1241 | /* next */ 1242 | /* line. */ 1243 | /* */ 1244 | /* Press any key to continue . . . */ 1245 | /****************************************************************/ 1246 | -------------------------------------------------------------------------------- /project.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef _PROJECT_H 4 | #define _PROJECT_H 5 | 6 | #include "Macro.h" 7 | 8 | #define RES_PROG 0x10 9 | #define RES_VERIFY 0x20 10 | #define RES_BLANK 0x30 11 | #define RES_ERASE 0x40 12 | #define RES_SEND 0x50 13 | #define RES_READ 0x60 14 | #define RES_IDCHECK 0x70 15 | #define RES_EZPORT 0x80 16 | 17 | typedef enum { 18 | BLANKCHECK_WHOLE_CHIP, 19 | PROGRAM_CHIP, 20 | ERASE_WHOLE_CHIP, 21 | READ_WHOLE_CHIP, 22 | READ_ANY_BY_PREFERENCE_CONFIGURATION, 23 | VERIFY_CONTENT, 24 | AUTO, 25 | 26 | Download2Card, 27 | // 07.03.2009 28 | UPDATE_FIRMWARE, 29 | AUTO_UPDATE_FIRMWARE, 30 | BLINK_SITE, 31 | NAND_SCAN_BB, 32 | NAND_SPECIAL_PROGRAM, 33 | NAND_SPECIAL_ERASE, 34 | NAND_SPECIAL_AUTO, 35 | 36 | } OPERATION_TYPE; 37 | 38 | typedef struct thread_data { 39 | OPERATION_TYPE type; 40 | int USBIndex; 41 | } THREAD_STRUCT; 42 | 43 | enum { 44 | GUI_USERS = 1, 45 | CONSOLE_USERS = 2, 46 | DLL_USERS = 3 47 | }; 48 | 49 | bool is_BoardVersionGreaterThan_5_0_0(int Index); 50 | bool is_SF100nBoardVersionGreaterThan_5_5_0(int Index); 51 | bool is_SF600nBoardVersionGreaterThan_6_9_0(int Index); 52 | bool is_SF100nBoardVersionGreaterThan_5_2_0(int Index); 53 | bool is_SF600nBoardVersionGreaterThan_7_0_1n6_7_0(int Index); 54 | //bool is_SF700(int Index); 55 | //bool is_SF600PG2(int Index); 56 | bool is_SF700_Or_SF600PG2(int Index); 57 | int GetFileFormatFromExt(const char* csPath); 58 | #if 0 59 | CHIP_INFO GetFirstDetectionMatch(int Index); 60 | #else 61 | CHIP_INFO GetFirstDetectionMatch(char* TypeName, int Index); 62 | #endif 63 | void SetIOMode(bool isProg, int Index); 64 | bool ReadFile(const char* csPath, unsigned char* buffer, unsigned long* FileSize, unsigned char PaddingByte); 65 | bool WriteFile(const char* csPath, unsigned char* buffer, unsigned int FileSize); 66 | void InitLED(int Index); 67 | bool ProjectInitWithID(CHIP_INFO chipinfo, int Index); // by designated ID 68 | bool ProjectInit(int Index); // by designated ID 69 | void SetProgReadCommand(int Index); 70 | void threadRun(void* Type); 71 | void Run(OPERATION_TYPE type, int DevIndex); 72 | bool threadBlankCheck(int Index); 73 | bool threadEraseWholeChip(int Index); 74 | bool threadReadRangeChip(struct CAddressRange range, int Index); 75 | bool threadConfiguredReadChip(int Index); 76 | bool threadCompareFileAndChip(int Index); 77 | bool threadReadChip(int Index); 78 | bool threadScanBB(int Index); 79 | bool threadPredefinedNandBatchSequences(int Index); 80 | 81 | 82 | int ReadBINFile(const char* filename, unsigned char* buf, unsigned long* size); 83 | int WriteBINFile(const char* filename, unsigned char* buf, unsigned long size); 84 | bool LoadFile(char* filename); 85 | unsigned int CRC32(unsigned char* v, unsigned long size); 86 | void TurnONVpp(int Index); 87 | void TurnONVcc(int Index); 88 | void TurnOFFVpp(int Index); 89 | void TurnOFFVcc(int Index); 90 | bool ProgramChip(int Index); 91 | void PrepareProgramParameters(int Index); 92 | bool ValidateProgramParameters(int Index); 93 | bool IdentifyChipBeforeOperation(int Index); 94 | 95 | static inline int Sleep(unsigned int mSec) 96 | { 97 | return usleep(mSec * 1000); 98 | } 99 | 100 | #endif //_PROJECT_H 101 | -------------------------------------------------------------------------------- /usbdriver.c: -------------------------------------------------------------------------------- 1 | #include "usbdriver.h" 2 | #include "FlashCommand.h" 3 | #include "project.h" 4 | #ifdef __FreeBSD__ 5 | #include 6 | #else 7 | #include 8 | #endif 9 | #include 10 | 11 | unsigned int m_nbDeviceDetected = 0; 12 | unsigned char DevIndex = 0; 13 | extern volatile bool g_bIsSF600[16]; 14 | extern volatile bool g_bIsSF700[16]; 15 | extern volatile bool g_bIsSF600PG2[16]; 16 | extern int g_CurrentSeriase; 17 | extern char g_board_type[8]; 18 | extern int g_firmversion; 19 | extern CHIP_INFO g_ChipInfo; 20 | extern unsigned int g_uiDevNum; 21 | extern bool isSendFFsequence; 22 | 23 | #define SerialFlash_FALSE -1 24 | #define SerialFlash_TRUE 1 25 | 26 | static int dev_index; 27 | static usb_device_entry_t usb_device_entry[MAX_Dev_Index]; 28 | static libusb_device_handle* dediprog_handle[MAX_Dev_Index]; 29 | 30 | static libusb_context* ctx = NULL; 31 | /* 32 | * Filter based on a bus:device combo, to make sure we *only* touch 33 | * that device 34 | */ 35 | unsigned g_usb_devnum = -1; 36 | unsigned g_usb_busnum = -1; 37 | 38 | bool Is_NewUSBCommand(int Index) 39 | { 40 | if (is_SF100nBoardVersionGreaterThan_5_5_0(Index) || is_SF600nBoardVersionGreaterThan_6_9_0(Index) || is_SF700_Or_SF600PG2(Index)) { 41 | return true; 42 | } 43 | return false; 44 | } 45 | extern unsigned char GetFPGAVersion(int Index); 46 | 47 | void usb_dev_init(void) 48 | { 49 | int r; 50 | r = libusb_init(&ctx); 51 | if (r < 0) { 52 | printf("initialization failed!"); 53 | return; 54 | } 55 | #if LIBUSB_API_VERSION < 0x01000106 56 | libusb_set_debug(ctx, LIBUSB_LOG_LEVEL_INFO); 57 | #else 58 | libusb_set_option(ctx, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_INFO); 59 | #endif 60 | } 61 | 62 | void usb_db_init(void) 63 | { 64 | int i; 65 | for (i = 0; i < MAX_Dev_Index; i++) { 66 | usb_device_entry[i].valid = 0; 67 | dediprog_handle[i] = NULL; 68 | } 69 | } 70 | 71 | void AssignSF600orSF700var(int Index) 72 | { 73 | if (Index == -1) 74 | Index = DevIndex; 75 | g_bIsSF600[Index] = false; 76 | g_bIsSF700[Index] = false; 77 | g_bIsSF600PG2[Index] = false; 78 | 79 | CNTRPIPE_RQ rq; 80 | unsigned char vBuffer[32]; 81 | int fw[3]; 82 | memset(vBuffer, '\0', 32); 83 | 84 | rq.Function = URB_FUNCTION_VENDOR_ENDPOINT; 85 | rq.Direction = VENDOR_DIRECTION_IN; 86 | rq.Request = 0x08; 87 | rq.Value = 0; 88 | rq.Index = 0; 89 | rq.Length = 32; 90 | 91 | if (InCtrlRequest(&rq, vBuffer, 32, Index) == SerialFlash_FALSE) 92 | return; 93 | 94 | memcpy(g_board_type, &vBuffer[0], 8); 95 | 96 | //memcpy(g_firmversion,&vBuffer[10],8); 97 | sscanf((char*)&vBuffer[8], "V:%d.%d.%d", &fw[0], &fw[1], &fw[2]); 98 | g_firmversion = ((fw[0] << 16) | (fw[1] << 8) | fw[2]); 99 | 100 | if (strstr(g_board_type, "SF700") != NULL) 101 | g_bIsSF700[Index] = true; 102 | else if (strstr(g_board_type, "SF600") != NULL) 103 | { 104 | if (strstr(g_board_type, "SF600PG2") != NULL) 105 | { 106 | g_bIsSF600PG2[Index] = true; 107 | Sleep(2); 108 | } 109 | else 110 | { 111 | g_bIsSF600[Index] = true; 112 | } 113 | } 114 | 115 | 116 | GetFPGAVersion(Index); 117 | } 118 | 119 | int get_usb_dev_cnt(void) 120 | { 121 | return dev_index; 122 | } 123 | 124 | /* Might be useful for other USB devices as well. static for now. */ 125 | static int FindUSBDevice(void) 126 | { 127 | unsigned int vid = 0x0483; 128 | unsigned int pid = 0xdada; 129 | 130 | usb_db_init(); 131 | 132 | ssize_t count; 133 | libusb_device** devs; 134 | count = libusb_get_device_list(ctx, &devs); 135 | for (size_t idx = 0; idx < count; ++idx) { 136 | libusb_device* device = devs[idx]; 137 | struct libusb_device_descriptor desc = { 0 }; 138 | int rc = libusb_get_device_descriptor(device, &desc); 139 | if (rc < 0) { 140 | printf("Error getting device descriptor\n"); 141 | break; 142 | } 143 | if (desc.idVendor == vid && desc.idProduct == pid) { 144 | usb_device_entry[dev_index].usb_device = device; 145 | usb_device_entry[dev_index].valid = 1; 146 | dev_index++; 147 | } 148 | } 149 | printf(" \n"); 150 | return dev_index; 151 | } 152 | 153 | int OutCtrlRequest(CNTRPIPE_RQ* rq, unsigned char* buf, unsigned long buf_size, int Index) 154 | { 155 | int requesttype; 156 | int ret = 0; 157 | 158 | if (Index == -1) 159 | Index = DevIndex; 160 | 161 | if ((rq->Function != URB_FUNCTION_VENDOR_ENDPOINT) && ((g_bIsSF600[Index] == true) || is_SF700_Or_SF600PG2(Index) == true)) 162 | return true; 163 | 164 | requesttype = 0x00; 165 | 166 | if (rq->Direction == VENDOR_DIRECTION_IN) 167 | requesttype |= 0x80; 168 | if (rq->Function == URB_FUNCTION_VENDOR_DEVICE) 169 | requesttype |= 0x40; 170 | if (rq->Function == URB_FUNCTION_VENDOR_INTERFACE) 171 | requesttype |= 0x41; 172 | if (rq->Function == URB_FUNCTION_VENDOR_ENDPOINT) 173 | requesttype |= 0x42; 174 | if (rq->Function == URB_FUNCTION_VENDOR_OTHER) 175 | requesttype |= 0x43; 176 | 177 | if (dediprog_handle[Index]) { 178 | ret = libusb_control_transfer(dediprog_handle[Index], requesttype, rq->Request, rq->Value, rq->Index, buf, buf_size, DEFAULT_TIMEOUT); 179 | } else { 180 | printf("no device"); 181 | } 182 | if (ret != buf_size) { 183 | printf("Error: %s\n", libusb_strerror(ret)); 184 | return -1; 185 | } 186 | return ret; 187 | } 188 | 189 | int InCtrlRequest(CNTRPIPE_RQ* rq, unsigned char* buf, unsigned long buf_size, int Index) 190 | { 191 | unsigned int requesttype; 192 | unsigned int ret = 0; 193 | 194 | 195 | if ((rq->Function != URB_FUNCTION_VENDOR_ENDPOINT) && ((g_bIsSF600[Index] == true) || is_SF700_Or_SF600PG2(Index) == true)) 196 | return true; 197 | 198 | 199 | if (Index == -1) 200 | Index = DevIndex; 201 | 202 | if (sizeof(buf) == 0) 203 | return 0; 204 | 205 | requesttype = 0x00; 206 | 207 | if (rq->Direction == VENDOR_DIRECTION_IN) 208 | requesttype |= 0x80; 209 | if (rq->Function == URB_FUNCTION_VENDOR_DEVICE) 210 | requesttype |= 0x40; 211 | if (rq->Function == URB_FUNCTION_VENDOR_INTERFACE) 212 | requesttype |= 0x41; 213 | if (rq->Function == URB_FUNCTION_VENDOR_ENDPOINT) 214 | requesttype |= 0x42; 215 | if (rq->Function == URB_FUNCTION_VENDOR_OTHER) 216 | requesttype |= 0x43; 217 | 218 | if (dediprog_handle[Index]) { 219 | ret = libusb_control_transfer(dediprog_handle[Index], requesttype, rq->Request, rq->Value, rq->Index, buf, buf_size, DEFAULT_TIMEOUT); 220 | } else { 221 | printf("no device"); 222 | } 223 | 224 | if (ret != 0 /*!= buf_size*/) 225 | { 226 | return ret; 227 | } 228 | else 229 | { 230 | #if 0 231 | 232 | printf("InCtrlRequest ---ret=%X\n",ret); 233 | printf("evInCtrlRequesty ---Control Pipe output error!\n"); 234 | printf("InCtrlRequest ---rq->Direction=%lX\n",rq->Direction); 235 | printf("InCtrlRequest ---rq->Function=%X\n",rq->Function); 236 | printf("InCtrlRequest ---rq->Request=%X\n",rq->Request); 237 | printf("InCtrlRequest ---rq->Value=%X\n",rq->Value); 238 | printf("InCtrlRequest ---rq->Index=%X\n",rq->Index); 239 | printf("InCtrlRequest ---rq->Length=%lX\n",rq->Length); 240 | printf("InCtrlRequest ---buf_size=%lX\n",buf_size); 241 | printf("InCtrlRequest ---buf[0]=%X\n",buf[0]); 242 | //printf("g_bIsSF600=%d\n",g_bIsSF600); 243 | #endif 244 | printf("Control Pipe input error!\n"); 245 | return -1; 246 | } 247 | 248 | return ret; 249 | } 250 | 251 | // part of USB driver , open usb pipes for data transfor 252 | // should be called after usb successfully opens pipes. 253 | int dediprog_start_appli(int Index) 254 | { 255 | // if((g_bIsSF600[Index] != false) || is_SF700_Or_SF600PG2(Index)!=false) 256 | // return 1; 257 | 258 | CNTRPIPE_RQ rq; 259 | int ret; 260 | unsigned char vInstruction; 261 | 262 | // special instruction 263 | vInstruction = 0; 264 | 265 | rq.Function = URB_FUNCTION_VENDOR_OTHER; 266 | rq.Direction = VENDOR_DIRECTION_IN; 267 | rq.Request = 0xb; 268 | rq.Value = 0x00; 269 | rq.Index = 0x00; 270 | rq.Length = 0x01; 271 | 272 | ret = OutCtrlRequest(&rq, &vInstruction, 1, Index); 273 | 274 | return ret; 275 | } 276 | 277 | int dediprog_get_chipid(int Index) 278 | { 279 | //printf("\n===>usbdrive.c --- dediprog_get_chipid\n"); 280 | CNTRPIPE_RQ rq; 281 | int ret; 282 | unsigned char vInstruction[3]; 283 | 284 | memset(vInstruction, 0, 3); 285 | rq.Function = URB_FUNCTION_VENDOR_ENDPOINT; 286 | rq.Direction = VENDOR_DIRECTION_OUT; 287 | rq.Request = 0x1; 288 | rq.Value = 0xff; 289 | if (Is_NewUSBCommand(Index)) 290 | rq.Index = 0; 291 | else 292 | rq.Index = 0x1; 293 | 294 | rq.Length = 0x1; 295 | 296 | vInstruction[0] = 0x9f; 297 | 298 | ret = OutCtrlRequest(&rq, vInstruction, 1, Index); 299 | 300 | // special instruction 301 | memset(vInstruction, 0, 3); 302 | 303 | rq.Function = URB_FUNCTION_VENDOR_ENDPOINT; 304 | rq.Direction = VENDOR_DIRECTION_IN; 305 | rq.Request = 0x1; 306 | rq.Value = 0x0; 307 | rq.Index = 0x00; 308 | rq.Length = 0x03; 309 | 310 | ret = InCtrlRequest(&rq, vInstruction, 3, Index); 311 | return ret; 312 | } 313 | 314 | // return size read 315 | // if fail , return -1 316 | //long CUSB::BulkPipeRead(PBYTE pBuff, UINT sz, UINT timeOut) const 317 | int BulkPipeRead(unsigned char* pBuff, unsigned int timeOut, int Index) 318 | { 319 | int ret, actual_length; 320 | if (Index == -1) 321 | Index = DevIndex; 322 | 323 | unsigned long cnRead = 512; 324 | ret = libusb_bulk_transfer(dediprog_handle[Index], 2 | LIBUSB_ENDPOINT_IN, pBuff, cnRead, &actual_length, DEFAULT_TIMEOUT); 325 | if (ret != 0) //libusb_bulk_transfer return false 326 | return 0; 327 | return cnRead; 328 | } 329 | 330 | //long CUSB::BulkPipeWrite(PBYTE pBuff, UINT sz, UINT timeOut) const 331 | int BulkPipeWrite(unsigned char* pBuff, unsigned int size, unsigned int timeOut, int Index) 332 | { 333 | int ret, actual_length; 334 | int nWrite = 512; 335 | unsigned char pData[512]; 336 | 337 | memset(pData, 0xFF, 512); // fill buffer with 0xFF 338 | 339 | memcpy(pData, pBuff, size); 340 | 341 | if (Index == -1) 342 | Index = DevIndex; 343 | 344 | ret = libusb_bulk_transfer(dediprog_handle[Index], ((g_bIsSF600[Index] == true) || is_SF700_Or_SF600PG2(Index) == true) ? 0x01 : 0x02, pData, nWrite, &actual_length, DEFAULT_TIMEOUT); 345 | nWrite = ret; 346 | return nWrite; 347 | } 348 | 349 | int dediprog_set_spi_voltage(int v, int Index) 350 | { 351 | int ret = 0; 352 | // int voltage_selector; 353 | CNTRPIPE_RQ rq; 354 | // unsigned char vBuffer[12]; 355 | 356 | if (0 == v) 357 | Sleep(200); 358 | 359 | rq.Function = URB_FUNCTION_VENDOR_ENDPOINT; 360 | rq.Direction = VENDOR_DIRECTION_OUT; 361 | rq.Request = SET_VCC; 362 | rq.Length = 0; 363 | 364 | if (Is_NewUSBCommand(Index)) { 365 | rq.Value = v; 366 | rq.Index = 0; 367 | } else { 368 | rq.Value = v; 369 | rq.Index = 0x04 | g_CurrentSeriase; // ID detect mode 370 | } 371 | ret = OutCtrlRequest(&rq, NULL, 0, Index); 372 | 373 | if (0 != v) { 374 | Sleep(200); 375 | if (isSendFFsequence) { 376 | unsigned char v[4] = { 0xff, 0xff, 0xff, 0xff }; 377 | FlashCommand_SendCommand_OutOnlyInstruction(v, 4, Index); 378 | } 379 | } 380 | return ret; 381 | } 382 | 383 | int dediprog_set_vpp_voltage(int volt, int Index) 384 | { 385 | int ret; 386 | int voltage_selector; 387 | CNTRPIPE_RQ rq; 388 | 389 | switch (volt) { 390 | case 0: 391 | /* Admittedly this one is an assumption. */ 392 | voltage_selector = 0x0; 393 | break; 394 | case 9: 395 | voltage_selector = 0x1; 396 | break; 397 | case 12: 398 | voltage_selector = 0x2; 399 | break; 400 | default: 401 | return 1; 402 | } 403 | 404 | rq.Function = URB_FUNCTION_VENDOR_ENDPOINT; 405 | rq.Direction = VENDOR_DIRECTION_OUT; 406 | rq.Request = 0x03; 407 | rq.Value = voltage_selector; 408 | rq.Index = 0; 409 | rq.Length = 0x0; 410 | 411 | ret = OutCtrlRequest(&rq, NULL, 0, Index); 412 | 413 | if (ret == SerialFlash_FALSE) { 414 | // printf("Command Set VPP Voltage 0x%x failed!\n", voltage_selector); 415 | return 1; 416 | } 417 | return 0; 418 | } 419 | 420 | int dediprog_set_spi_clk(int khz, int Index) 421 | { 422 | return 0; 423 | int ret; 424 | int hz_selector; 425 | CNTRPIPE_RQ rq; 426 | 427 | switch (khz) { 428 | case 24000: 429 | /* Admittedly this one is an assumption. */ 430 | hz_selector = 0x0; 431 | break; 432 | case 8000: 433 | hz_selector = 0x1; 434 | break; 435 | case 12000: 436 | hz_selector = 0x2; 437 | break; 438 | case 3000: 439 | hz_selector = 0x3; 440 | break; 441 | case 2180: 442 | hz_selector = 0x4; 443 | break; 444 | case 1500: 445 | hz_selector = 0x5; 446 | break; 447 | case 750: 448 | hz_selector = 0x6; 449 | break; 450 | case 375: 451 | hz_selector = 0x7; 452 | break; 453 | default: 454 | printf("Unknown clk %i KHz! Aborting.\n", khz); 455 | return 1; 456 | } 457 | // printf("Setting SPI clk to %u.%03u MHz\n", khz / 1000, 458 | // khz % 1000); 459 | 460 | rq.Function = URB_FUNCTION_VENDOR_ENDPOINT; 461 | rq.Direction = VENDOR_DIRECTION_OUT; 462 | rq.Request = 0x61; 463 | rq.Value = hz_selector; 464 | rq.Index = 0; 465 | rq.Length = 0x0; 466 | 467 | ret = OutCtrlRequest(&rq, NULL, 0, Index); 468 | 469 | if (ret == SerialFlash_FALSE) { 470 | // printf("Command Set SPI clk 0x%x failed!\n", hz_selector); 471 | return 1; 472 | } 473 | return 0; 474 | } 475 | 476 | int usb_driver_init(void) 477 | { 478 | //printf("\n===>usbdrive.c --- usb_driver_init\n"); 479 | // struct usb_bus *bus; 480 | // struct usb_device *dev; 481 | bool result = false; 482 | int device_cnt = 0; 483 | int ret; 484 | 485 | for (int i = 0; i < MAX_Dev_Index; i++) { 486 | dediprog_handle[i] = NULL; 487 | } 488 | usb_dev_init(); 489 | 490 | device_cnt = FindUSBDevice(); 491 | 492 | if (g_uiDevNum == 0) { 493 | for (int i = 0; i < device_cnt; i++) { 494 | if (usb_device_entry[i].valid == 0) { 495 | printf("Error: Programmers are not connected.\n"); 496 | return 0; 497 | } 498 | 499 | ret = libusb_open(usb_device_entry[i].usb_device, &dediprog_handle[i]); 500 | if (dediprog_handle[i] == NULL) { 501 | printf("Error: Programmers are not connected.\n"); 502 | return 0; 503 | } 504 | ret = libusb_set_configuration(dediprog_handle[i], 1); 505 | 506 | if (ret) { 507 | printf("Error: Programmers USB set configuration: 0x%x.\n", ret); 508 | return 0; 509 | } 510 | ret = libusb_claim_interface(dediprog_handle[i], 0); 511 | if (ret) { 512 | printf("Error: Programmers USB claim interface: 0x%x.\n", ret); 513 | return 0; 514 | } 515 | 516 | dediprog_start_appli(i); 517 | AssignSF600orSF700var(i); 518 | result = (dediprog_handle[i] != NULL); 519 | } 520 | } else { 521 | if (usb_device_entry[g_uiDevNum - 1].valid == 0) { 522 | printf("Error: Programmers are not connected.\n"); 523 | return 0; 524 | } 525 | 526 | ret = libusb_open(usb_device_entry[g_uiDevNum - 1].usb_device, &dediprog_handle[g_uiDevNum - 1]); 527 | if (dediprog_handle[g_uiDevNum - 1] == NULL) { 528 | printf("Error: Programmers are not connected.\n"); 529 | return 0; 530 | } 531 | //printf("dediprog_handle[%d]=%p\n", g_uiDevNum - 1, dediprog_handle[g_uiDevNum - 1]); 532 | ret = libusb_set_configuration(dediprog_handle[g_uiDevNum - 1], 1); 533 | 534 | if (ret) { 535 | printf("Error: Programmers USB set configuration: 0x%x.\n", ret); 536 | return 0; 537 | } 538 | ret = libusb_claim_interface(dediprog_handle[g_uiDevNum - 1], 0); 539 | if (ret) { 540 | printf("Error: Programmers USB claim interface: 0x%x.\n", ret); 541 | return 0; 542 | } 543 | 544 | dediprog_start_appli(g_uiDevNum - 1); 545 | 546 | AssignSF600orSF700var(g_uiDevNum - 1); 547 | 548 | result = (dediprog_handle[g_uiDevNum - 1] != NULL); 549 | } 550 | 551 | return result; //((dediprog_handle[i] != NULL)? 1:0); 552 | } 553 | 554 | int usb_driver_release(void) 555 | { 556 | for (int i = 0; i < dev_index; i++) { 557 | if (dediprog_handle[i] == NULL) 558 | return 0; 559 | libusb_release_interface(dediprog_handle[i], 0); 560 | libusb_close(dediprog_handle[i]); 561 | } 562 | return 0; 563 | } 564 | 565 | bool Is_usbworking(int Index) 566 | { 567 | usleep(1000); // unknow reson 568 | return ((dediprog_handle[Index] != NULL) ? true : false); 569 | } 570 | //long long flash_ReadId(boost::tuple command,int Index) 571 | long flash_ReadId(unsigned int read_id_code, unsigned int out_data_size, int Index) 572 | { 573 | // read status 574 | // if(! m_usb.is_open() ) 575 | // return 0 ; 576 | 577 | // RDID is not decoded when in DP mode 578 | // so , first release from Deep Power Down mode or read signature 579 | // DoRDP() ; 580 | 581 | // send request 582 | 583 | 584 | CNTRPIPE_RQ rq; 585 | unsigned char vInstruction[8]; 586 | unsigned long rc = 0; 587 | int i; 588 | 589 | // first control packet 590 | vInstruction[0] = read_id_code; 591 | rq.Function = URB_FUNCTION_VENDOR_ENDPOINT; 592 | rq.Direction = VENDOR_DIRECTION_OUT; 593 | rq.Request = TRANSCEIVE; 594 | if (Is_NewUSBCommand(Index)) { 595 | rq.Value = RESULT_IN; 596 | rq.Index = 0; 597 | } else { 598 | rq.Value = RFU; 599 | rq.Index = RESULT_IN; 600 | } 601 | rq.Length = 1; 602 | 603 | if (OutCtrlRequest(&rq, vInstruction, (unsigned long)1, Index) == SerialFlash_FALSE) 604 | return rc; //OutCtrlRequest() return error 605 | 606 | // second control packet : fetch data 607 | memset(vInstruction, 0, sizeof(vInstruction)); 608 | 609 | rq.Function = URB_FUNCTION_VENDOR_ENDPOINT; 610 | rq.Direction = VENDOR_DIRECTION_IN; 611 | rq.Request = TRANSCEIVE; 612 | if (Is_NewUSBCommand(Index)) { 613 | rq.Value = 0x01; 614 | rq.Index = 0; 615 | } else { 616 | rq.Value = CTRL_TIMEOUT; 617 | rq.Index = NO_REGISTER; 618 | } 619 | rq.Length = out_data_size; 620 | 621 | if (InCtrlRequest(&rq, vInstruction, (unsigned long)out_data_size, Index) == SerialFlash_FALSE) 622 | return rc; 623 | for (i = 0; i < out_data_size; i++) { 624 | rc = (rc << 8) + vInstruction[i]; 625 | } 626 | // printf("\n(Simon)Flash ID 0x%x (0x%x, %d)\n",rc, read_id_code, out_data_size); 627 | return rc; 628 | } 629 | 630 | int BulkPipeReadEx(unsigned char* pBuff, unsigned int cnRead, unsigned int timeOut, int Index) 631 | { 632 | int ret, actual_length; 633 | if (Index == -1) 634 | Index = DevIndex; 635 | 636 | //unsigned long cnTemp = cnRead; 637 | ret = libusb_bulk_transfer(dediprog_handle[Index], 2 | LIBUSB_ENDPOINT_IN, pBuff, cnRead, &actual_length, DEFAULT_TIMEOUT); 638 | if (ret != 0) //libusb_bulk_transfer return false 639 | return 0; 640 | return cnRead; 641 | } 642 | 643 | -------------------------------------------------------------------------------- /usbdriver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef DEDI_USB_DRIVER 4 | #define DEDI_USB_DRIVER 5 | 6 | #ifdef __FreeBSD__ 7 | #include 8 | #else 9 | #include 10 | #endif 11 | #include 12 | #include 13 | #include 14 | 15 | #define URB_FUNCTION_VENDOR_DEVICE 0x0017 16 | #define URB_FUNCTION_VENDOR_INTERFACE 0x0018 17 | #define URB_FUNCTION_VENDOR_ENDPOINT 0x0019 18 | #define URB_FUNCTION_VENDOR_OTHER 0x0020 19 | 20 | #define URB_FUNCTION_CLASS_DEVICE 0x001A 21 | #define URB_FUNCTION_CLASS_INTERFACE 0x001B 22 | #define URB_FUNCTION_CLASS_ENDPOINT 0x001C 23 | #define URB_FUNCTION_CLASS_OTHER 0x001F 24 | 25 | #define PIPE_RESET 1 26 | #define ABORT_TRANSFER 0 27 | 28 | #define VENDOR_DIRECTION_IN 1 29 | #define VENDOR_DIRECTION_OUT 0 30 | 31 | #define DEFAULT_TIMEOUT 30000 32 | 33 | #define MAX_Dev_Index 16 34 | 35 | bool Is_usbworking(int Index); 36 | 37 | typedef struct usb_device_entry { 38 | libusb_device* usb_device; 39 | int valid; 40 | } usb_device_entry_t; 41 | 42 | typedef struct { 43 | unsigned short Function; 44 | unsigned long Direction; 45 | unsigned char Request; 46 | unsigned short Value; 47 | unsigned short Index; 48 | unsigned long Length; 49 | } CNTRPIPE_RQ, *PCNTRPIPE_RQ; 50 | 51 | /* Set/clear LEDs on dediprog */ 52 | #define PASS_ON (0 << 0) 53 | #define PASS_OFF (1 << 0) 54 | #define BUSY_ON (0 << 1) 55 | #define BUSY_OFF (1 << 1) 56 | #define ERROR_ON (0 << 2) 57 | #define ERROR_OFF (1 << 2) 58 | 59 | int usb_driver_init(void); 60 | int get_usb_dev_cnt(void); 61 | int usb_driver_release(void); 62 | 63 | int OutCtrlRequest(CNTRPIPE_RQ* rq, unsigned char* buf, unsigned long buf_size, int Index); 64 | 65 | int InCtrlRequest(CNTRPIPE_RQ* rq, unsigned char* buf, unsigned long buf_size, int Index); 66 | 67 | int BulkPipeRead(unsigned char* pBuff, unsigned int timeOut, int Index); 68 | 69 | int dediprog_set_spi_voltage(int millivolt, int Index); 70 | int dediprog_set_vpp_voltage(int volt, int Index); 71 | 72 | long flash_ReadId(unsigned int read_id_code, unsigned int out_data_size, int Index); 73 | 74 | int BulkPipeWrite(unsigned char* pBuff, unsigned int size, unsigned int timeOut, int Index); 75 | int BulkPipeReadEx(unsigned char* pBuff, unsigned int cnRead, unsigned int timeOut, int Index); 76 | 77 | 78 | #endif //DEDI_USB_DRIVER 79 | --------------------------------------------------------------------------------