X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/7c676e7269ce6ca6be9fbadb237873dd31b4d27d..e9281ae812bd5b30394c78889034e653373f1397:/armsrc/lfops.c diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 3cd2bc36..479da772 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -15,221 +15,44 @@ #include "crc16.h" #include "string.h" #include "lfdemod.h" +#include "lfsampling.h" -typedef struct { - uint8_t * buffer; - uint32_t numbits; - uint8_t position; -} BitstreamOut; -/** - * @brief Pushes bit onto the stream - * @param stream - * @param bit - */ -void pushBit( BitstreamOut* stream, bool bit) -{ - int bytepos = stream->position >> 3; // divide by 8 - int bitpos = stream->position & 7; - *(stream->buffer+bytepos) |= (bit & 1) << (7 - bitpos); - stream->position++; - stream->numbits++; -} -/** - * @brief Does LF sample acquisition, this method implements decimation and quantization in order to - * be able to provide longer sample traces. - * @param decimation - how much should the signal be decimated. A decimation of 1 means every sample, 2 means - * every other sample, etc. - * @param bits_per_sample - bits per sample. Max 8, min 1 bit per sample. - * @param trigger_threshold - a threshold. The sampling won't commence until this threshold has been reached. Set - * to -1 to ignore threshold. - * @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. - * @return the number of bits occupied by the samples. - */ -uint8_t DoAcquisition(int decimation, int bits_per_sample, int trigger_threshold, bool averaging) -{ - //A decimation of 2 means we keep every 2nd sample - //A decimation of 3 means we keep 1 in 3 samples. - //A quantization of 1 means one bit is discarded from the sample (division by 2). - uint8_t *dest = (uint8_t *)BigBuf; - int bufsize = BIGBUF_SIZE; - memset(dest, 0, bufsize); - if(bits_per_sample < 1) bits_per_sample = 1; - if(bits_per_sample > 8) bits_per_sample = 8; - - // 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 ; - - for(;;) { - 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; - if (trigger_threshold != -1 && sample < trigger_threshold) - continue; - sample_total_numbers++; - - LED_D_OFF(); - trigger_threshold = -1; - sample_counter++; - sample_sum += sample; - //Check decimation - if(sample_counter < decimation) continue; - //Averaging - if(averaging) sample = sample_sum / decimation; - - sample_counter = 0; - sample_sum =0; - sample_total_saved ++; - 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); - if(bits_per_sample > 7) pushBit(&data, sample & 0x01); - - if((data.numbits >> 3) +1 >= bufsize) break; - } - } - Dbprintf("Done, saved %l out of %l seen samples.",sample_total_saved, sample_total_numbers); - - return data.numbits; -} - - -/** -* Does the sample acquisition. If threshold is specified, the actual sampling -* is not commenced until the threshold has been reached. -* @param trigger_threshold - the threshold -* @param silent - is true, now outputs are made. If false, dbprints the status -*/ -void DoAcquisition125k_internal(int trigger_threshold,bool silent) -{ - uint8_t *dest = (uint8_t *)BigBuf; - int n = sizeof(BigBuf); - int i; - - memset(dest, 0, n); - i = 0; - for(;;) { - 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) { - dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - LED_D_OFF(); - if (trigger_threshold != -1 && dest[i] < trigger_threshold) - continue; - else - trigger_threshold = -1; - if (++i >= n) break; - } - } - if(!silent) - { - 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]); - - } -} -/** -* Perform sample aquisition. -*/ -void DoAcquisition125k(int trigger_threshold) -{ - DoAcquisition125k_internal(trigger_threshold, false); -} - -/** -* 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(); -} /** -* Initializes the FPGA, and acquires the samples. -**/ -void AcquireRawAdcSamples125k(int divisor) -{ - LFSetupFPGAForADC(divisor, true); - // Now call the acquisition routine - DoAcquisition125k_internal(-1,false); -} -/** -* Initializes the FPGA for snoop-mode, and acquires the samples. -**/ - -void SnoopLFRawAdcSamples(int divisor, int trigger_threshold) -{ - LFSetupFPGAForADC(divisor, false); - DoAcquisition125k(trigger_threshold); -} - + * Function to do a modulation and then get samples. + * @param delay_off + * @param period_0 + * @param period_1 + * @param command + */ void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1, uint8_t *command) { - /* Make sure the tag is reset */ - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelay(2500); - - int divisor_used = 95; // 125 KHz // see if 'h' was specified if (command[strlen((char *) command) - 1] == 'h') divisor_used = 88; // 134.8 KHz + sample_config sc = { 0,0,1, divisor_used, 0}; + setSamplingConfig(&sc); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - // Give it a bit of time for the resonant antenna to settle. - SpinDelay(50); + /* Make sure the tag is reset */ + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelay(2500); - // And a little more time for the tag to fully power up - SpinDelay(2000); + LFSetupFPGAForADC(sc.divisor, 1); - // Now set up the SSC to get the ADC samples that are now streaming at us. - FpgaSetupSsc(); + // And a little more time for the tag to fully power up + SpinDelay(2000); // now modulate the reader field while(*command != '\0' && *command != ' ') { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LED_D_OFF(); SpinDelayUs(delay_off); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc.divisor); FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); LED_D_ON(); @@ -241,14 +64,16 @@ void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1, FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LED_D_OFF(); SpinDelayUs(delay_off); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc.divisor); FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); // now do the read - DoAcquisition125k(-1); + DoAcquisition_config(false); } + + /* blank r/w tag data stream ...0000000000000000 01111111 1010101010101010101010101010101010101010101010101010101010101010 @@ -268,8 +93,8 @@ void ReadTItag(void) #define FREQLO 123200 #define FREQHI 134200 - signed char *dest = (signed char *)BigBuf; - int n = sizeof(BigBuf); + signed char *dest = (signed char *)BigBuf_get_addr(); + uint16_t n = BigBuf_max_traceLen(); // 128 bit shift register [shift3:shift2:shift1:shift0] uint32_t shift3 = 0, shift2 = 0, shift1 = 0, shift0 = 0; @@ -421,7 +246,8 @@ void AcquireTiType(void) #define TIBUFLEN 1250 // clear buffer - memset(BigBuf,0,sizeof(BigBuf)); + uint32_t *BigBuf = (uint32_t *)BigBuf_get_addr(); + memset(BigBuf,0,BigBuf_max_traceLen()/sizeof(uint32_t)); // Set up the synchronous serial port AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DIN; @@ -469,7 +295,7 @@ void AcquireTiType(void) AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DOUT; AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN | GPIO_SSC_DOUT; - char *dest = (char *)BigBuf; + char *dest = (char *)BigBuf_get_addr(); n = TIBUFLEN*32; // unpack buffer for (i=TIBUFLEN-1; i>=0; i--) { @@ -558,7 +384,7 @@ void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc) void SimulateTagLowFrequency(int period, int gap, int ledcontrol) { int i; - uint8_t *tab = (uint8_t *)BigBuf; + uint8_t *tab = BigBuf_get_addr(); FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT); @@ -618,7 +444,7 @@ void SimulateTagLowFrequencyBidir(int divisor, int t0) // compose fc/8 fc/10 waveform static void fc(int c, int *n) { - uint8_t *dest = (uint8_t *)BigBuf; + uint8_t *dest = BigBuf_get_addr(); int idx; // for when we want an fc8 pattern every 4 logical bits @@ -722,11 +548,11 @@ void CmdHIDsimTAG(int hi, int lo, int ledcontrol) // loop to get raw HID waveform then FSK demodulate the TAG ID from it void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol) { - uint8_t *dest = (uint8_t *)BigBuf; - - size_t size=0; //, found=0; + uint8_t *dest = BigBuf_get_addr(); + const size_t sizeOfBigBuff = BigBuf_max_traceLen(); + size_t size = 0; uint32_t hi2=0, hi=0, lo=0; - + int idx=0; // Configure to go in 125Khz listen mode LFSetupFPGAForADC(95, true); @@ -735,13 +561,12 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol) WDT_HIT(); if (ledcontrol) LED_A_ON(); - DoAcquisition125k_internal(-1,true); - // FSK demodulator - size = HIDdemodFSK(dest, sizeof(BigBuf), &hi2, &hi, &lo); - - WDT_HIT(); - - if (size>0 && lo>0){ + DoAcquisition_default(-1,true); + // FSK demodulator + 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 @@ -797,6 +622,8 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol) } if (findone){ if (ledcontrol) LED_A_OFF(); + *high = hi; + *low = lo; return; } // reset @@ -810,9 +637,9 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol) void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol) { - uint8_t *dest = (uint8_t *)BigBuf; + uint8_t *dest = BigBuf_get_addr(); - size_t size=0; + size_t size=0, idx=0; int clk=0, invert=0, errCnt=0; uint64_t lo=0; // Configure to go in 125Khz listen mode @@ -823,8 +650,8 @@ void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol) WDT_HIT(); if (ledcontrol) LED_A_ON(); - DoAcquisition125k_internal(-1,true); - size = sizeof(BigBuf); + DoAcquisition_default(-1,true); + size = BigBuf_max_traceLen(); //Dbprintf("DEBUG: Buffer got"); //askdemod and manchester decode errCnt = askmandemod(dest, &size, &clk, &invert); @@ -832,7 +659,7 @@ void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol) WDT_HIT(); if (errCnt>=0){ - lo = Em410xDecode(dest,size); + lo = Em410xDecode(dest, &size, &idx); //Dbprintf("DEBUG: EM GOT"); if (lo>0){ Dbprintf("EM TAG ID: %02x%08x - (%05d_%03d_%08d)", @@ -844,6 +671,8 @@ void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol) } if (findone){ if (ledcontrol) LED_A_OFF(); + *high=lo>>32; + *low=lo & 0xFFFFFFFF; return; } } else{ @@ -862,7 +691,7 @@ void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol) void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) { - uint8_t *dest = (uint8_t *)BigBuf; + uint8_t *dest = BigBuf_get_addr(); int idx=0; uint32_t code=0, code2=0; uint8_t version=0; @@ -874,10 +703,10 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) 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 @@ -910,6 +739,8 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) if (findone){ if (ledcontrol) LED_A_OFF(); //LED_A_OFF(); + *high=code; + *low=code2; return; } code=code2=0; @@ -1049,11 +880,11 @@ void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMod // Read one card block in page 0 void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode) { - uint8_t *dest = (uint8_t *)BigBuf; + uint8_t *dest = BigBuf_get_addr(); //int m=0, i=0; //enio adjustment 12/10/14 uint32_t m=0, i=0; FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - m = sizeof(BigBuf); + m = BigBuf_max_traceLen(); // Clear destination buffer before sending the command memset(dest, 128, m); // Connect the A/D to the peak-detected low-frequency path. @@ -1114,11 +945,11 @@ void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode) // Read card traceability data (page 1) void T55xxReadTrace(void){ - uint8_t *dest = (uint8_t *)BigBuf; + uint8_t *dest = BigBuf_get_addr(); int m=0, i=0; FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - m = sizeof(BigBuf); + m = BigBuf_max_traceLen(); // Clear destination buffer before sending the command memset(dest, 128, m); // Connect the A/D to the peak-detected low-frequency path. @@ -1468,8 +1299,8 @@ void CopyIndala224toT55x7(int uid1, int uid2, int uid3, int uid4, int uid5, int int DemodPCF7931(uint8_t **outBlocks) { uint8_t BitStream[256]; uint8_t Blocks[8][16]; - uint8_t *GraphBuffer = (uint8_t *)BigBuf; - int GraphTraceLen = sizeof(BigBuf); + uint8_t *GraphBuffer = BigBuf_get_addr(); + int GraphTraceLen = BigBuf_max_traceLen(); int i, j, lastval, bitidx, half_switch; int clock = 64; int tolerance = clock / 8; @@ -1479,7 +1310,9 @@ int DemodPCF7931(uint8_t **outBlocks) { int lmin=128, lmax=128; uint8_t dir; - AcquireRawAdcSamples125k(0); + LFSetupFPGAForADC(95, true); + DoAcquisition_default(0, 0); + lmin = 64; lmax = 192; @@ -1886,7 +1719,7 @@ void EM4xLogin(uint32_t Password) { void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) { uint8_t fwd_bit_count; - uint8_t *dest = (uint8_t *)BigBuf; + uint8_t *dest = BigBuf_get_addr(); int m=0, i=0; //If password mode do login @@ -1896,7 +1729,7 @@ void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) { fwd_bit_count = Prepare_Cmd( FWD_CMD_READ ); fwd_bit_count += Prepare_Addr( Address ); - m = sizeof(BigBuf); + m = BigBuf_max_traceLen(); // Clear destination buffer before sending the command memset(dest, 128, m); // Connect the A/D to the peak-detected low-frequency path.