diff --git a/README.md b/README.md index 62c3add53..350763c34 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,8 @@ This repo compiles nicely on - WSL, WSL2 (Windows subsystem linux) on Windows 10 - Docker container +The [public roadmap](https://github.com/RfidResearchGroup/proxmark3/wiki/Public-Roadmap) is an excellent start to read if you are interesting in contributing. + > 👉 **Remember!** If you intend to contribute to the code, please read the [coding style notes](HACKING.md) first. We usually merge your contributions fast since we do like the idea of getting a functionality in the Proxmark3 and weed out the bugs afterwards. @@ -93,7 +95,8 @@ The new universal GUI will work. [Proxmark3 Universal GUI](https://github.com/bu Please see the [Proxmark Forum](http://www.proxmark.org/forum/index.php) and see if your issue is listed in the first instance Google is your friend :) Questions will be answered via the forum by Iceman and the team. -It's needed to have a good USB cable to connect Proxmark3 to USB. If you have stability problems (Proxmark3 resets, firmware hangs, especially firmware hangs just after start, etc.) - check your cable with a USB tester (or try to change it). It needs to have a resistance smaller or equal to 0.3 Ohm. +Read the [Troubleshooting](/doc/md/Installation_Instructions/Troubleshooting.md) guide to weed out most known problems. + ## The end diff --git a/armsrc/Makefile b/armsrc/Makefile index f94868b6e..beb19c243 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -109,6 +109,7 @@ THUMBSRC = start.c \ string.c \ BigBuf.c \ ticks.c \ + clocks.c \ hfsnoop.c diff --git a/armsrc/appmain.c b/armsrc/appmain.c index b524c4883..e70b03cf8 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -11,6 +11,7 @@ //----------------------------------------------------------------------------- #include "appmain.h" +#include "clocks.h" #include "usb_cdc.h" #include "proxmark3_arm.h" #include "dbprint.h" @@ -303,6 +304,14 @@ void SendVersion(void) { reply_ng(CMD_VERSION, PM3_SUCCESS, (uint8_t *)&payload, 12 + payload.versionstr_len); } +void TimingIntervalAcquisition(void) { + // trigger new acquisition by turning main oscillator off and on + mck_from_pll_to_slck(); + mck_from_slck_to_pll(); + // wait for MCFR and recompute RTMR scaler + StartTickCount(); +} + // measure the Connection Speed by sending SpeedTestBufferSize bytes to client and measuring the elapsed time. // Note: this mimics GetFromBigbuf(), i.e. we have the overhead of the PacketCommandNG structure included. void printConnSpeed(void) { @@ -354,6 +363,17 @@ void SendStatus(void) { while ((AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINRDY) == 0); // Wait for MAINF value to become available... uint16_t mainf = AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINF; // Get # main clocks within 16 slow clocks Dbprintf(" Slow clock..............%d Hz", (16 * MAINCK) / mainf); + uint32_t delta_time = 0; + uint32_t start_time = GetTickCount(); + #define SLCK_CHECK_MS 50 + SpinDelay(SLCK_CHECK_MS); + delta_time = GetTickCountDelta(start_time); + if ((delta_time < SLCK_CHECK_MS - 1) || (delta_time > SLCK_CHECK_MS + 1)) { + // error > 2% with SLCK_CHECK_MS=50 + Dbprintf(_RED_(" Slow Clock speed change detected, TIA needed")); + Dbprintf(_YELLOW_(" Slow Clock actual speed seems closer to %d kHz"), + (16 * MAINCK / 1000) / mainf * delta_time / SLCK_CHECK_MS); + } DbpString(_BLUE_("Installed StandAlone Mode")); ModInfo(); @@ -1878,6 +1898,16 @@ static void PacketReceived(PacketCommandNG *packet) { SendStatus(); break; } + case CMD_TIA: { + uint16_t mainf = AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINF; + Dbprintf(" Slow clock old measured value:.........%d Hz", (16 * MAINCK) / mainf); + TimingIntervalAcquisition(); + mainf = AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINF; + Dbprintf(""); // first message gets lost + Dbprintf(" Slow clock new measured value:.........%d Hz", (16 * MAINCK) / mainf); + reply_ng(CMD_TIA, PM3_SUCCESS, NULL, 0); + break; + } case CMD_STANDALONE: { RunMod(); break; diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index db347cf13..38eb2ecb6 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -2044,7 +2044,7 @@ bool GetIso14443aAnswerFromTag_Thinfilm(uint8_t *receivedResponse, uint8_t *rec } } - if (GetTickCount() - receive_timer > 100) + if (GetTickCountDelta(receive_timer) > 100) break; } *received_len = Demod.len; @@ -2094,7 +2094,7 @@ static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receive } // timeout already in ms + 100ms guard time - if (GetTickCount() - receive_timer > timeout + 100) + if (GetTickCountDelta(receive_timer) > timeout + 100) break; } return false; diff --git a/armsrc/mifaresim.c b/armsrc/mifaresim.c index 0f912c083..cdd8b556d 100644 --- a/armsrc/mifaresim.c +++ b/armsrc/mifaresim.c @@ -1106,7 +1106,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 Dbprintf("[MFEMUL_AUTH1] AUTH COMPLETED for sector %d with key %c. time=%d", cardAUTHSC, cardAUTHKEY == 0 ? 'A' : 'B', - GetTickCount() - authTimer + GetTickCountDelta(authTimer) ); } LED_C_ON(); diff --git a/bootrom/Makefile b/bootrom/Makefile index d666f3acd..5c7823896 100644 --- a/bootrom/Makefile +++ b/bootrom/Makefile @@ -9,6 +9,7 @@ # DO NOT use thumb mode in the phase 1 bootloader since that generates a section with glue code ARMSRC = THUMBSRC = usb_cdc.c \ + clocks.c \ bootrom.c ASMSRC = ram-reset.s flash-reset.s diff --git a/bootrom/bootrom.c b/bootrom/bootrom.c index 4b255536f..aa633f448 100644 --- a/bootrom/bootrom.c +++ b/bootrom/bootrom.c @@ -6,6 +6,7 @@ // Main code for the bootloader //----------------------------------------------------------------------------- +#include "clocks.h" #include "usb_cdc.h" #include "proxmark3_arm.h" @@ -68,45 +69,7 @@ static void ConfigClocks(void) { (1 << AT91C_ID_PWMC) | (1 << AT91C_ID_UDP); - // worst case scenario, with MAINCK = 16MHz xtal, startup delay is 1.4ms - // if SLCK slow clock runs at its worst case (max) frequency of 42kHz - // max startup delay = (1.4ms*42k)/8 = 7.356 so round up to 8 - - // enable main oscillator and set startup delay - AT91C_BASE_PMC->PMC_MOR = - AT91C_CKGR_MOSCEN | - PMC_MAIN_OSC_STARTUP_DELAY(8); - - // wait for main oscillator to stabilize - while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MOSCS)) {}; - - // PLL output clock frequency in range 80 - 160 MHz needs CKGR_PLL = 00 - // PLL output clock frequency in range 150 - 180 MHz needs CKGR_PLL = 10 - // PLL output is MAINCK * multiplier / divisor = 16MHz * 12 / 2 = 96MHz - AT91C_BASE_PMC->PMC_PLLR = - PMC_PLL_DIVISOR(2) | - //PMC_PLL_COUNT_BEFORE_LOCK(0x10) | - PMC_PLL_COUNT_BEFORE_LOCK(0x3F) | - PMC_PLL_FREQUENCY_RANGE(0) | - PMC_PLL_MULTIPLIER(12) | - PMC_PLL_USB_DIVISOR(1); - - // wait for PLL to lock - while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCK)) {}; - - // we want a master clock (MCK) to be PLL clock / 2 = 96MHz / 2 = 48MHz - // datasheet recommends that this register is programmed in two operations - // when changing to PLL, program the prescaler first then the source - AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2; - - // wait for main clock ready signal - while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY)) {}; - - // set the source to PLL - AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2 | AT91C_PMC_CSS_PLL_CLK; - - // wait for main clock ready signal - while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY)) {}; + mck_from_slck_to_pll(); } static void Fatal(void) { diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 67aa84396..bb20e5b3a 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -150,7 +150,7 @@ static int usage_hf_iclass_writeblock(void) { return PM3_SUCCESS; } static int usage_hf_iclass_readblock(void) { - PrintAndLogEx(NORMAL, "Usage: hf iclass readblk b k [c|e|r|v]\n"); + PrintAndLogEx(NORMAL, "Usage: hf iclass rdbl b k [c|e|r|v]\n"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " b : The block number as 2 hex symbols"); PrintAndLogEx(NORMAL, " k : Access Key as 16 hex symbols or 1 hex to select key from memory"); @@ -159,9 +159,9 @@ static int usage_hf_iclass_readblock(void) { PrintAndLogEx(NORMAL, " r : raw, no computations applied to key"); PrintAndLogEx(NORMAL, " v : verbose output"); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf iclass readblk b 06 k 0011223344556677"); - PrintAndLogEx(NORMAL, " hf iclass readblk b 1B k 0011223344556677 c"); - PrintAndLogEx(NORMAL, " hf iclass readblk b 0A k 0"); + PrintAndLogEx(NORMAL, " hf iclass rdbl b 06 k 0011223344556677"); + PrintAndLogEx(NORMAL, " hf iclass rdbl b 1B k 0011223344556677 c"); + PrintAndLogEx(NORMAL, " hf iclass rdbl b 0A k 0"); return PM3_SUCCESS; } static int usage_hf_iclass_readtagfile() { diff --git a/client/cmdhw.c b/client/cmdhw.c index 5dddac5fc..ec53ad2cf 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -511,6 +511,18 @@ static int CmdStatus(const char *Cmd) { return PM3_SUCCESS; } +static int CmdTia(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + clearCommandBuffer(); + PrintAndLogEx(INFO, "Triggering new Timing Interval Acquisition..."); + PacketResponseNG resp; + SendCommandNG(CMD_TIA, NULL, 0); + if (WaitForResponseTimeout(CMD_TIA, &resp, 2000) == false) + PrintAndLogEx(WARNING, "Tia command failed. You probably need to unplug the Proxmark3."); + PrintAndLogEx(INFO, "TIA done."); + return PM3_SUCCESS; +} + static int CmdPing(const char *Cmd) { uint32_t len = strtol(Cmd, NULL, 0); if (len > PM3_CMD_DATA_SIZE) @@ -604,6 +616,7 @@ static command_t CommandTable[] = { {"setmux", CmdSetMux, IfPm3Present, "Set the ADC mux to a specific value"}, {"standalone", CmdStandalone, IfPm3Present, "Jump to the standalone mode"}, {"status", CmdStatus, IfPm3Present, "Show runtime status information about the connected Proxmark3"}, + {"tia", CmdTia, IfPm3Present, "Trigger a Timing Interval Acquisition to re-adjust the RealTimeCounter divider"}, {"tune", CmdTune, IfPm3Present, "Measure antenna tuning"}, {"version", CmdVersion, IfPm3Present, "Show version information about the connected Proxmark3"}, {NULL, NULL, NULL, NULL} diff --git a/common/lfdemod.c b/common/lfdemod.c index 30990ec73..2a9983130 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -201,7 +201,7 @@ void getHiLo(int *high, int *low, uint8_t fuzzHi, uint8_t fuzzLo) { } // if fuzzing to great and overlap - if (*high < *low) { + if (*high <= *low) { *high = signalprop.high; *low = signalprop.low; } @@ -1723,7 +1723,6 @@ int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int *startId size_t i; int high, low; - getHiLo(&high, &low, 75, 75); getHiLo(&high, &low, 75, 75); uint8_t bit = 0; diff --git a/common_arm/clocks.c b/common_arm/clocks.c new file mode 100644 index 000000000..c6fa874d3 --- /dev/null +++ b/common_arm/clocks.c @@ -0,0 +1,61 @@ +#include "clocks.h" +#include "proxmark3_arm.h" + +void mck_from_pll_to_slck(void) { + // switch main clk to slow clk, first CSS then PRES + AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2 | AT91C_PMC_CSS_SLOW_CLK; + while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY)) {}; + AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK | AT91C_PMC_CSS_SLOW_CLK; + while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY)) {}; + + // disable the PLL + AT91C_BASE_PMC->PMC_PLLR = 0x0; + + // disable main oscillator + AT91C_BASE_PMC->PMC_MOR = 0; +} + +void mck_from_slck_to_pll(void) { + // worst case scenario, with MAINCK = 16MHz xtal, startup delay is 1.4ms + // if SLCK slow clock runs at its worst case (max) frequency of 42kHz + // max startup delay = (1.4ms*42k)/8 = 7.356 so round up to 8 + // UPDATE: + // we observed on 10% of the devices very wrong initial slow clock RC TIA measures. + // Bumping delay to 16 helps fixing the issue even on the most screwed RC. + + // enable main oscillator and set startup delay + AT91C_BASE_PMC->PMC_MOR = + AT91C_CKGR_MOSCEN | + PMC_MAIN_OSC_STARTUP_DELAY(16); + + // wait for main oscillator to stabilize + while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MOSCS)) {}; + + // PLL output clock frequency in range 80 - 160 MHz needs CKGR_PLL = 00 + // PLL output clock frequency in range 150 - 180 MHz needs CKGR_PLL = 10 + // PLL output is MAINCK * multiplier / divisor = 16MHz * 12 / 2 = 96MHz + AT91C_BASE_PMC->PMC_PLLR = + PMC_PLL_DIVISOR(2) | + //PMC_PLL_COUNT_BEFORE_LOCK(0x10) | + PMC_PLL_COUNT_BEFORE_LOCK(0x3F) | + PMC_PLL_FREQUENCY_RANGE(0) | + PMC_PLL_MULTIPLIER(12) | + PMC_PLL_USB_DIVISOR(1); + + // wait for PLL to lock + while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCK)) {}; + + // we want a master clock (MCK) to be PLL clock / 2 = 96MHz / 2 = 48MHz + // datasheet recommends that this register is programmed in two operations + // when changing to PLL, program the prescaler first then the source + AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2 | AT91C_PMC_CSS_SLOW_CLK; + + // wait for main clock ready signal + while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY)) {}; + + // set the source to PLL + AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2 | AT91C_PMC_CSS_PLL_CLK; + + // wait for main clock ready signal + while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY)) {}; +} diff --git a/common_arm/clocks.h b/common_arm/clocks.h new file mode 100644 index 000000000..1752ba4fd --- /dev/null +++ b/common_arm/clocks.h @@ -0,0 +1,10 @@ +#ifndef _CLOCKS_H_ +#define _CLOCKS_H_ + +#include "common.h" +#include "at91sam7s512.h" + +void mck_from_pll_to_slck(void); +void mck_from_slck_to_pll(void); + +#endif // _CLOCKS_H_ diff --git a/doc/md/Installation_Instructions/Troubleshooting.md b/doc/md/Installation_Instructions/Troubleshooting.md index e0cf7f7aa..ab893d177 100644 --- a/doc/md/Installation_Instructions/Troubleshooting.md +++ b/doc/md/Installation_Instructions/Troubleshooting.md @@ -16,7 +16,8 @@ Always use the latest repository commits from *master* branch. There are always * [Troubles with SIM card reader](#troubles-with-sim-card-reader) * [Troubles with t5577 commands or MFC/iClass/T55x7 dictionaries](#troubles-with-t5577-commands-or-mfciclasst55x7-dictionaries) * [File not found](#file-not-found) - * [pixmap / pixbuf warnings](#pixmap--pixbuf-warnings) + * [Pixmap / pixbuf warnings](#pixmap--pixbuf-warnings) + * [Usb cable](#usb-cable) ## `pm3` or `pm3-flash*` doesn't see my Proxmark @@ -154,6 +155,12 @@ pm3 --> sc upgrade f ../tools/simmodule/sim011.bin etc. -## pixmap / pixbuf warnings +## Pixmap / pixbuf warnings If you get warnings related to pixmap or pixbuf such as *Pixbuf theme: Cannot load pixmap file* or *Invalid borders specified for theme pixmap*, it's a problem of your Theme, try another one and the problem should vanish. See e.g. [#354](https://github.com/RfidResearchGroup/proxmark3/issues/354) (Yaru theme on Ubuntu) and [#386](https://github.com/RfidResearchGroup/proxmark3/issues/386) (Kali-X theme on Kali). + +## Usb cable + +It's needed to have a good USB cable to connect Proxmark3 to USB. If you have stability problems (Proxmark3 resets, firmware hangs, especially firmware hangs just after start, etc.) + +- check your cable with a USB tester (or try to change it). It needs to have a resistance smaller or equal to 0.3 Ohm. diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index c92a1faee..19ef27afb 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -287,6 +287,7 @@ typedef struct { #define CMD_SET_DBGMODE 0x0114 #define CMD_STANDALONE 0x0115 #define CMD_WTX 0x0116 +#define CMD_TIA 0x0117 // RDV40, Flash memory operations #define CMD_FLASHMEM_WRITE 0x0121 diff --git a/tools/jtag_openocd/openocd_flash_dump.sh b/tools/jtag_openocd/openocd_flash_dump.sh index 497847dd1..650c218f1 100755 --- a/tools/jtag_openocd/openocd_flash_dump.sh +++ b/tools/jtag_openocd/openocd_flash_dump.sh @@ -1,5 +1,6 @@ #!/bin/bash +cd $(dirname "$0") . openocd_configuration || exit 1 if [ -e "$DUMP" ]; then diff --git a/tools/jtag_openocd/openocd_flash_recovery.sh b/tools/jtag_openocd/openocd_flash_recovery.sh index 2e88c52e6..80caa08f0 100755 --- a/tools/jtag_openocd/openocd_flash_recovery.sh +++ b/tools/jtag_openocd/openocd_flash_recovery.sh @@ -1,5 +1,6 @@ #!/bin/bash +cd $(dirname "$0") . openocd_configuration || exit 1 if [ ! -e "$IMAGE" ]; then diff --git a/tools/jtag_openocd/openocd_interactive.sh b/tools/jtag_openocd/openocd_interactive.sh index ea7919da8..ac022f3f2 100755 --- a/tools/jtag_openocd/openocd_interactive.sh +++ b/tools/jtag_openocd/openocd_interactive.sh @@ -1,5 +1,6 @@ #!/bin/bash +cd $(dirname "$0") . openocd_configuration || exit 1 echo "*********************************************"