X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/952a8bb59b197973e35ae187fc8acd2027ee570d..7c676e7269ce6ca6be9fbadb237873dd31b4d27d:/armsrc/lfops.c diff --git a/armsrc/lfops.c b/armsrc/lfops.c index f5040850..3cd2bc36 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -16,6 +16,97 @@ #include "string.h" #include "lfdemod.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