diff --git a/armsrc/Makefile b/armsrc/Makefile index a0f5c7f5c..fb2a2a91b 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -24,7 +24,7 @@ APP_CFLAGS = -DWITH_CRC \ -DWITH_FLASH \ -DWITH_SMARTCARD \ -DWITH_HFSNOOP \ - -DWITH_LF_SAMYRUN \ + -DWITH_HF_COLIN \ -fno-strict-aliasing -ffunction-sections -fdata-sections ### IMPORTANT - move the commented variable below this line @@ -106,12 +106,9 @@ ARMSRC = fpgaloader.c \ parity.c \ usb_cdc.c \ cmd.c \ - lf_samyrun.c \ - vtsend.c - # lf_samyrun.c \ - # lf_hidbrute.c \ - # lf_proxbrute.c \ - # hf_mattyrun.c \ + vtsend.c \ + hf_colin.c \ + lib_AT91SAM7.c VERSIONSRC = version.c \ fpga_version_info.c @@ -120,7 +117,6 @@ VERSIONSRC = version.c \ include ../common/Makefile.common COMMON_FLAGS = -Os - OBJS = $(OBJDIR)/fullimage.s19 FPGA_COMPRESSOR = ../client/fpga_compress diff --git a/armsrc/Standalone/hf_colin.c b/armsrc/Standalone/hf_colin.c index 1ba31a9c7..3a34396eb 100644 --- a/armsrc/Standalone/hf_colin.c +++ b/armsrc/Standalone/hf_colin.c @@ -12,8 +12,6 @@ #define MF1KSZ 1024 #define MF1KSZSIZE 64 -//#define FALSE false -//#define TRUE true #define AUTHENTICATION_TIMEOUT 848 uint8_t cjuid[10]; @@ -27,58 +25,328 @@ int curlline; // Colin's VIGIKPWN sniff/simulate/clone repeat routine for HF Mifare -void cjPrintBigArray(const char *bigar, int len, uint8_t newlines, uint8_t debug) { +void cjPrintBigArray(const char *bigar, int len, uint8_t newlines, uint8_t debug) +{ uint32_t chunksize = (USB_CMD_DATA_SIZE / 4); uint8_t totalchunks = len / chunksize; uint8_t last_chunksize = len - (totalchunks * chunksize); char chunk[chunksize + 1]; memset(chunk, 0x00, sizeof(chunk)); - if (debug > 0) { + if (debug > 0) + { Dbprintf("len : %d", len); Dbprintf("chunksize : %d bytes", chunksize); Dbprintf("totalchunks : %d", totalchunks); Dbprintf("last_chunksize: %d", last_chunksize); } - for (uint8_t i = 0; i < totalchunks; i++) { + for (uint8_t i = 0; i < totalchunks; i++) + { memset(chunk, 0x00, sizeof(chunk)); memcpy(chunk, &bigar[i * chunksize], chunksize); DbprintfEx(FLAG_RAWPRINT, "%s", chunk); } - if (last_chunksize > 0) { + if (last_chunksize > 0) + { memset(chunk, 0x00, sizeof(chunk)); memcpy(chunk, &bigar[totalchunks * chunksize], last_chunksize); DbprintfEx(FLAG_RAWPRINT, "%s", chunk); } - if (newlines > 0) { + if (newlines > 0) + { DbprintfEx(FLAG_NOLOG, " "); } } -void cjSetCursFRight() { +void cjSetCursFRight() +{ vtsend_cursor_position(NULL, 98, (currfline)); currfline++; } -void cjSetCursRight() { +void cjSetCursRight() +{ vtsend_cursor_position(NULL, 59, (currline)); currline++; } -void cjSetCursLeft() { +void cjSetCursLeft() +{ vtsend_cursor_position(NULL, 0, (curlline)); curlline++; } void cjTabulize() { DbprintfEx(FLAG_RAWPRINT, "\t\t\t"); } -void cjPrintKey(uint64_t key, uint8_t *foundKey, uint16_t sectorNo, uint8_t type) { +void cjPrintKey(uint64_t key, uint8_t *foundKey, uint16_t sectorNo, uint8_t type) +{ char tosendkey[13]; sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[0], foundKey[1], foundKey[2], foundKey[3], foundKey[4], foundKey[5]); cjSetCursRight(); DbprintfEx(FLAG_NOLOG, "SEC: %02x | KEY : %s | TYP: %d", sectorNo, tosendkey, type); } -void RunMod() { +void SpinOff(uint32_t pause) +{ + LED_A_OFF(); + LED_B_OFF(); + LED_C_OFF(); + LED_D_OFF(); + SpinDelay(pause); +} + +// 0=A, 1=B, 2=C, 3=D +void SpinErr(uint8_t led, uint32_t speed, uint8_t times) +{ + SpinOff(speed); + NTIME(times) + { + switch (led) + { + case 0: + LED_A_INV(); + break; + case 1: + LED_B_INV(); + break; + case 2: + LED_C_INV(); + break; + case 3: + LED_D_INV(); + break; + } + SpinDelay(speed); + } +} + +void SpinDown(uint32_t speed) +{ + SpinOff(speed); + LED_D_ON(); + SpinDelay(speed); + LED_D_OFF(); + LED_C_ON(); + SpinDelay(speed); + LED_C_OFF(); + LED_B_ON(); + SpinDelay(speed); + LED_B_OFF(); + LED_A_ON(); + SpinDelay(speed); + LED_A_OFF(); +} + +void SpinUp(uint32_t speed) +{ + SpinOff(speed); + LED_A_ON(); + SpinDelay(speed); + LED_A_OFF(); + LED_B_ON(); + SpinDelay(speed); + LED_B_OFF(); + LED_C_ON(); + SpinDelay(speed); + LED_C_OFF(); + LED_D_ON(); + SpinDelay(speed); + LED_D_OFF(); +} + +void TestFlashmemSpeed(size_t buffersize, bool fastmode) +{ + + DbprintfEx(FLAG_NOLOG, "%s---+----[ %s %s[%dKB] %s]", _GREEN_, _WHITE_, _YELLOW_, buffersize / 1024, _WHITE_); + uint16_t t = 0; + + LED_B_ON(); + uint8_t *mem = BigBuf_malloc(buffersize); + bool isok = false; + size_t len = 0; + uint32_t startidx = 0; + uint32_t numofbytes = 0x3FFFF; + + if (!FlashInit(fastmode)) { + return; + } + Flash_CheckBusy(BUSY_TIMEOUT); + + //Flash_ReadStat1(); + + uint32_t end_time; + uint32_t start_time = end_time = GetTickCount(); + + for (size_t i = 0; i < numofbytes; i += buffersize) + { + len = MIN((numofbytes - i), buffersize); + + //isok = Flash_ReadData(startidx + i, mem, len); + //uint32_t iend_time; + //uint32_t istart_time = iend_time = GetTickCount(); + if (fastmode) + { + isok = Flash_FastReadDataCont(startidx + i, mem, len); + } + else + { + isok = Flash_ReadDataCont(startidx + i, mem, len); + } + //iend_time = GetTickCount(); + //DbprintfEx(FLAG_RAWPRINT, "%s%dms%s>", _YELLOW_, iend_time - istart_time, _WHITE_); + //cjSetCursLeft(); + if (!isok) + { + Dbprintf("[FAIL] reading flash memory failed :: | bytes between %d - %d", i, len); + return; + } + //isok = cmd_send(CMD_DOWNLOADED_FLASHMEM, i, len, 0, mem, len); + //if (!isok) + // Dbprintf("transfer to client failed :: | bytes between %d - %d", i, len); + t++; + } + end_time = GetTickCount(); + DbprintfEx(FLAG_NOLOG, "%s |--< %s %s%dms%s for FULL_FLASH_READ", _GREEN_, _WHITE_, _YELLOW_, end_time - start_time, _WHITE_); + DbprintfEx(FLAG_NOLOG, "%s `--= %s %d runs of %s~%dms%s each", _GREEN_, _WHITE_, t, _YELLOW_, (end_time - start_time) / t, _WHITE_); + DbprintfEx(FLAG_NOLOG, ""); + //cjSetCursLeft(); + LED_B_OFF(); + FlashStop(); +} + +void ReadLastTagFromFlash() +{ + + SpinOff(0); + LED_A_ON(); + LED_B_ON(); + LED_C_ON(); + LED_D_ON(); + uint16_t isok = 0; + uint32_t startidx = 0; + uint16_t len = 1024; + + DbprintfEx(FLAG_NOLOG, "Button HELD ! Using LAST Known TAG for Simulation..."); + cjSetCursLeft(); + + size_t size = len; + uint8_t *mem = BigBuf_malloc(size); + + //if (!FlashFastReadInit()){ + if (!FlashInit(0)) + { + return; + } + //Flash_ReadStat1(); + + uint32_t end_time; + uint32_t start_time = end_time = GetTickCount(); + + for (size_t i = 0; i < len; i += size) + { + len = MIN((len - i), size); + + // isok = Flash_FastReadDataCont(startidx + i, mem, len); + isok = Flash_ReadDataCont(startidx + i, mem, len); + if (isok == len) + { + //print_result("Chunk: ", mem, len); + emlSetMem(mem, 0, 64); + } + else + { + DbprintfEx(FLAG_NOLOG, "FlashMem reading failed | %d | %d", len, isok); + cjSetCursLeft(); + SpinOff(100); + FlashStop(); + return; + } + } + end_time = GetTickCount(); + DbprintfEx(FLAG_NOLOG, "[OK] Last tag recovered from FLASHMEM set to emulator"); + cjSetCursLeft(); + DbprintfEx(FLAG_NOLOG, "%s[IN]%s %s%dms%s for TAG_FLASH_READ", _GREEN_, _WHITE_, _YELLOW_, end_time - start_time, _WHITE_); + cjSetCursLeft(); + FlashStop(); + SpinOff(0); + return; +} + +void WriteTagToFlash(uint8_t index, size_t size) +{ + + SpinOff(0); + LED_A_ON(); + LED_B_ON(); + LED_C_ON(); + LED_D_ON(); + + uint8_t isok = 0; + uint16_t res = 0; + uint32_t len = size; + uint32_t bytes_sent = 0; + uint32_t bytes_remaining = len; + + uint8_t data[(size * (16 * 64))/1024]; + uint8_t buff[PAGESIZE]; + // cnt = 0; + emlGetMem(data, 0, (size * 64)/1024); + + //if (!FlashFastReadInit()){ + if (!FlashInit(0)) + { + return; + } + + Flash_WriteEnable(); + Flash_Erase4k(0,0); + Flash_CheckBusy(BUSY_TIMEOUT); + Flash_WriteEnable(); + + uint32_t end_time; + uint32_t start_time = end_time = GetTickCount(); + + while (bytes_remaining > 0) + { + uint32_t bytes_in_packet = MIN(FLASH_MEM_BLOCK_SIZE, bytes_remaining); + + memcpy(buff, data + bytes_sent, bytes_in_packet); + + bytes_remaining -= bytes_in_packet; + res = Flash_WriteDataCont(bytes_sent + (index * size), buff, bytes_in_packet); + bytes_sent += bytes_in_packet; + + isok = (res == bytes_in_packet) ? 1 : 0; + + if (!isok) + { + DbprintfEx(FLAG_NOLOG, "FlashMem write FAILEd [offset %u]", bytes_sent); + cjSetCursLeft(); + SpinOff(100); + + return; + } + + LED_A_INV(); + LED_B_INV(); + LED_C_INV(); + LED_D_INV(); + } + end_time = GetTickCount(); + + DbprintfEx(FLAG_NOLOG, "[OK] TAG WRITTEN TO FLASH ! [0-to offset %u]", bytes_sent); + cjSetCursLeft(); + DbprintfEx(FLAG_NOLOG, "%s[IN]%s %s%dms%s for TAG_FLASH_WRITE", _GREEN_, _WHITE_, _YELLOW_, end_time - start_time, _WHITE_); + cjSetCursLeft(); + + FlashStop(); + + SpinOff(0); + + return; +} + +void RunMod() +{ currline = 20; curlline = 20; currfline = 24; @@ -89,7 +357,7 @@ void RunMod() { uint64_t key64; // Defines current key uint8_t *keyBlock = NULL; // Where the keys will be held in memory. -/* VIGIK EXPIRED DUMP FOR STUDY + /* VIGIK EXPIRED DUMP FOR STUDY Sector 0 121C7F730208040001FA33F5CB2D021D 44001049164916491649000000000000 @@ -125,11 +393,11 @@ KEY A : 1KGIV ; ACCBITS : 796788[00]+VALUE */ -//---------------------------- -// Set of keys to be used. -// This should cover ~98% of -// French VIGIK system @2017 -//---------------------------- + //---------------------------- + // Set of keys to be used. + // This should cover ~98% of + // French VIGIK system @2017 + //---------------------------- #define STKEYS 37 @@ -177,7 +445,8 @@ ACCBITS : 796788[00]+VALUE keyBlock = BigBuf_malloc(STKEYS * 6); int mfKeysCnt = sizeof(mfKeys) / sizeof(uint64_t); - for (int mfKeyCounter = 0; mfKeyCounter < mfKeysCnt; mfKeyCounter++) { + for (int mfKeyCounter = 0; mfKeyCounter < mfKeysCnt; mfKeyCounter++) + { num_to_bytes(mfKeys[mfKeyCounter], 6, (uint8_t *)(keyBlock + mfKeyCounter * 6)); } @@ -185,10 +454,13 @@ ACCBITS : 796788[00]+VALUE // and why not a simple memset abuse to 0xffize the whole space in one go ? // uint8_t foundKey[2][40][6]; //= [ {0xff} ]; /* C99 abusal 6.7.8.21 uint8_t foundKey[2][40][6]; - for (uint16_t t = 0; t < 2; t++) { - for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) { + for (uint16_t t = 0; t < 2; t++) + { + for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) + { // validKey[t][sectorNo] = false; - for (uint16_t i = 0; i < 6; i++) { + for (uint16_t i = 0; i < 6; i++) + { foundKey[t][sectorNo][i] = 0xff; } } @@ -200,11 +472,6 @@ ACCBITS : 796788[00]+VALUE bool allKeysFound = true; uint32_t size = mfKeysCnt; - LED_A_OFF(); - LED_B_OFF(); - LED_C_OFF(); - LED_D_OFF(); - LED_A_ON(); // banner: vtsend_reset(NULL); @@ -218,7 +485,36 @@ ACCBITS : 796788[00]+VALUE currfline = 24; cjSetCursLeft(); + SpinDown(50); + SpinOff(50); + SpinUp(50); + SpinOff(50); + SpinDown(50); + +#if 0 + DbprintfEx(FLAG_NOLOG, "%s>>%s Will Now Test dumping Full flash [256Kb] (2Mbits)through Bigbuf buffers\n", _GREEN_, _WHITE_); + MF_DBGLEVEL = MF_DBG_NONE; + DbprintfEx(FLAG_NOLOG, "---------\n%s[A]%s Using NORMAL Reads @Max (24Mhz=MCK/2)\n--------", _GREEN_, _WHITE_); + TestFlashmemSpeed(32768,0); + TestFlashmemSpeed(16384 + 4096 + 4096,0); + TestFlashmemSpeed(16384,0); + TestFlashmemSpeed(4096,0); + TestFlashmemSpeed(1024,0); + SpinDelay(1000); + WDT_HIT(); + DbprintfEx(FLAG_NOLOG, "--------\n%s[B]%s Using FAST Reads @Max (48Mhz=MCK=CPUClock/2=MAXSPI)\n--------", _GREEN_, _WHITE_); + TestFlashmemSpeed(32768,1); + TestFlashmemSpeed(16384 + 4096 + 4096,1); + TestFlashmemSpeed(16384,1); + TestFlashmemSpeed(4096,1); + TestFlashmemSpeed(1024,1); + SpinDelay(1000); + WDT_HIT(); + return; +#endif + failtag: + vtsend_cursor_position_save(NULL); vtsend_set_attribute(NULL, 1); vtsend_set_attribute(NULL, 5); @@ -226,11 +522,32 @@ failtag: vtsend_set_attribute(NULL, 0); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - while (!iso14443a_select_card(cjuid, NULL, &cjcuid, true, 0, true)) { + SpinOff(50); + LED_A_ON(); + uint8_t ticker = 0; + //while (!BUTTON_PRESS() && !iso14443a_select_card(cjuid, NULL, &cjcuid, true, 0, true)) + while (!iso14443a_select_card(cjuid, NULL, &cjcuid, true, 0, true)) + { WDT_HIT(); + + ticker++; + if (ticker % 64 == 0) + { + LED_A_INV(); + } + + if (BUTTON_HELD(10) > 0) + { + WDT_HIT(); + DbprintfEx(FLAG_NOLOG, "\t\t\t[ READING FLASH ]"); + ReadLastTagFromFlash(); + goto readysim; + } } + + SpinOff(50); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelay(200); vtsend_cursor_position_restore(NULL); DbprintfEx(FLAG_NOLOG, "\t\t\t%s[ GOT a Tag ! ]%s", _GREEN_, _WHITE_); cjSetCursLeft(); @@ -239,12 +556,16 @@ failtag: DbprintfEx(FLAG_NOLOG, "\t%sGOT TAG :%s %08x%s", _RED_, _CYAN_, cjcuid, _WHITE_); - if (cjcuid == 0) { + if (cjcuid == 0) + { cjSetCursLeft(); - DbprintfEx(FLAG_NOLOG, "%s>>%s BUG: 0000_CJCUID! Retrying...", _RED_, _WHITE_); + SpinErr(0, 100, 8); goto failtag; } + + SpinOff(50); + LED_B_ON(); cjSetCursRight(); DbprintfEx(FLAG_NOLOG, "--------+--------------------+-------"); cjSetCursRight(); @@ -283,31 +604,38 @@ failtag: // also we could avoid first UID check for every block // then let’s expose this “optimal case” of “well known vigik schemes” : - for (uint8_t type = 0; type < 2 && !err && !trapped; type++) { - for (int sec = 0; sec < sectorsCnt && !err && !trapped; ++sec) { + for (uint8_t type = 0; type < 2 && !err && !trapped; type++) + { + for (int sec = 0; sec < sectorsCnt && !err && !trapped; ++sec) + { key = cjat91_saMifareChkKeys(sec * 4, type, NULL, size, &keyBlock[0], &key64); // key = saMifareChkKeys(sec * 4, type, NULL, size, &keyBlock[0], &key64); - if (key == -1) { + if (key == -1) + { err = 1; allKeysFound = false; // used in “portable” imlementation on microcontroller: it reports back the fail and open the standalone lock // cmd_send(CMD_CJB_FSMSTATE_MENU, 0, 0, 0, 0, 0); break; - } else if (key == -2) { + } + else if (key == -2) + { err = 1; // Can't select card. allKeysFound = false; // cmd_send(CMD_CJB_FSMSTATE_MENU, 0, 0, 0, 0, 0); break; - } else { + } + else + { /* BRACE YOURSELF : AS LONG AS WE TRAP A KNOWN KEY, WE STOP CHECKING AND ENFORCE KNOWN SCHEMES */ // uint8_t tosendkey[12]; - char tosendkey[13]; + char tosendkey[12]; num_to_bytes(key64, 6, foundKey[type][sec]); cjSetCursRight(); DbprintfEx(FLAG_NOLOG, "SEC: %02x ; KEY : %012" PRIx64 " ; TYP: %i", sec, key64, type); /*cmd_send(CMD_CJB_INFORM_CLIENT_KEY, 12, sec, type, tosendkey, 12);*/ - - switch (key64) { + switch (key64) + { ///////////////////////////////////////////////////////// // COMMON SCHEME 1 : INFINITRON/HEXACT case 0x484558414354: @@ -328,7 +656,8 @@ failtag: ; // Type 0 / A first uint16_t t = 0; - for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) { + for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) + { num_to_bytes(0x484558414354, 6, foundKey[t][sectorNo]); sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2], foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]); @@ -474,8 +803,10 @@ failtag: // emlClearMem(); // A very weak one... - for (uint16_t t = 0; t < 2; t++) { - for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) { + for (uint16_t t = 0; t < 2; t++) + { + for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) + { num_to_bytes(key64, 6, foundKey[t][sectorNo]); sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2], foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]); @@ -509,7 +840,8 @@ failtag: DbprintfEx(FLAG_NOLOG, "%s>>>>>>>>>>>>!*DONE*!<<<<<<<<<<<<<<%s", _GREEN_, _WHITE_); ; t = 0; - for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) { + for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) + { num_to_bytes(0x414c41524f4e, 6, foundKey[t][sectorNo]); sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2], foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]); @@ -519,7 +851,8 @@ failtag: ; } t = 1; - for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) { + for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) + { num_to_bytes(0x424c41524f4e, 6, foundKey[t][sectorNo]); sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2], foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]); @@ -536,21 +869,25 @@ failtag: } } - if (!allKeysFound) { - // cmd_send(CMD_CJB_FSMSTATE_MENU, 0, 0, 0, 0, 0); + if (!allKeysFound) + { cjSetCursLeft(); cjTabulize(); DbprintfEx(FLAG_NOLOG, "%s[ FAIL ]%s\r\n->did not found all the keys :'(", _RED_, _WHITE_); cjSetCursLeft(); + SpinErr(1, 100, 8); + SpinOff(100); return; } /* Settings keys to emulator */ emlClearMem(); uint8_t mblock[16]; - for (uint8_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) { + for (uint8_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) + { emlGetMem(mblock, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1); - for (uint8_t t = 0; t < 2; t++) { + for (uint8_t t = 0; t < 2; t++) + { memcpy(mblock + t * 10, foundKey[t][sectorNo], 6); } emlSetMem(mblock, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1); @@ -565,27 +902,41 @@ failtag: DbprintfEx(FLAG_NOLOG, "%s>>%s Filling Emulator <- from A keys...", _YELLOW_, _WHITE_); e_MifareECardLoad(sectorsCnt, 0, 0, &filled); - if (filled != 1) { + if (filled != 1) + { cjSetCursLeft(); DbprintfEx(FLAG_NOLOG, "%s>>%s W_FAILURE ! %sTrying fallback B keys....", _RED_, _ORANGE_, _WHITE_); /* no trace, no dbg */ e_MifareECardLoad(sectorsCnt, 1, 0, &filled); - if (filled != 1) { + if (filled != 1) + { cjSetCursLeft(); DbprintfEx(FLAG_NOLOG, "FATAL:EML_FALLBACKFILL_B"); - // cmd_send(CMD_CJB_FSMSTATE_MENU, 0, 0, 0, 0, 0); + SpinErr(2, 100, 8); + SpinOff(100); return; } } + end_time = GetTickCount(); cjSetCursLeft(); DbprintfEx(FLAG_NOLOG, "%s>>%s Time for VIGIK break :%s%dms%s", _GREEN_, _WHITE_, _YELLOW_, end_time - start_time, _WHITE_); - // cmd_send(CMD_CJB_FSMSTATE_MENU, 0, 0, 0, 0, 0); + vtsend_cursor_position_save(NULL); + vtsend_set_attribute(NULL, 1); + vtsend_set_attribute(NULL, 5); + cjTabulize(); + DbprintfEx(FLAG_NOLOG, "[ WRITING FLASH ]"); + cjSetCursLeft(); + cjSetCursLeft(); + + WriteTagToFlash(0,1024); + +readysim: // SIM ? cjSetCursLeft(); @@ -602,12 +953,14 @@ failtag: cjTabulize(); - vtsend_cursor_position_save(NULL); - vtsend_set_attribute(NULL, 1); - vtsend_set_attribute(NULL, 5); DbprintfEx(FLAG_NOLOG, "[ SIMULATION ]"); vtsend_set_attribute(NULL, 0); - Mifare1ksim((FLAG_4B_UID_IN_DATA | FLAG_UID_IN_EMUL ), 0, 0, cjuid); + + SpinOff(100); + LED_C_ON(); + Mifare1ksim(FLAG_4B_UID_IN_DATA | FLAG_UID_IN_EMUL, 0, 0, cjuid); + LED_C_OFF(); + SpinOff(50); vtsend_cursor_position_restore(NULL); DbprintfEx(FLAG_NOLOG, "[ SIMUL ENDED ]%s", _GREEN_, _WHITE_); cjSetCursLeft(); @@ -652,7 +1005,9 @@ failtag: DbprintfEx(FLAG_NOLOG, "- [ LA FIN ] -\r\n%s`-> You can take shell back :) ...", _WHITE_); cjSetCursLeft(); vtsend_set_attribute(NULL, 0); - + SpinErr(3, 100, 16); + SpinDown(75); + SpinOff(100); return; } @@ -660,7 +1015,8 @@ failtag: * - *datain used as error return * - tracing is falsed */ -void e_MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain) { +void e_MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain) +{ MF_DBGLEVEL = MF_DBG_NONE; uint8_t numSectors = arg0; @@ -675,9 +1031,6 @@ void e_MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *dat byte_t dataoutbuf2[16]; // uint8_t uid[10]; - LED_A_ON(); - LED_B_OFF(); - LED_C_OFF(); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); clear_trace(); @@ -686,23 +1039,30 @@ void e_MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *dat bool isOK = true; // iso14443a_fast_select_card(cjuid, 0); - if (!iso14443a_select_card(cjuid, NULL, &cjcuid, true, 0, true)) { + if (!iso14443a_select_card(cjuid, NULL, &cjcuid, true, 0, true)) + { isOK = false; if (MF_DBGLEVEL >= 1) DbprintfEx(FLAG_RAWPRINT, "Can't select card"); } - for (uint8_t sectorNo = 0; isOK && sectorNo < numSectors; sectorNo++) { + for (uint8_t sectorNo = 0; isOK && sectorNo < numSectors; sectorNo++) + { ui64Key = emlGetKey(sectorNo, keyType); - if (sectorNo == 0) { - if (isOK && mifare_classic_auth(pcs, cjcuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_FIRST)) { + if (sectorNo == 0) + { + if (isOK && mifare_classic_auth(pcs, cjcuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_FIRST)) + { isOK = false; if (MF_DBGLEVEL >= 1) DbprintfEx(FLAG_NOLOG, "Sector[%2d]. Auth error", sectorNo); break; } - } else { - if (isOK && mifare_classic_auth(pcs, cjcuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_NESTED)) { + } + else + { + if (isOK && mifare_classic_auth(pcs, cjcuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_NESTED)) + { isOK = false; if (MF_DBGLEVEL >= 1) DbprintfEx(FLAG_NOLOG, "Sector[%2d]. Auth nested error", sectorNo); @@ -710,29 +1070,38 @@ void e_MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *dat } } - for (uint8_t blockNo = 0; isOK && blockNo < NumBlocksPerSector(sectorNo); blockNo++) { - if (isOK && mifare_classic_readblock(pcs, cjcuid, FirstBlockOfSector(sectorNo) + blockNo, dataoutbuf)) { + for (uint8_t blockNo = 0; isOK && blockNo < NumBlocksPerSector(sectorNo); blockNo++) + { + if (isOK && mifare_classic_readblock(pcs, cjcuid, FirstBlockOfSector(sectorNo) + blockNo, dataoutbuf)) + { isOK = false; if (MF_DBGLEVEL >= 1) DbprintfEx(FLAG_NOLOG, "Error reading sector %2d block %2d", sectorNo, blockNo); break; }; - if (isOK) { + if (isOK) + { *datain = 1; - if (blockNo < NumBlocksPerSector(sectorNo) - 1) { + if (blockNo < NumBlocksPerSector(sectorNo) - 1) + { emlSetMem(dataoutbuf, FirstBlockOfSector(sectorNo) + blockNo, 1); - } else { // sector trailer, keep the keys, set only the AC + } + else + { // sector trailer, keep the keys, set only the AC emlGetMem(dataoutbuf2, FirstBlockOfSector(sectorNo) + blockNo, 1); memcpy(&dataoutbuf2[6], &dataoutbuf[6], 4); emlSetMem(dataoutbuf2, FirstBlockOfSector(sectorNo) + blockNo, 1); } - } else { + } + else + { *datain = 0; } } } - if (mifare_classic_halt(pcs, cjcuid)) { + if (mifare_classic_halt(pcs, cjcuid)) + { if (MF_DBGLEVEL >= 1) DbprintfEx(FLAG_NOLOG, "Halt error"); }; @@ -741,7 +1110,6 @@ void e_MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *dat crypto1_destroy(pcs); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LEDsoff(); if (MF_DBGLEVEL >= 2) DbpString("EMUL FILL SECTORS FINISHED\n"); @@ -752,7 +1120,8 @@ void e_MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *dat /* the chk function is a piwi’ed(tm) check that will try all keys for a particular sector. also no tracing no dbg */ -int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, uint8_t keyCount, uint8_t *datain, uint64_t *key) { +int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, uint8_t keyCount, uint8_t *datain, uint64_t *key) +{ MF_DBGLEVEL = MF_DBG_NONE; iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); set_tracing(false); @@ -763,40 +1132,41 @@ int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, ui pcs = &mpcs; // byte_t isOK = 0; - for (int i = 0; i < keyCount; ++i) { - LEDsoff(); + for (int i = 0; i < keyCount; ++i) + { /* no need for anticollision. just verify tag is still here */ // if (!iso14443a_fast_select_card(cjuid, 0)) { - if (!iso14443a_select_card(cjuid, NULL, &cjcuid, true, 0, true)) { + if (!iso14443a_select_card(cjuid, NULL, &cjcuid, true, 0, true)) + { cjSetCursLeft(); DbprintfEx(FLAG_NOLOG, "%sFATAL%s : E_MF_LOSTTAG", _RED_, _WHITE_); return -1; } uint64_t ui64Key = bytes_to_num(datain + i * 6, 6); - if (mifare_classic_auth(pcs, cjcuid, blockNo, keyType, ui64Key, AUTH_FIRST)) { + if (mifare_classic_auth(pcs, cjcuid, blockNo, keyType, ui64Key, AUTH_FIRST)) + { uint8_t dummy_answer = 0; ReaderTransmit(&dummy_answer, 1, NULL); // wait for the card to become ready again SpinDelayUs(AUTHENTICATION_TIMEOUT); continue; } - LED_A_ON(); crypto1_destroy(pcs); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); *key = ui64Key; return i; } - LED_A_ON(); crypto1_destroy(pcs); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); return -1; } -void saMifareMakeTag(void) { - // uint8_t cfail = 0;` +void saMifareMakeTag(void) +{ + uint8_t cfail = 0; cjSetCursLeft(); cjTabulize(); vtsend_cursor_position_save(NULL); @@ -808,8 +1178,8 @@ void saMifareMakeTag(void) { DbprintfEx(FLAG_NOLOG, ">> Write to Special:"); int flags = 0; - LED_A_ON(); // yellow - for (int blockNum = 0; blockNum < 16 * 4; blockNum++) { + for (int blockNum = 0; blockNum < 16 * 4; blockNum++) + { uint8_t mblock[16]; // cnt = 0; emlGetMem(mblock, blockNum, 1); @@ -825,10 +1195,12 @@ void saMifareMakeTag(void) { if (blockNum == 16 * 4 - 1) flags = 0x04 + 0x10; - if (saMifareCSetBlock(0, flags & 0xFE, blockNum, mblock)) { //&& cnt <= retry) { - // cnt++; + if (saMifareCSetBlock(0, flags & 0xFE, blockNum, mblock)) + { //&& cnt <= retry) { + // cnt++; cjSetCursFRight(); - if (currfline > 53) { + if (currfline > 53) + { currfline = 54; } DbprintfEx(FLAG_NOLOG, "Block :%02x %sOK%s", blockNum, _GREEN_, _WHITE_); @@ -836,14 +1208,16 @@ void saMifareMakeTag(void) { // cfail=1; // return; continue; - } else { + } + else + { cjSetCursLeft(); cjSetCursLeft(); DbprintfEx(FLAG_NOLOG, "`--> %sFAIL%s : CHN_FAIL_BLK_%02x_NOK", _RED_, _WHITE_, blockNum); cjSetCursFRight(); DbprintfEx(FLAG_NOLOG, "%s>>>>%s STOP AT %02x", _RED_, _WHITE_, blockNum); - + cfail++; break; } cjSetCursFRight(); @@ -855,13 +1229,20 @@ void saMifareMakeTag(void) { break; } */ } + if (cfail == 0) + { + SpinUp(50); + SpinUp(50); + SpinUp(50); + } } //----------------------------------------------------------------------------- // Matt's StandAlone mod. // Work with "magic Chinese" card (email him: ouyangweidaxian@live.cn) //----------------------------------------------------------------------------- -int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain) { +int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain) +{ // params uint8_t needWipe = arg0; @@ -888,30 +1269,32 @@ int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *data uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE]; // reset FPGA and LED - if (workFlags & 0x08) { - LED_A_ON(); - LED_B_OFF(); - LED_C_OFF(); + if (workFlags & 0x08) + { iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); // clear_trace(); set_tracing(FALSE); } - while (true) { - // cjSetCursLeft(); + while (true) + { + cjSetCursLeft(); // get UID from chip - if (workFlags & 0x01) { + if (workFlags & 0x01) + { // if (!iso14443a_fast_select_card(cjuid, 0)) { - if (!iso14443a_select_card(cjuid, NULL, &cjcuid, true, 0, true)) { + if (!iso14443a_select_card(cjuid, NULL, &cjcuid, true, 0, true)) + { if (MF_DBGLEVEL >= 1) DbprintfEx(FLAG_NOLOG, "Can't select card"); break; }; - if (mifare_classic_halt(NULL, cjcuid)) { + if (mifare_classic_halt(NULL, cjcuid)) + { if (MF_DBGLEVEL >= 1) DbprintfEx(FLAG_NOLOG, "Halt error"); break; @@ -919,22 +1302,26 @@ int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *data }; // reset chip - if (needWipe) { + if (needWipe) + { ReaderTransmitBitsPar(wupC1, 7, 0, NULL); - if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) { + if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) + { // if (MF_DBGLEVEL >= 1) DbprintfEx(FLAG_NOLOG, "wupC1 error"); break; }; ReaderTransmit(wipeC, sizeof(wipeC), NULL); - if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) { + if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) + { if (MF_DBGLEVEL >= 1) DbprintfEx(FLAG_NOLOG, "wipeC error"); break; }; - if (mifare_classic_halt(NULL, cjcuid)) { + if (mifare_classic_halt(NULL, cjcuid)) + { if (MF_DBGLEVEL >= 1) DbprintfEx(FLAG_NOLOG, "Halt error"); break; @@ -943,39 +1330,46 @@ int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *data // chaud // write block - if (workFlags & 0x02) { + if (workFlags & 0x02) + { ReaderTransmitBitsPar(wupC1, 7, 0, NULL); - if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) { + if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) + { // if (MF_DBGLEVEL >= 1) DbprintfEx(FLAG_NOLOG, "wupC1 error"); break; }; ReaderTransmit(wupC2, sizeof(wupC2), NULL); - if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) { + if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) + { // if (MF_DBGLEVEL >= 1) DbprintfEx(FLAG_NOLOG, "wupC2 errorv"); break; }; } - if ((mifare_sendcmd_short(NULL, 0, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 1) || (receivedAnswer[0] != 0x0a)) { + if ((mifare_sendcmd_short(NULL, 0, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 1) || (receivedAnswer[0] != 0x0a)) + { // if (MF_DBGLEVEL >= 1) DbprintfEx(FLAG_NOLOG, "write block send command error"); break; }; memcpy(d_block, datain, 16); - AddCrc14A(d_block,16); + AddCrc14A(d_block, 16); ReaderTransmit(d_block, sizeof(d_block), NULL); - if ((ReaderReceive(receivedAnswer, receivedAnswerPar) != 1) || (receivedAnswer[0] != 0x0a)) { + if ((ReaderReceive(receivedAnswer, receivedAnswerPar) != 1) || (receivedAnswer[0] != 0x0a)) + { // if (MF_DBGLEVEL >= 1) DbprintfEx(FLAG_NOLOG, "write block send data error"); break; }; - if (workFlags & 0x04) { - if (mifare_classic_halt(NULL, cjcuid)) { + if (workFlags & 0x04) + { + if (mifare_classic_halt(NULL, cjcuid)) + { // if (MF_DBGLEVEL >= 1) cjSetCursFRight(); @@ -988,12 +1382,10 @@ int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *data break; } - if ((workFlags & 0x10) || (!isOK)) { + if ((workFlags & 0x10) || (!isOK)) + { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LEDsoff(); } return isOK; } - - diff --git a/armsrc/Standalone/hf_colin.h b/armsrc/Standalone/hf_colin.h index 83c152095..29f8f52e6 100644 --- a/armsrc/Standalone/hf_colin.h +++ b/armsrc/Standalone/hf_colin.h @@ -16,18 +16,21 @@ #ifndef __HF_COLIN_H #define __HF_COLIN_H -#include // for bool -#include -#include -#include "standalone.h" // standalone definitions + #include "proxmark3.h" #include "mifareutil.h" #include "iso14443a.h" +//#include "printf.h" #include "protocols.h" #include "util.h" +#include "standalone.h" // standalone definitions +#include // for bool +#include +#include +//#include #include "vtsend.h" #include "apps.h" -#include "usb_cmd.h" // mifare1ksim flags +#include "printf.h" #define _RED_ "\x1b[31m" #define _GREEN_ "\x1b[32m" @@ -38,14 +41,19 @@ #define _WHITE_ "\x1b[0m" #define _ORANGE_ _YELLOW_ +#define NTIME(n) for (int _index = 0; _index < n; _index++) + int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, uint8_t keyCount, uint8_t *datain, uint64_t *key); void e_MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain); void saMifareMakeTag(void); int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain); void cjPrintBigArray(const char *bigar, int len, uint8_t newlines, uint8_t debug); +void WriteTagToFlash(uint8_t index, size_t size); const char clearTerm[8] = {0x1b, 0x5b, 0x48, 0x1b, 0x5b, 0x32, 0x4a, '\0'}; + + #define LOGO logo_kigiv const char sub_banner[] = " From Vigik : \"20 years of (un)security without a single update\""; @@ -410,7 +418,7 @@ const char logo_kigiv[] = { 0x38, 0x3b, 0x35, 0x3b, 0x35, 0x39, 0x6d, 0x31, 0x1b, 0x5b, 0x33, 0x38, 0x3b, 0x35, 0x3b, 0x35, 0x39, 0x6d, 0x31, 0x0d, 0x0a}; unsigned int logo_kigiv_len = 9303; -const char logo_kigiv_nocolor[] = { +/*const char logo_kigiv_nocolor[] = { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x30, 0x30, 0x30, 0x30, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, @@ -494,6 +502,6 @@ const char logo_kigiv_nocolor[] = { 0x30, 0x31, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x31, 0x31, 0x30, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x30, 0x31, 0x31, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x31, 0x30, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x31, 0x31, 0x30, 0x31, 0x31, 0x0d, 0x0a}; -unsigned int logo_kigiv_nocolor_len = 2153; +unsigned int logo_kigiv_nocolor_len = 2153;*/ #endif /* __HF_COLIN_H */ diff --git a/armsrc/appmain.c b/armsrc/appmain.c index c6e6e0dee..b0538383e 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -33,10 +33,6 @@ #include "i2c.h" #endif -#ifdef WITH_FPC -#include "usart.h" -#endif - //============================================================================= // A buffer where we can queue things up to be sent through the FPGA, for // any purpose (fake tag, as reader, whatever). We go MSB first, since that @@ -78,26 +74,24 @@ void PrintToSendBuffer(void) { } void print_result(char *name, uint8_t *buf, size_t len) { - uint8_t *p = buf; - uint16_t tmp = len & 0xFFF0; - for(; p-buf < tmp; p += 16) { - Dbprintf("[%s: %02d/%02d] %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + if ( len % 16 == 0 ) { + for(; p-buf < len; p += 16) + Dbprintf("[%s:%d/%d] %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", name, p-buf, len, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15] ); } - if (len % 16 != 0) { - char s[46] = {0}; - char *sp = s; - for (; p-buf < len; p++ ) { - sprintf(sp, "%02x ", p[0] ); - sp += 3; - } - Dbprintf("[%s: %02d/%02d] %s", name, p-buf, len, s); + else { + for(; p-buf < len; p += 8) + Dbprintf("[%s:%d/%d] %02x %02x %02x %02x %02x %02x %02x %02x", + name, + p-buf, + len, + p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); } } @@ -107,7 +101,7 @@ void print_result(char *name, uint8_t *buf, size_t len) { void DbpStringEx(char *str, uint32_t cmd) { #if DEBUG - uint8_t len = strlen(str); + byte_t len = strlen(str); cmd_send(CMD_DEBUG_PRINT_STRING, len, cmd, 0, (byte_t*)str, len); #endif } @@ -119,7 +113,7 @@ void DbpString(char *str) { } #if 0 -void DbpIntegers(int x1, int x2, int x3) { +void DbpIntegers(inst x1, int x2, int x3) { cmd_send(CMD_DEBUG_PRINT_INTEGERS,x1,x2,x3,0,0); } #endif @@ -440,7 +434,7 @@ void printStandAloneModes(void) { DbpString(" LF HID corporate 1000 bruteforce - (Federico dotta & Maurizio Agazzini)"); #endif #if defined(WITH_HF_MATTYRUN) - DbpString(" HF Mifare sniff/clone - aka MattyRun (Matas A. R Medina)"); + DbpString(" HF Mifare sniff/clone - aka MattyRun (Mat�as A. R� Medina)"); #endif #if defined(WITH_HF_COLIN) DbpString(" HF Mifare ultra fast sniff/sim/clone - aka VIGIKPWN (Colin Brigato)"); @@ -448,7 +442,6 @@ void printStandAloneModes(void) { //DbpString("Running "); //Dbprintf(" Is Device attached to USB| %s", USB_ATTACHED() ? "Yes" : "No"); - //Dbprintf(" Is Device attached to FPC| %s", 0 ? "Yes" : "No"); //Dbprintf(" Is USB_reconnect value | %d", GetUSBreconnect() ); //Dbprintf(" Is USB_configured value | %d", GetUSBconfigured() ); @@ -1077,7 +1070,6 @@ void UsbPacketReceived(uint8_t *packet, int len) { #endif case CMD_BUFF_CLEAR: BigBuf_Clear(); - BigBuf_free(); break; case CMD_MEASURE_ANTENNA_TUNING: @@ -1114,7 +1106,7 @@ void UsbPacketReceived(uint8_t *packet, int len) { len = MIN( (numofbytes - i), USB_CMD_DATA_SIZE); isok = cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K, i, len, BigBuf_get_traceLen(), mem + startidx + i, len); if (!isok) - Dbprintf("transfer to client failed :: | bytes between %d - %d (%d)", i, i+len, len); + Dbprintf("transfer to client failed :: | bytes between %d - %d", i, len); } // Trigger a finish downloading signal with an ACK frame // iceman, when did sending samplingconfig array got attached here?!? @@ -1160,7 +1152,7 @@ void UsbPacketReceived(uint8_t *packet, int len) { len = MIN((numofbytes - i), USB_CMD_DATA_SIZE); isok = cmd_send(CMD_DOWNLOADED_EML_BIGBUF, i, len, 0, mem + startidx + i, len); if (!isok) - Dbprintf("transfer to client failed :: | bytes between %d - %d (%d)", i, i+len, len); + Dbprintf("transfer to client failed :: | bytes between %d - %d", i, len); } // Trigger a finish downloading signal with an ACK frame cmd_send(CMD_ACK, 1, 0, 0, 0, 0); @@ -1177,6 +1169,7 @@ void UsbPacketReceived(uint8_t *packet, int len) { uint16_t isok = 0; uint32_t startidx = c->arg[0]; uint16_t len = c->arg[1]; + uint8_t fast = c->arg[2]; Dbprintf("FlashMem read | %d - %d", startidx, len); @@ -1184,14 +1177,23 @@ void UsbPacketReceived(uint8_t *packet, int len) { uint8_t *mem = BigBuf_malloc(size); + + if (fast) { + FlashInit(1); + //FlashInit(); + Flash_CheckBusy(BUSY_TIMEOUT); + } for(size_t i = 0; i < len; i += size) { len = MIN((len - i), size); - memset(mem, 0, len); - Dbprintf("FlashMem reading | %d | %d | %d", startidx + i, i, len); + if (!fast){ isok = Flash_ReadData(startidx + i, mem, len); + } + if (fast){ + isok = Flash_FastReadDataCont(startidx + i, mem, len); + } if ( isok == len ) { print_result("Chunk: ", mem, len); } else { @@ -1199,6 +1201,9 @@ void UsbPacketReceived(uint8_t *packet, int len) { break; } } + if (fast){ + FlashStop(); + } LED_B_OFF(); break; } @@ -1271,21 +1276,36 @@ void UsbPacketReceived(uint8_t *packet, int len) { size_t len = 0; uint32_t startidx = c->arg[0]; uint32_t numofbytes = c->arg[1]; + uint8_t fast = c->arg[2]; + // arg0 = startindex // arg1 = length bytes to transfer // arg2 = RFU + + + if (fast) { + FlashInit(1); + //FlashInit(); + Flash_CheckBusy(BUSY_TIMEOUT); + } for (size_t i = 0; i < numofbytes; i += USB_CMD_DATA_SIZE) { len = MIN((numofbytes - i), USB_CMD_DATA_SIZE); - + if (!fast){ isok = Flash_ReadData(startidx + i, mem, len); + } + if (fast){ + isok = Flash_FastReadDataCont(startidx + i, mem, len); + } if (!isok ) Dbprintf("reading flash memory failed :: | bytes between %d - %d", i, len); isok = cmd_send(CMD_DOWNLOADED_FLASHMEM, i, len, 0, mem, len); if (!isok) - Dbprintf("transfer to client failed :: | bytes between %d - %d (%d)", i, i+len, len); + Dbprintf("transfer to client failed :: | bytes between %d - %d", i, len); + } + if (fast){ + FlashStop(); } - cmd_send(CMD_ACK, 1, 0, 0, 0, 0); LED_B_OFF(); break; @@ -1297,7 +1317,7 @@ void UsbPacketReceived(uint8_t *packet, int len) { bool isok = Flash_ReadData(FLASH_MEM_SIGNATURE_OFFSET, info->signature, FLASH_MEM_SIGNATURE_LEN); - if (FlashInit()) { + if (FlashInit(0)) { Flash_UniqueID( info->flashid); FlashStop(); } @@ -1392,8 +1412,6 @@ void __attribute__((noreturn)) AppMain(void) { LEDsoff(); - usb_enable(); - // The FPGA gets its clock from us from PCK0 output, so set that up. AT91C_BASE_PIOA->PIO_BSR = GPIO_PCK0; AT91C_BASE_PIOA->PIO_PDR = GPIO_PCK0; @@ -1419,16 +1437,22 @@ void __attribute__((noreturn)) AppMain(void) { StartTickCount(); #ifdef WITH_LCD - LCDInit(); +// LCDInit(); #endif #ifdef WITH_SMARTCARD - I2C_init(); +// I2C_init(); #endif #ifdef WITH_FPC - usart_init(); +// usart_init(); #endif + + // This is made as late as possible to ensure enumeration without timeout + // against device such as http://www.hobbytronics.co.uk/usb-host-board-v2 + usb_disable(); + usb_enable(); + uint8_t rx[sizeof(UsbCommand)]; for(;;) { @@ -1464,6 +1488,10 @@ void __attribute__((noreturn)) AppMain(void) { RunMod(); #endif + // when here, we are no longer in standalone mode. + // reseting the variables which keeps track of usb re-attached/configured + //SetUSBreconnect(0); + //SetUSBconfigured(0); } } } diff --git a/armsrc/flashmem.c b/armsrc/flashmem.c index 7c5beb47a..b5786fbe9 100644 --- a/armsrc/flashmem.c +++ b/armsrc/flashmem.c @@ -1,39 +1,43 @@ #include "flashmem.h" + +#define MCK 48000000 +//#define FLASH_BAUD 24000000 +//define FLASH_BAUD 33000000 +#define FLASH_BAUD MCK/2 +#define FLASH_FASTBAUD MCK + /* here: use NCPS2 @ PA10: */ -#define SPI_CSR_NUM 2 // Chip Select register[] 0,1,2,3 (at91samv512 has 4) - -/* PCS_0 for NPCS0, PCS_1 for NPCS1 ... */ -#define PCS_0 ((0<<0)|(1<<1)|(1<<2)|(1<<3)) // 0xE - 1110 -#define PCS_1 ((1<<0)|(0<<1)|(1<<2)|(1<<3)) // 0xD - 1101 -#define PCS_2 ((1<<0)|(1<<1)|(0<<2)|(1<<3)) // 0xB - 1011 -#define PCS_3 ((1<<0)|(1<<1)|(1<<2)|(0<<3)) // 0x7 - 0111 - -// TODO -#if (SPI_CSR_NUM == 0) -#define SPI_MR_PCS PCS_0 -#elif (SPI_CSR_NUM == 1) -#define SPI_MR_PCS PCS_1 -#elif (SPI_CSR_NUM == 2) -#define SPI_MR_PCS PCS_2 -#elif (SPI_CSR_NUM == 3) -#define SPI_MR_PCS PCS_3 -#else -#error "SPI_CSR_NUM invalid" -// not realy - when using an external address decoder... -// but this code takes over the complete SPI-interace anyway -#endif +#define SPI_CSR_NUM 2 +#define SPI_PCS(npcs) ((~(1 << (npcs)) & 0xF) << 16) +/// Calculates the value of the CSR SCBR field given the baudrate and MCK. +#define SPI_SCBR(baudrate, masterClock) ((uint32_t) ((masterClock) / (baudrate)) << 8) +/// Calculates the value of the CSR DLYBS field given the desired delay (in ns) +#define SPI_DLYBS(delay, masterClock) ((uint32_t) ((((masterClock) / 1000000) * (delay)) / 1000) << 16) +/// Calculates the value of the CSR DLYBCT field given the desired delay (in ns) +#define SPI_DLYBCT(delay, masterClock) ((uint32_t) ((((masterClock) / 1000000) * (delay)) / 32000) << 24) -/* - ȡָԴһλÿʼĶܽоƬȡ - ҳдָÿдΪ1-256ֽڣDzܿԽ256ֽڱ߽ - ָָ뽫CSߣ򲻻ִ -*/ -void FlashSetup(void) { - // PA1 -> SPI_NCS3 chip select (MEM) - // PA10 -> SPI_NCS2 chip select (LCD) +// initialize +bool FlashInit(bool fast) { + FlashSetup(fast); + + StartTicks(); + + if (Flash_CheckBusy(BUSY_TIMEOUT)) { + StopTicks(); + return false; + } + + return true; +} + +void FlashSetup(bool fast){ + //WDT_DISABLE + AT91C_BASE_WDTC->WDTC_WDMR = AT91C_WDTC_WDDIS; + + // PA10 -> SPI_NCS2 chip select (FLASHMEM) // PA11 -> SPI_NCS0 chip select (FPGA) // PA12 -> SPI_MISO Master-In Slave-Out // PA13 -> SPI_MOSI Master-Out Slave-In @@ -54,27 +58,71 @@ void FlashSetup(void) { //enable the SPI Peripheral clock AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SPI); + + //reset spi needs double SWRST, see atmel's errata on this case + AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST; + AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST; + // Enable SPI AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIEN; // NPCS2 Mode 0 AT91C_BASE_SPI->SPI_MR = - ( 0 << 24) | // Delay between chip selects (take default: 6 MCK periods) - (0xB << 16) | // Peripheral Chip Select (selects SPI_NCS2 or PA10) - ( 0 << 7) | // Local Loopback Disabled - ( 1 << 4) | // Mode Fault Detection disabled - ( 0 << 2) | // Chip selects connected directly to peripheral - ( 0 << 1) | // Fixed Peripheral Select - ( 1 << 0); // Master Mode + (0 << 24) | // Delay between chip selects = DYLBCS/MCK BUT: + // If DLYBCS is less than or equal to six, six MCK periods + // will be inserted by default. + SPI_PCS(SPI_CSR_NUM) | // Peripheral Chip Select (selects SPI_NCS2 or PA10) + ( 0 << 7) | // Disable LLB (1=MOSI2MISO test mode) + ( 1 << 4) | // Disable ModeFault Protection + ( 0 << 3) | // makes spi operate at MCK (1 is MCK/2) + ( 0 << 2) | // Chip selects connected directly to peripheral + AT91C_SPI_PS_FIXED | // Fixed Peripheral Select + AT91C_SPI_MSTR; // Master Mode + + int baudrate = FLASH_BAUD; + uint8_t csaat = 1; + int dlybct = 0; + if (fast) { + baudrate = FLASH_FASTBAUD; + //csaat = 0; + dlybct = MCK/32; + } - // 8 bit AT91C_BASE_SPI->SPI_CSR[2] = - ( 0 << 24) | // Delay between Consecutive Transfers (32 MCK periods) - ( 0 << 16) | // Delay Before SPCK (1 MCK period) - ( 6 << 8) | // Serial Clock Baud Rate (baudrate = MCK/6 = 24Mhz/6 = 4M baud - ( 0 << 4) | // Bits per Transfer (8 bits) - ( 1 << 3) | // Chip Select inactive after transfer - ( 1 << 1) | // Clock Phase data captured on leading edge, changes on following edge + SPI_DLYBCT(dlybct,MCK) | // Delay between Consecutive Transfers (32 MCK periods) + SPI_DLYBS(0,MCK) | // Delay Beforce SPCK CLock + SPI_SCBR(baudrate,MCK) | // SPI Baudrate Selection + AT91C_SPI_BITS_8 | // Bits per Transfer (8 bits) + //AT91C_SPI_CSAAT | // Chip Select inactive after transfer + // 40.4.6.2 SPI: Bad tx_ready Behavior when CSAAT = 1 and SCBR = 1 + // If the SPI is programmed with CSAAT = 1, SCBR(baudrate) = 1 and two transfers are performed consecutively on + // the same slave with an IDLE state between them, the tx_ready signal does not rise after the second data has been + // transferred in the shifter. This can imply for example, that the second data is sent twice. + // COLIN :: For now we STILL use CSAAT=1 to avoid having to (de)assert NPCS manually via PIO lines and we deal with delay + ( csaat << 3) | +/* Spi modes: +Mode CPOL CPHA NCPHA +0 0 0 1 clock normally low read on rising edge +1 0 1 0 clock normally low read on falling edge +2 1 0 1 clock normally high read on falling edge +3 1 1 0 clock normally high read on rising edge +However, page 512 of the AT91SAM7Sx datasheet say "Note that in SPI +master mode the ATSAM7S512/256/128/64/321/32 does not sample the data +(MISO) on the opposite edge where data clocks out (MOSI) but the same +edge is used as shown in Figure 36-3 and Figure 36-4." Figure 36-3 +shows that CPOL=NCPHA=0 or CPOL=NCPHA=1 samples on the rising edge and +that the data changes sometime after the rising edge (about 2 ns). To +be consistent with normal SPI operation, it is probably safe to say +that the data changes on the falling edge and should be sampled on the +rising edge. Therefore, it appears that NCPHA should be treated the +same as CPHA. Thus: +Mode CPOL CPHA NCPHA +0 0 0 0 clock normally low read on rising edge +1 0 1 1 clock normally low read on falling edge +2 1 0 0 clock normally high read on falling edge +3 1 1 1 clock normally high read on rising edge +*/ + ( 0 << 1) | // Clock Phase data captured on leading edge, changes on following edge ( 0 << 0); // Clock Polarity inactive state is logic 0 // read first, empty buffer @@ -82,6 +130,7 @@ void FlashSetup(void) { } void FlashStop(void) { + //Bof //* Reset all the Chip Select register AT91C_BASE_SPI->SPI_CSR[0] = 0; AT91C_BASE_SPI->SPI_CSR[1] = 0; @@ -104,24 +153,21 @@ void FlashStop(void) { // send one byte over SPI uint16_t FlashSendByte(uint32_t data) { - uint16_t incoming = 0; - - WDT_HIT(); // wait until SPI is ready for transfer - while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0) {}; + //if you are checking for incoming data returned then the TXEMPTY flag is redundant + //while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0) {}; // send the data AT91C_BASE_SPI->SPI_TDR = data; + while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TDRE) == 0){}; + // wait recive transfer is complete - while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RDRF) == 0) - WDT_HIT(); + while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RDRF) == 0); // reading incoming data - incoming = ((AT91C_BASE_SPI->SPI_RDR) & 0xFFFF); - - return incoming; + return ((AT91C_BASE_SPI->SPI_RDR) & 0xFFFF); } // send last byte over SPI @@ -132,41 +178,35 @@ uint16_t FlashSendLastByte(uint32_t data) { // read state register 1 uint8_t Flash_ReadStat1(void) { FlashSendByte(READSTAT1); - uint8_t stat1 = FlashSendLastByte(0xFF); -// if ( MF_DBGLEVEL > 3 ) Dbprintf("stat1 [%02x]", stat1); - return stat1; + return FlashSendLastByte(0xFF); } -// read state register 2 -uint8_t Flash_ReadStat2(void) { - FlashSendByte(READSTAT2); - uint8_t stat2 = FlashSendLastByte(0xFF); -// if ( MF_DBGLEVEL > 3 ) Dbprintf("stat2 [%02x]", stat2); - return stat2; -} +bool Flash_CheckBusy(uint32_t timeout) +{ + WaitUS(WINBOND_WRITE_DELAY); + StartCountUS(); + uint32_t _time = GetCountUS(); -// determine whether FLASHMEM is busy -bool Flash_CheckBusy(uint16_t times) { - bool ret = (Flash_ReadStat1() & BUSY); + do + { + if (!(Flash_ReadStat1() & BUSY)) + { + return false; + } + } while ((GetCountUS() - _time) < timeout); - if (!ret || !times || !(times--)) - return ret; - - while (times) { - WDT_HIT(); - SpinDelay(1); - ret = (Flash_ReadStat1() & BUSY); - if (!ret) - break; - times--; + if (timeout <= (GetCountUS() - _time)) + { + return true; } - return ret; + + return false; } // read ID out uint8_t Flash_ReadID(void) { - if (Flash_CheckBusy(100)) return 0; + if (Flash_CheckBusy(BUSY_TIMEOUT)) return 0; // Manufacture ID / device ID FlashSendByte(ID); @@ -188,7 +228,7 @@ uint8_t Flash_ReadID(void) { // read unique id for chip. void Flash_UniqueID(uint8_t *uid) { - if (Flash_CheckBusy(100)) return; + if (Flash_CheckBusy(BUSY_TIMEOUT)) return; // reading unique serial number FlashSendByte(UNIQUE_ID); @@ -209,12 +249,10 @@ void Flash_UniqueID(uint8_t *uid) { uint16_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len) { - if (!FlashInit()) return 0; - - Flash_ReadStat1(); - + if (!FlashInit(0)) return 0; + // length should never be zero - if (!len || Flash_CheckBusy(100)) return 0; + if (!len || Flash_CheckBusy(BUSY_TIMEOUT)) return 0; FlashSendByte(READDATA); FlashSendByte((address >> 16) & 0xFF); @@ -231,6 +269,55 @@ uint16_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len) { return len; } +/* This ensure we can ReadData without having to cycle through initialization everytime */ +uint16_t Flash_ReadDataCont(uint32_t address, uint8_t *out, uint16_t len) { + + // length should never be zero + if (!len) return 0; + + FlashSendByte(READDATA); + FlashSendByte((address >> 16) & 0xFF); + FlashSendByte((address >> 8) & 0xFF); + FlashSendByte((address >> 0) & 0xFF); + + uint16_t i = 0; + for (; i < (len - 1); i++) + out[i] = FlashSendByte(0xFF); + + out[i] = FlashSendLastByte(0xFF); + + return len; +} + +uint16_t Flash_FastReadDataCont(uint32_t address, uint8_t *out, uint16_t len) { + + // length should never be zero + if (!len) return 0; + + //if (Flash_CheckBusy(BUSY_TIMEOUT)) + //{return 0;} + + FlashSendByte(FASTREAD); + FlashSendByte((address >> 16) & 0xFF); + FlashSendByte((address >> 8) & 0xFF); + FlashSendByte((address >> 0) & 0xFF); + FlashSendByte(0xFF); + //Flash_CheckBusy(BUSY_TIMEOUT); + + + uint16_t i = 0; + for (; i < (len - 1); i++) + out[i] = FlashSendByte(0xFF); + + out[i] = FlashSendLastByte(0xFF); + + return len; +} + + + +//////////////////////////////////////// + // Write data can only program one page. A page has 256 bytes. // if len > 256, it might wrap around and overwrite pos 0. uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len) { @@ -251,12 +338,13 @@ uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len) { return 0; } - if (!FlashInit()) { + if (!FlashInit(0)) { if ( MF_DBGLEVEL > 3 ) Dbprintf("Flash_WriteData init fail"); return 0; } - Flash_ReadStat1(); + Flash_CheckBusy(BUSY_TIMEOUT); + //Flash_ReadStat1(); Flash_WriteEnable(); @@ -275,22 +363,61 @@ uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len) { return len; } +uint16_t Flash_WriteDataCont(uint32_t address, uint8_t *in, uint16_t len) { + + // length should never be zero + if (!len) + return 0; + + // Max 256 bytes write + if (((address & 0xFF) + len) > 256) { + Dbprintf("Flash_WriteData 256 fail [ 0x%02x ] [ %u ]", (address & 0xFF)+len, len ); + return 0; + } + + // out-of-range + if ( (( address >> 16 ) & 0xFF ) > MAX_BLOCKS) { + Dbprintf("Flash_WriteData, block out-of-range"); + return 0; + } + + + //Flash_CheckBusy(100); + //SpinDelay(1); + Flash_CheckBusy(BUSY_TIMEOUT); + //Flash_ReadStat1(); + Flash_WriteEnable(); + + FlashSendByte(PAGEPROG); + FlashSendByte((address >> 16) & 0xFF); + FlashSendByte((address >> 8) & 0xFF); + FlashSendByte((address >> 0) & 0xFF); + + uint16_t i = 0; + for (; i < (len - 1); i++) + FlashSendByte(in[i]); + + FlashSendLastByte(in[i]); + + return len; +} + bool Flash_WipeMemoryPage(uint8_t page) { - if (!FlashInit()) { + if (!FlashInit(0)) { if ( MF_DBGLEVEL > 3 ) Dbprintf("Flash_WriteData init fail"); return false; } Flash_ReadStat1(); // Each block is 64Kb. One block erase takes 1s ( 1000ms ) - Flash_WriteEnable(); Flash_Erase64k(page); Flash_CheckBusy(1000); + Flash_WriteEnable(); Flash_Erase64k(page); Flash_CheckBusy(BUSY_TIMEOUT); FlashStop(); return true; } // Wipes flash memory completely, fills with 0xFF bool Flash_WipeMemory() { - if (!FlashInit()) { + if (!FlashInit(0)) { if ( MF_DBGLEVEL > 3 ) Dbprintf("Flash_WriteData init fail"); return false; } @@ -298,10 +425,10 @@ bool Flash_WipeMemory() { // Each block is 64Kb. Four blocks // one block erase takes 1s ( 1000ms ) - Flash_WriteEnable(); Flash_Erase64k(0); Flash_CheckBusy(1000); - Flash_WriteEnable(); Flash_Erase64k(1); Flash_CheckBusy(1000); - Flash_WriteEnable(); Flash_Erase64k(2); Flash_CheckBusy(1000); - Flash_WriteEnable(); Flash_Erase64k(3); Flash_CheckBusy(1000); + Flash_WriteEnable(); Flash_Erase64k(0); Flash_CheckBusy(BUSY_TIMEOUT); + Flash_WriteEnable(); Flash_Erase64k(1); Flash_CheckBusy(BUSY_TIMEOUT); + Flash_WriteEnable(); Flash_Erase64k(2); Flash_CheckBusy(BUSY_TIMEOUT); + Flash_WriteEnable(); Flash_Erase64k(3); Flash_CheckBusy(BUSY_TIMEOUT); FlashStop(); return true; @@ -366,25 +493,13 @@ void Flash_EraseChip(void) { FlashSendLastByte(CHIPERASE); } -// initialize -bool FlashInit(void) { - FlashSetup(); - StartTicks(); - - if (Flash_CheckBusy(100)) { - StopTicks(); - return false; - } - if ( MF_DBGLEVEL > 3 ) Dbprintf("FlashInit OK"); - return true; -} void Flashmem_print_status(void) { DbpString("Flash memory"); - if (!FlashInit()) { + if (!FlashInit(0)) { DbpString(" init....................FAIL"); return; } @@ -414,4 +529,4 @@ void Flashmem_print_status(void) { ); FlashStop(); -} \ No newline at end of file +} diff --git a/armsrc/flashmem.h b/armsrc/flashmem.h index 198e3392d..3563eb41d 100644 --- a/armsrc/flashmem.h +++ b/armsrc/flashmem.h @@ -45,6 +45,7 @@ #define WRITEENABLE 0x06 #define READDATA 0x03 +#define FASTREAD 0x0B #define PAGEPROG 0x02 #define SECTORERASE 0x20 @@ -57,27 +58,17 @@ // Not used or not support command #define RELEASE 0xAB #define POWERDOWN 0xB9 -#define FASTREAD 0x0B #define SUSPEND 0x75 #define RESUME 0x7A +#define BUSY_TIMEOUT 1000000000L -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// -// Chip specific instructions // -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// - -//~~~~~~~~~~~~~~~~~~~~~~~~~ Winbond ~~~~~~~~~~~~~~~~~~~~~~~~~// #define WINBOND_MANID 0xEF #define WINBOND_DEVID 0x11 #define PAGESIZE 0x100 +#define WINBOND_WRITE_DELAY 0x02 -//~~~~~~~~~~~~~~~~~~~~~~~~ Microchip ~~~~~~~~~~~~~~~~~~~~~~~~// -#define MICROCHIP_MANID 0xBF -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// -// Definitions // -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// - -#define SPI_CLK 75000000 //Hex equivalent of 75MHz +#define SPI_CLK 48000000 #define BUSY 0x01 #define WRTEN 0x02 @@ -113,14 +104,17 @@ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// extern void Dbprintf(const char *fmt, ...); - -void FlashSetup(void); +bool FlashInit(bool fast); +void FlashSetup(bool fast); void FlashStop(void); bool Flash_WaitIdle(void); uint8_t Flash_ReadStat1(void); uint8_t Flash_ReadStat2(void); uint16_t FlashSendByte(uint32_t data); +bool Flash_CheckBusy(uint32_t timeout); + + void Flash_WriteEnable(); bool Flash_WipeMemoryPage(uint8_t page); bool Flash_WipeMemory(); @@ -128,12 +122,16 @@ bool Flash_Erase4k(uint8_t block, uint8_t sector); //bool Flash_Erase32k(uint32_t address); bool Flash_Erase64k(uint8_t block); -bool FlashInit(); void Flash_UniqueID(uint8_t *uid); uint8_t Flash_ReadID(void); uint16_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len); + +uint16_t Flash_ReadDataCont(uint32_t address, uint8_t *out, uint16_t len); +uint16_t Flash_FastReadDataCont(uint32_t address, uint8_t *out, uint16_t len); + uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len); +uint16_t Flash_WriteDataCont(uint32_t address, uint8_t *in, uint16_t len); void Flashmem_print_status(void); #endif \ No newline at end of file diff --git a/client/cmdflashmem.c b/client/cmdflashmem.c index 2b86bdcfc..5f83f9263 100644 --- a/client/cmdflashmem.c +++ b/client/cmdflashmem.c @@ -15,9 +15,10 @@ static int CmdHelp(const char *Cmd); int usage_flashmem_read(void){ PrintAndLogEx(NORMAL, "Read flash memory on device"); - PrintAndLogEx(NORMAL, "Usage: mem read o l "); + PrintAndLogEx(NORMAL, "Usage: mem read o l [f]"); PrintAndLogEx(NORMAL, " o : offset in memory"); PrintAndLogEx(NORMAL, " l : length"); + PrintAndLogEx(NORMAL, " f : fastRead mode"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " mem read o 0 l 32"); // read 32 bytes starting at offset 0 @@ -41,6 +42,7 @@ int usage_flashmem_save(void){ PrintAndLogEx(NORMAL, " o : offset in memory"); PrintAndLogEx(NORMAL, " l : length"); PrintAndLogEx(NORMAL, " f : file name"); + PrintAndLogEx(NORMAL, " + : fast read mode"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " mem save f myfile"); // download whole flashmem to file myfile @@ -79,9 +81,14 @@ int CmdFlashMemRead(const char *Cmd) { uint8_t cmdp = 0; bool errors = false; uint32_t start_index = 0, len = 0; + uint8_t fast = 0; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { + case 'f': + fast = 1; + cmdp += 1; + break; case 'o': start_index = param_get32ex(Cmd, cmdp+1, 0, 10); cmdp += 2; @@ -107,7 +114,7 @@ int CmdFlashMemRead(const char *Cmd) { return 1; } - UsbCommand c = {CMD_READ_FLASH_MEM, {start_index, len, 0}}; + UsbCommand c = {CMD_READ_FLASH_MEM, {start_index, len, fast}}; clearCommandBuffer(); SendCommand(&c); return 0; @@ -221,6 +228,7 @@ int CmdFlashMemSave(const char *Cmd){ uint8_t cmdp = 0; bool errors = false; uint32_t start_index = 0, len = FLASH_MEM_MAX_SIZE; + uint8_t fast = 0; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { @@ -233,6 +241,10 @@ int CmdFlashMemSave(const char *Cmd){ start_index = param_get32ex(Cmd, cmdp+1, 0, 10); cmdp += 2; break; + case '+': + fast = 1; + cmdp += 1; + break; case 'f': //File handling if ( param_getstr(Cmd, cmdp+1, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE ) { diff --git a/client/cmdmain.c b/client/cmdmain.c index ea118a2f0..ac391f1b8 100644 --- a/client/cmdmain.c +++ b/client/cmdmain.c @@ -199,7 +199,31 @@ void UsbCommandReceived(UsbCommand* _ch) { memset(s, 0x00, sizeof(s)); size_t len = MIN(c->arg[0], USB_CMD_DATA_SIZE); memcpy(s, c->d.asBytes, len); - + + //#define FLAG_RAWPRINT 0x0111 + //#define FLAG_NOOPT 0x0000 + //#define FLAG_NOLOG 0x0001 + //#define FLAG_NONEWLINE 0x0010 + //#define FLAG_NOPROMPT 0x0100 + uint64_t flag = c->arg[1]; + if (flag > 0) { // FLAG_RAWPRINT) { + switch (flag) { + case FLAG_RAWPRINT: { + printf("%s", s); + } return; break; + case FLAG_NONEWLINE: { + printf("%s\r", s); + } return; break; + case FLAG_NOLOG: { + printf("%s\r\n", s); + } return; break; + // printf("%s", s); + fflush(stdout); + return; + } + } + + // print debug line on same row. escape seq \r if ( c->arg[1] == CMD_MEASURE_ANTENNA_TUNING_HF) { PrintAndLogEx(NORMAL, "\r#db# %s", s);