From: Martin Holst Swende Date: Sat, 31 Jan 2015 17:21:38 +0000 (+0100) Subject: Merged with master X-Git-Tag: v2.0.0-rc1~33^2 X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/commitdiff_plain/0644d5e3a3ed255fea1084c0af564c00f592b36c Merged with master --- 0644d5e3a3ed255fea1084c0af564c00f592b36c diff --cc armsrc/appmain.c index 32b7e592,791ad4f8..cb1b9f73 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@@ -906,13 -912,13 +913,13 @@@ void UsbPacketReceived(uint8_t *packet case CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K: LED_B_ON(); + uint8_t *BigBuf = BigBuf_get_addr(); for(size_t i=0; iarg[1]; i += USB_CMD_DATA_SIZE) { size_t len = MIN((c->arg[1] - i),USB_CMD_DATA_SIZE); - cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K,i,len,0,((byte_t*)BigBuf)+c->arg[0]+i,len); + cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K,i,len,traceLen,BigBuf+c->arg[0]+i,len); } // Trigger a finish downloading signal with an ACK frame - // We put a 1 in arg[0] to alert the host we're also sending sample_config - cmd_send(CMD_ACK,1,0,0,getSamplingConfig(),sizeof(sample_config)); - cmd_send(CMD_ACK,0,0,traceLen,0,0); ++ cmd_send(CMD_ACK,1,0,traceLen,getSamplingConfig(),sizeof(sample_config)); LED_B_OFF(); break; diff --cc armsrc/apps.h index 89440bfe,5ef87623..58a2a621 --- a/armsrc/apps.h +++ b/armsrc/apps.h @@@ -81,9 -43,11 +43,8 @@@ int AvgAdc(int ch) void ToSendStuffBit(int b); void ToSendReset(void); void ListenReaderField(int limit); -void AcquireRawAdcSamples125k(int at134khz); -void SnoopLFRawAdcSamples(int divisor, int trigger_threshold); -void DoAcquisition125k(int trigger_threshold); extern int ToSendMax; extern uint8_t ToSend[]; - extern uint32_t BigBuf[]; /// fpga.h void FpgaSendCommand(uint16_t cmd, uint16_t v); diff --cc armsrc/lfops.c index 43af4eed,7b6fa97a..479da772 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@@ -560,13 -645,12 +561,12 @@@ void CmdHIDdemodFSK(int findone, int *h WDT_HIT(); if (ledcontrol) LED_A_ON(); - DoAcquisition125k_internal(-1,true); - // FSK demodulator + DoAcquisition_default(-1,true); + // FSK demodulator - size = HIDdemodFSK(dest, sizeof(BigBuf), &hi2, &hi, &lo); - - WDT_HIT(); - - if (size>0 && lo>0){ + size = sizeOfBigBuff; //variable size will change after demod so re initialize it before use + idx = HIDdemodFSK(dest, &size, &hi2, &hi, &lo); + + if (idx>0 && lo>0){ // final loop, go over previously decoded manchester data and decode into usable tag ID // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0 if (hi2 != 0){ //extra large HID tags @@@ -648,8 -734,8 +650,8 @@@ void CmdEM410xdemod(int findone, int *h WDT_HIT(); if (ledcontrol) LED_A_ON(); - DoAcquisition125k_internal(-1,true); - size = BigBuf_max_traceLen(); + DoAcquisition_default(-1,true); - size = sizeof(BigBuf); ++ size = BigBuf_max_traceLen(); //Dbprintf("DEBUG: Buffer got"); //askdemod and manchester decode errCnt = askmandemod(dest, &size, &clk, &invert); @@@ -699,10 -787,10 +703,10 @@@ void CmdIOdemodFSK(int findone, int *hi while(!BUTTON_PRESS()) { WDT_HIT(); if (ledcontrol) LED_A_ON(); - DoAcquisition125k_internal(-1,true); - //fskdemod and get start index + DoAcquisition_default(-1,true); + //fskdemod and get start index WDT_HIT(); - idx = IOdemodFSK(dest,sizeof(BigBuf)); + idx = IOdemodFSK(dest, BigBuf_max_traceLen()); if (idx>0){ //valid tag found diff --cc armsrc/lfsampling.c index 6314ac74,00000000..348549ef mode 100644,000000..100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@@ -1,251 -1,0 +1,252 @@@ +//----------------------------------------------------------------------------- +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Miscellaneous routines for low frequency sampling. +//----------------------------------------------------------------------------- + +#include "proxmark3.h" +#include "apps.h" +#include "util.h" +#include "string.h" + +#include "lfsampling.h" + +sample_config config = { 1, 8, 1, 88, 0 } ; + +void printConfig() +{ + Dbprintf("Sampling config: "); + Dbprintf(" [q] divisor: %d ", config.divisor); + Dbprintf(" [b] bps: %d ", config.bits_per_sample); + Dbprintf(" [d] decimation: %d ", config.decimation); + Dbprintf(" [a] averaging: %d ", config.averaging); + Dbprintf(" [t] trigger threshold: %d ", config.trigger_threshold); +} + + +/** + * Called from the USB-handler to set the sampling configuration + * The sampling config is used for std reading and snooping. + * + * 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) + * @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->decimation!= 0) config.decimation= sc->decimation; + if(sc->trigger_threshold != -1) config.trigger_threshold= sc->trigger_threshold; + + config.averaging= sc->averaging; + if(config.bits_per_sample > 8) config.bits_per_sample = 8; + if(config.decimation < 1) config.decimation = 1; + + printConfig(); +} + +sample_config* getSamplingConfig() +{ + return &config; +} + +typedef struct { + uint8_t * buffer; + uint32_t numbits; + uint32_t position; +} BitstreamOut; + + +/** + * @brief Pushes bit onto the stream + * @param stream + * @param bit + */ +void pushBit( BitstreamOut* stream, uint8_t bit) +{ + int bytepos = stream->position >> 3; // divide by 8 + int bitpos = stream->position & 7; + *(stream->buffer+bytepos) |= (bit > 0) << (7 - bitpos); + stream->position++; + stream->numbits++; +} + +/** +* Setup the FPGA to listen for samples. This method downloads the FPGA bitstream +* if not already loaded, sets divisor and starts up the antenna. +* @param divisor : 1, 88> 255 or negative ==> 134.8 KHz +* 0 or 95 ==> 125 KHz +* +**/ +void LFSetupFPGAForADC(int divisor, bool lf_field) +{ + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + if ( (divisor == 1) || (divisor < 0) || (divisor > 255) ) + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz + else if (divisor == 0) + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + else + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor); + + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | (lf_field ? FPGA_LF_ADC_READER_FIELD : 0)); + + // Connect the A/D to the peak-detected low-frequency path. + SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + // Give it a bit of time for the resonant antenna to settle. + SpinDelay(50); + // Now set up the SSC to get the ADC samples that are now streaming at us. + FpgaSetupSsc(); +} + + +/** + * Does the sample acquisition. If threshold is specified, the actual sampling + * is not commenced until the threshold has been reached. + * This method implements decimation and quantization in order to + * be able to provide longer sample traces. + * Uses the following global settings: + * @param decimation - how much should the signal be decimated. A decimation of N means we keep 1 in N samples, etc. + * @param bits_per_sample - bits per sample. Max 8, min 1 bit per sample. + * @param averaging If set to true, decimation will use averaging, so that if e.g. decimation is 3, the sample + * value that will be used is the average value of the three samples. + * @param trigger_threshold - a threshold. The sampling won't commence until this threshold has been reached. Set + * to -1 to ignore threshold. + * @param silent - is true, now outputs are made. If false, dbprints the status + * @return the number of bits occupied by the samples. + */ + +uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averaging, int trigger_threshold,bool silent) +{ + //. - uint8_t *dest = (uint8_t *)BigBuf; - int bufsize = BIGBUF_SIZE; ++ uint8_t *dest = BigBuf_get_addr(); ++ int bufsize = BigBuf_max_traceLen(); ++ + memset(dest, 0, bufsize); + + if(bits_per_sample < 1) bits_per_sample = 1; + if(bits_per_sample > 8) bits_per_sample = 8; + + if(decimation < 1) decimation = 1; + + // Use a bit stream to handle the output + BitstreamOut data = { dest , 0, 0}; + int sample_counter = 0; + uint8_t sample = 0; + //If we want to do averaging + uint32_t sample_sum =0 ; + uint32_t sample_total_numbers =0 ; + uint32_t sample_total_saved =0 ; + + while(!BUTTON_PRESS()) { + WDT_HIT(); + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { + AT91C_BASE_SSC->SSC_THR = 0x43; + LED_D_ON(); + } + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + LED_D_OFF(); + if (trigger_threshold > 0 && sample < trigger_threshold) + continue; + + trigger_threshold = 0; + sample_total_numbers++; + + if(averaging) + { + sample_sum += sample; + } + //Check decimation + if(decimation > 1) + { + sample_counter++; + if(sample_counter < decimation) continue; + sample_counter = 0; + } + //Averaging + if(averaging && decimation > 1) { + sample = sample_sum / decimation; + sample_sum =0; + } + //Store the sample + sample_total_saved ++; + if(bits_per_sample == 8){ + dest[sample_total_saved-1] = sample; + data.numbits = sample_total_saved << 3;//Get the return value correct + if(sample_total_saved >= bufsize) break; + } + else{ + pushBit(&data, sample & 0x80); + if(bits_per_sample > 1) pushBit(&data, sample & 0x40); + if(bits_per_sample > 2) pushBit(&data, sample & 0x20); + if(bits_per_sample > 3) pushBit(&data, sample & 0x10); + if(bits_per_sample > 4) pushBit(&data, sample & 0x08); + if(bits_per_sample > 5) pushBit(&data, sample & 0x04); + if(bits_per_sample > 6) pushBit(&data, sample & 0x02); + //Not needed, 8bps is covered above + //if(bits_per_sample > 7) pushBit(&data, sample & 0x01); + if((data.numbits >> 3) +1 >= bufsize) break; + } + } + } + + if(!silent) + { + Dbprintf("Done, saved %d out of %d seen samples at %d bits/sample",sample_total_saved, sample_total_numbers,bits_per_sample); + Dbprintf("buffer samples: %02x %02x %02x %02x %02x %02x %02x %02x ...", + dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]); + } + return data.numbits; +} +/** + * @brief Does sample acquisition, ignoring the config values set in the sample_config. + * This method is typically used by tag-specific readers who just wants to read the samples + * the normal way + * @param trigger_threshold + * @param silent + * @return number of bits sampled + */ +uint32_t DoAcquisition_default(int trigger_threshold, bool silent) +{ + return DoAcquisition(1,8,0,trigger_threshold,silent); +} +uint32_t DoAcquisition_config( bool silent) +{ + return DoAcquisition(config.decimation + ,config.bits_per_sample + ,config.averaging + ,config.trigger_threshold + ,silent); +} + +uint32_t ReadLF(bool activeField) +{ + printConfig(); + LFSetupFPGAForADC(config.divisor, activeField); + // Now call the acquisition routine + return DoAcquisition_config(false); +} + +/** +* Initializes the FPGA for reader-mode (field on), and acquires the samples. +* @return number of bits sampled +**/ +uint32_t SampleLF() +{ + return ReadLF(true); +} +/** +* Initializes the FPGA for snoop-mode (field off), and acquires the samples. +* @return number of bits sampled +**/ + +uint32_t SnoopLF() +{ + return ReadLF(false); +} diff --cc client/cmddata.c index 8f73b400,8c91f0e1..0ec73cbb --- a/client/cmddata.c +++ b/client/cmddata.c @@@ -21,9 -21,8 +21,10 @@@ #include "cmdmain.h" #include "cmddata.h" #include "lfdemod.h" +#include "usb_cmd.h" + uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN]; + uint8_t g_debugMode; int DemodBufferLen; static int CmdHelp(const char *Cmd); @@@ -540,44 -560,28 +562,65 @@@ int CmdDec(const char *Cmd RepaintGraphWindow(); return 0; } +/** + * Undecimate - I'd call it 'interpolate', but we'll save that + * name until someone does an actual interpolation command, not just + * blindly repeating samples + * @param Cmd + * @return + */ +int CmdUndec(const char *Cmd) +{ + if(param_getchar(Cmd, 0) == 'h') + { + PrintAndLog("Usage: data undec [factor]"); + PrintAndLog("This function performs un-decimation, by repeating each sample N times"); + PrintAndLog("Options: "); + PrintAndLog(" h This help"); + PrintAndLog(" factor The number of times to repeat each sample.[default:2]"); + PrintAndLog("Example: 'data undec 3'"); + return 0; + } + + uint8_t factor = param_get8ex(Cmd, 0,2, 10); + //We have memory, don't we? + int swap[MAX_GRAPH_TRACE_LEN] = { 0 }; + uint32_t g_index = 0 ,s_index = 0; + while(g_index < GraphTraceLen && s_index < MAX_GRAPH_TRACE_LEN) + { + int count = 0; + for(count = 0; count < factor && s_index+count < MAX_GRAPH_TRACE_LEN; count ++) + swap[s_index+count] = GraphBuffer[g_index]; + s_index+=count; + } + + memcpy(GraphBuffer,swap, s_index * sizeof(int)); + GraphTraceLen = s_index; + RepaintGraphWindow(); + return 0; +} + //by marshmellow + //shift graph zero up or down based on input + or - + int CmdGraphShiftZero(const char *Cmd) + { + + int shift=0; + //set options from parameters entered with the command + sscanf(Cmd, "%i", &shift); + int shiftedVal=0; + for(int i = 0; i127) + shiftedVal=127; + else if (shiftedVal<-127) + shiftedVal=-127; + GraphBuffer[i]= shiftedVal; + } + CmdNorm(""); + return 0; + } + /* Print our clock rate */ // uses data from graphbuffer int CmdDetectClockRate(const char *Cmd) @@@ -1116,11 -1485,7 +1547,11 @@@ uint8_t getByte(uint8_t bits_per_sample int CmdSamples(const char *Cmd) { - uint8_t got[BIGBUF_SIZE] = {0x00}; + //If we get all but the last byte in bigbuf, + // we don't have to worry about remaining trash + // in the last byte in case the bits-per-sample + // does not line up on byte boundaries - uint8_t got[40000-1]; ++ uint8_t got[BIGBUF_SIZE-1] = { 0 }; int n = strtol(Cmd, NULL, 0); if (n == 0) diff --cc client/graph.h index 2c448161,fe35d4f1..9817d776 --- a/client/graph.h +++ b/client/graph.h @@@ -20,9 -20,10 +20,12 @@@ int GetClock(const char *str, int peak int GetNRZpskClock(const char *str, int peak, int verbose); void setGraphBuf(uint8_t *buff, size_t size); + bool HasGraphData(); + void DetectHighLowInGraph(int *high, int *low, bool addFuzz); + -#define MAX_GRAPH_TRACE_LEN (1024*128) +// Max graph trace len: 40000 (bigbuf) * 8 (at 1 bit per sample) +#define MAX_GRAPH_TRACE_LEN (40000 * 8 ) ++ extern int GraphBuffer[MAX_GRAPH_TRACE_LEN]; extern int GraphTraceLen; - #endif