From 0869cbc6ad4a6c493b8fe934c581f1abb88fcd0a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 9 Jan 2020 19:28:44 +0100 Subject: [PATCH] Fix: 'lf config' - calling without param messes up all device settings. --- armsrc/lfadc.c | 6 +- armsrc/lfsampling.c | 41 +++++++++----- armsrc/lfsampling.h | 8 +-- client/cmdlf.c | 134 +++++++++++++++++++++++++------------------- include/pm3_cmd.h | 12 ++-- 5 files changed, 116 insertions(+), 85 deletions(-) diff --git a/armsrc/lfadc.c b/armsrc/lfadc.c index a42fe8c52..d59fae07d 100644 --- a/armsrc/lfadc.c +++ b/armsrc/lfadc.c @@ -150,12 +150,12 @@ void lf_init(bool reader) { AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; LOW(GPIO_SSC_DOUT); - // Enable peripheral Clock for TIMER_CLOCK0 + // Enable peripheral Clock for TIMER_CLOCK 0 AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC0); AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV4_CLOCK; - // Enable peripheral Clock for TIMER_CLOCK0 + // Enable peripheral Clock for TIMER_CLOCK 1 AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1); AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV4_CLOCK; @@ -168,7 +168,7 @@ void lf_init(bool reader) { AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; // Prepare data trace - if (logging) initSamplingBuffer(NULL); + if (logging) initSampleBuffer(NULL); } diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index d836accfa..32865d204 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -42,25 +42,40 @@ void printConfig() { /** * Called from the USB-handler to set the sampling configuration - * The sampling config is used for std reading and sniffing. + * The sampling config is used for standard reading and sniffing. * * Other functions may read samples and ignore the sampling config, * such as functions to read the UID from a prox tag or similar. * - * Values set to '0' implies no change (except for averaging) + * Values set to '-1' implies no change * @brief setSamplingConfig * @param sc */ void setSamplingConfig(sample_config *sc) { - if (sc->divisor != 0) config.divisor = sc->divisor; - if (sc->bits_per_sample != 0) config.bits_per_sample = sc->bits_per_sample; - if (sc->trigger_threshold != -1) config.trigger_threshold = sc->trigger_threshold; -// if (sc->samples_to_skip == 0xffffffff) // if needed to not update if not supplied - config.samples_to_skip = sc->samples_to_skip; - config.decimation = (sc->decimation != 0) ? sc->decimation : 1; - config.averaging = sc->averaging; - if (config.bits_per_sample > 8) config.bits_per_sample = 8; + // decimation (1-8) how many bits of adc sample value to save + if (sc->decimation > 0 && sc->decimation < 8) + config.decimation = sc->decimation; + + // bits per sample (1-8) + if (sc->bits_per_sample > 0 && sc->bits_per_sample < 8) + config.bits_per_sample = sc->bits_per_sample; + + // + if (sc->averaging > -1) + config.averaging = (sc->averaging > 0) ? 1 : 0; + + // Frequency divisor (19 - 255) + if (sc->divisor > 18 && sc->divisor < 256) + config.divisor = sc->divisor; + + // Start saving samples when adc value larger than trigger_threshold + if (sc->trigger_threshold > -1) + config.trigger_threshold = sc->trigger_threshold; + + // Skip n adc samples before saving + if (sc->samples_to_skip > -1) + config.samples_to_skip = sc->samples_to_skip; if (sc->verbose) printConfig(); @@ -113,7 +128,7 @@ uint32_t getSampleCounter() { return samples.total_saved; } -void logSample(uint8_t sample, uint8_t decimation, uint32_t bits_per_sample, bool avg) { +void logSample(uint8_t sample, uint8_t decimation, uint8_t bits_per_sample, bool avg) { if (!data.buffer) return; @@ -207,8 +222,8 @@ void LFSetupFPGAForADC(int divisor, bool lf_field) { * @param verbose - is true, dbprints the status, else no outputs * @return the number of bits occupied by the samples. */ -uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool avg, int trigger_threshold, - bool verbose, uint32_t sample_size, uint32_t cancel_after, uint32_t samples_to_skip) { +uint32_t DoAcquisition(uint8_t decimation, uint8_t bits_per_sample, bool avg, int16_t trigger_threshold, + bool verbose, uint32_t sample_size, uint32_t cancel_after, int32_t samples_to_skip) { initSampleBuffer(&sample_size); diff --git a/armsrc/lfsampling.h b/armsrc/lfsampling.h index 8ccaa5579..e97a3ac1a 100644 --- a/armsrc/lfsampling.h +++ b/armsrc/lfsampling.h @@ -42,8 +42,8 @@ uint32_t SampleLF(bool verbose, uint32_t sample_size); **/ uint32_t SniffLF(); -uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool avg, int trigger_threshold, - bool verbose, uint32_t sample_size, uint32_t cancel_after, uint32_t samples_to_skip); +uint32_t DoAcquisition(uint8_t decimation, uint8_t bits_per_sample, bool avg, int16_t trigger_threshold, + bool verbose, uint32_t sample_size, uint32_t cancel_after, int32_t samples_to_skip); // adds sample size to default options uint32_t DoPartialAcquisition(int trigger_threshold, bool verbose, uint32_t sample_size, uint32_t cancel_after); @@ -69,8 +69,8 @@ uint32_t DoAcquisition_config(bool verbose, uint32_t sample_size); /** * Refactoring of lf sampling buffer */ -void initSamplingBuffer(uint32_t *sample_size); -void logSample(uint8_t sample, uint8_t decimation, uint32_t bits_per_sample, bool avg); +void initSampleBuffer(uint32_t *sample_size); +void logSample(uint8_t sample, uint8_t decimation, uint8_t bits_per_sample, bool avg); uint32_t getSampleCounter(); /** diff --git a/client/cmdlf.c b/client/cmdlf.c index 64ff0ed9a..337444f1e 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -68,9 +68,10 @@ static int usage_lf_cmdread(void) { PrintAndLogEx(NORMAL, " c Command bytes (in ones and zeros)"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, " ************* " _YELLOW_("All periods in microseconds (us)")); - PrintAndLogEx(NORMAL, " ************* Use " _YELLOW_("'lf config'") "to configure options."); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf cmdread d 80 z 100 o 200 c 11000"); + PrintAndLogEx(NORMAL, "Extras:"); + PrintAndLogEx(NORMAL, " use " _YELLOW_("'lf config'")"to set parameters."); return PM3_SUCCESS; } static int usage_lf_read(void) { @@ -79,16 +80,16 @@ static int usage_lf_read(void) { PrintAndLogEx(NORMAL, " h This help"); PrintAndLogEx(NORMAL, " d #samples # samples to collect (optional)"); PrintAndLogEx(NORMAL, " s silent"); - PrintAndLogEx(NORMAL, "Use 'lf config' to set parameters."); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf read s d 12000 - collects 12000 samples silent"); PrintAndLogEx(NORMAL, " lf read"); + PrintAndLogEx(NORMAL, "Extras:"); + PrintAndLogEx(NORMAL, " use " _YELLOW_("'lf config'")"to set parameters."); return PM3_SUCCESS; } static int usage_lf_sim(void) { PrintAndLogEx(NORMAL, "Simulate low frequence tag from graphbuffer."); - PrintAndLogEx(NORMAL, "Use " _YELLOW_("'lf config'")" to set parameters."); PrintAndLogEx(NORMAL, "Usage: lf sim [h] "); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h This help"); @@ -96,16 +97,19 @@ static int usage_lf_sim(void) { PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf sim 240 - start simulating with 240ms gap"); PrintAndLogEx(NORMAL, " lf sim"); + PrintAndLogEx(NORMAL, "Extras:"); + PrintAndLogEx(NORMAL, " use " _YELLOW_("'lf config'")"to set parameters."); return PM3_SUCCESS; } static int usage_lf_sniff(void) { PrintAndLogEx(NORMAL, "Sniff low frequence signal."); - PrintAndLogEx(NORMAL, "Use " _YELLOW_("'lf config'")" to set parameters."); - PrintAndLogEx(NORMAL, "Use " _YELLOW_("'data samples'")" command to download from device, and " _YELLOW_("'data plot'")" to look at it"); - PrintAndLogEx(NORMAL, "Usage: lf sniff [h]"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h This help"); + PrintAndLogEx(NORMAL, "Extras:"); + PrintAndLogEx(NORMAL, " use " _YELLOW_("'lf config'")"to set parameters."); + PrintAndLogEx(NORMAL, " use " _YELLOW_("'data samples'")"command to download from device"); + PrintAndLogEx(NORMAL, " use " _YELLOW_("'data plot'")"to look at it"); return PM3_SUCCESS; } static int usage_lf_config(void) { @@ -117,22 +121,17 @@ static int usage_lf_config(void) { PrintAndLogEx(NORMAL, " q Manually set freq divisor. %d -> 134 kHz, %d -> 125 kHz", LF_DIVISOR_134, LF_DIVISOR_125); PrintAndLogEx(NORMAL, " f Manually set frequency in kHz"); PrintAndLogEx(NORMAL, " b Sets resolution of bits per sample. Default (max): 8"); - PrintAndLogEx(NORMAL, " d Sets decimation. A value of N saves only 1 in N samples. Default: 1"); + PrintAndLogEx(NORMAL, " d Sets decimation. A value of N saves only 1 in N samples. Default: 1"); PrintAndLogEx(NORMAL, " a [0|1] Averaging - if set, will average the stored sample value when decimating. Default: 1"); PrintAndLogEx(NORMAL, " t Sets trigger threshold. 0 means no threshold (range: 0-128)"); PrintAndLogEx(NORMAL, " s Sets a number of samples to skip before capture. Default: 0"); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " lf config"); - PrintAndLogEx(NORMAL, " Shows current config"); - PrintAndLogEx(NORMAL, " lf config b 8 L"); - PrintAndLogEx(NORMAL, " Samples at 125 kHz, 8bps."); - PrintAndLogEx(NORMAL, " lf config H b 4 d 3"); - PrintAndLogEx(NORMAL, " Samples at 134 kHz, averages three samples into one, stored with "); - PrintAndLogEx(NORMAL, " a resolution of 4 bits per sample."); - PrintAndLogEx(NORMAL, " lf read"); - PrintAndLogEx(NORMAL, " Performs a read (active field)"); - PrintAndLogEx(NORMAL, " lf sniff"); - PrintAndLogEx(NORMAL, " Performs a sniff (no active field)"); + PrintAndLogEx(NORMAL, " lf config - shows current config"); + PrintAndLogEx(NORMAL, " lf config b 8 L - samples at 125 kHz, 8bps."); + PrintAndLogEx(NORMAL, " lf config H b 4 d 3 - samples at 134 kHz, averages three samples into one, stored with "); + PrintAndLogEx(NORMAL, " a resolution of 4 bits per sample."); + PrintAndLogEx(NORMAL, " lf read - performs a read (active field)"); + PrintAndLogEx(NORMAL, " lf sniff - performs a sniff (no active field)"); return PM3_SUCCESS; } static int usage_lf_simfsk(void) { @@ -457,7 +456,11 @@ int lf_config(sample_config *config) { if (!session.pm3_present) return PM3_ENOTTY; clearCommandBuffer(); - SendCommandNG(CMD_LF_SAMPLING_SET_CONFIG, (uint8_t *)config, sizeof(sample_config)); + if (config != NULL) + SendCommandNG(CMD_LF_SAMPLING_SET_CONFIG, (uint8_t *)config, sizeof(sample_config)); + else + SendCommandNG(CMD_LF_SAMPLING_GET_CONFIG, NULL, 0); + return PM3_SUCCESS; } @@ -465,15 +468,22 @@ int CmdLFConfig(const char *Cmd) { if (!session.pm3_present) return PM3_ENOTTY; - uint8_t divisor = 0;//Frequency divisor - uint8_t bps = 0; // Bits per sample - uint8_t decimation = 0; //How many to keep - bool averaging = 1; // Defaults to true - bool errors = false; - int trigger_threshold = -1;//Means no change - uint8_t unsigned_trigg = 0; - uint32_t samples_to_skip = 0; // will return offset to 0 if not supplied. Could set to 0xffffffff if needed to not update + // if called with no params, just print the device config + if (strlen(Cmd) == 0) { + return lf_config(NULL); + } + sample_config config = { + .decimation = -1, + .bits_per_sample = -1, + .averaging = -1, + .divisor = -1, + .trigger_threshold = -1, + .samples_to_skip = -1, + .verbose = true + }; + + bool errors = false; uint8_t cmdp = 0; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { @@ -481,16 +491,16 @@ int CmdLFConfig(const char *Cmd) { case 'h': return usage_lf_config(); case 'H': - divisor = LF_DIVISOR_134; + config.divisor = LF_DIVISOR_134; cmdp++; break; case 'L': - divisor = LF_DIVISOR_125; + config.divisor = LF_DIVISOR_125; cmdp++; break; case 'q': - errors |= param_getdec(Cmd, cmdp + 1, &divisor); - if (divisor < 19) { + config.divisor = param_get8ex(Cmd, cmdp + 1, 95, 10); + if (config.divisor < 19) { PrintAndLogEx(ERR, "divisor must be between 19 and 255"); return PM3_EINVARG; } @@ -498,36 +508,50 @@ int CmdLFConfig(const char *Cmd) { break; case 'f': { int freq = param_get32ex(Cmd, cmdp + 1, 125, 10); - divisor = LF_FREQ2DIV(freq); - if (divisor < 19) { + config.divisor = LF_FREQ2DIV(freq); + if (config.divisor < 19) { PrintAndLogEx(ERR, "freq must be between 47 and 600"); return PM3_EINVARG; } cmdp += 2; break; } - case 't': - errors |= param_getdec(Cmd, cmdp + 1, &unsigned_trigg); + case 't': { + uint8_t trigg = 0; + errors |= param_getdec(Cmd, cmdp + 1, &trigg); cmdp += 2; if (!errors) { - trigger_threshold = unsigned_trigg; - g_lf_threshold_set = (trigger_threshold > 0); + config.trigger_threshold = trigg; + g_lf_threshold_set = (config.trigger_threshold > 0); } break; - case 'b': - errors |= param_getdec(Cmd, cmdp + 1, &bps); + } + case 'b': { + config.bits_per_sample = param_get8ex(Cmd, cmdp + 1, 8, 10); + + // bps is limited to 8 + if (config.bits_per_sample >> 4) + config.bits_per_sample = 8; + cmdp += 2; break; - case 'd': - errors |= param_getdec(Cmd, cmdp + 1, &decimation); + } + case 'd': { + config.decimation = param_get8ex(Cmd, cmdp + 1, 1, 10); + + // decimation is limited to 255 + if (config.decimation >> 4) + config.decimation = 8; + cmdp += 2; break; + } case 'a': - averaging = param_getchar(Cmd, cmdp + 1) == '1'; + config.averaging = (param_getchar(Cmd, cmdp + 1) == '1'); cmdp += 2; break; case 's': - samples_to_skip = param_get32ex(Cmd, cmdp + 1, 0, 10); + config.samples_to_skip = param_get32ex(Cmd, cmdp + 1, 0, 10); cmdp += 2; break; default: @@ -540,15 +564,6 @@ int CmdLFConfig(const char *Cmd) { // validations if (errors) return usage_lf_config(); - // print current settings. - if (cmdp == 0) - return lf_config(NULL); - - // bps is limited to 8 - if (bps >> 4) bps = 8; - - sample_config config = { decimation, bps, averaging, divisor, trigger_threshold, samples_to_skip, true }; - return lf_config(&config); } @@ -1334,13 +1349,14 @@ static command_t CommandTable[] = { {"visa2000", CmdLFVisa2k, AlwaysAvailable, "{ Visa2000 RFIDs... }"}, {"", CmdHelp, AlwaysAvailable, ""}, {"config", CmdLFConfig, IfPm3Lf, "Get/Set config for LF sampling, bit/sample, decimation, frequency"}, - {"cmdread", CmdLFCommandRead, IfPm3Lf, " <'0' period> <'1' period> ['h' 134] \n\t\t-- Modulate LF reader field to send command before read (all periods in microseconds)"}, - {"read", CmdLFRead, IfPm3Lf, "['s' silent] Read 125/134 kHz LF ID-only tag. Do 'lf read h' for help"}, - {"search", CmdLFfind, AlwaysAvailable, "[offline] ['u'] Read and Search for valid known tag (in offline mode it you can load first then search) \n\t\t-- 'u' to search for unknown tags"}, - {"sim", CmdLFSim, IfPm3Lf, "[GAP] -- Simulate LF tag from buffer with optional GAP (in microseconds)"}, - {"simask", CmdLFaskSim, IfPm3Lf, "[clock] [invert <1|0>] [biphase/manchester/raw <'b'|'m'|'r'>] [msg separator 's'] [d ] \n\t\t-- Simulate LF ASK tag from demodbuffer or input"}, - {"simfsk", CmdLFfskSim, IfPm3Lf, "[c ] [i] [H ] [L ] [d ] \n\t\t-- Simulate LF FSK tag from demodbuffer or input"}, - {"simpsk", CmdLFpskSim, IfPm3Lf, "[1|2|3] [c ] [i] [r ] [d ] \n\t\t-- Simulate LF PSK tag from demodbuffer or input"}, + {"cmdread", CmdLFCommandRead, IfPm3Lf, "Modulate LF reader field to send command before read (all periods in microseconds)"}, + {"read", CmdLFRead, IfPm3Lf, "Read LF tag"}, + {"search", CmdLFfind, AlwaysAvailable, "Read and Search for valid known tag (in offline mode it you can load first then search)"}, + {"sim", CmdLFSim, IfPm3Lf, "Simulate LF tag from buffer with optional GAP (in microseconds)"}, + {"simask", CmdLFaskSim, IfPm3Lf, "Simulate LF ASK tag from demodbuffer or input"}, + {"simfsk", CmdLFfskSim, IfPm3Lf, "Simulate LF FSK tag from demodbuffer or input"}, + {"simpsk", CmdLFpskSim, IfPm3Lf, "Simulate LF PSK tag from demodbuffer or input"}, +// {"simpsk", CmdLFnrzSim, IfPm3Lf, "Simulate LF NRZ tag from demodbuffer or input"}, {"simbidir", CmdLFSimBidir, IfPm3Lf, "Simulate LF tag (with bidirectional data transmission between reader and tag)"}, {"sniff", CmdLFSniff, IfPm3Lf, "Sniff LF traffic between reader and tag"}, {"tune", CmdLFTune, IfPm3Lf, "Continuously measure LF antenna tuning"}, diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 44747b1ea..9100348bc 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -113,12 +113,12 @@ typedef struct { // A struct used to send sample-configs over USB typedef struct { - uint8_t decimation; - uint8_t bits_per_sample; - bool averaging; - int divisor; - int trigger_threshold; - uint32_t samples_to_skip; + int8_t decimation; + int8_t bits_per_sample; + int8_t averaging; + int16_t divisor; + int16_t trigger_threshold; + int32_t samples_to_skip; bool verbose; } PACKED sample_config; /*