]>
cvs.zerfleddert.de Git - proxmark3-svn/blob - armsrc/lfsampling.c
   1 //----------------------------------------------------------------------------- 
   2 // This code is licensed to you under the terms of the GNU GPL, version 2 or, 
   3 // at your option, any later version. See the LICENSE.txt file for the text of 
   5 //----------------------------------------------------------------------------- 
   6 // Miscellaneous routines for low frequency sampling. 
   7 //----------------------------------------------------------------------------- 
  13 #include "lfsampling.h" 
  14 #include "usb_cdc.h"    // for usb_poll_validate_length 
  15 //#include "ticks.h"            // for StartTicks 
  17 sample_config config 
= { 1, 8, 1, 95, 0 } ; 
  21         Dbprintf("LF Sampling config: "); 
  22         Dbprintf("  [q] divisor:           %d ", config
.divisor
); 
  23         Dbprintf("  [b] bps:               %d ", config
.bits_per_sample
); 
  24         Dbprintf("  [d] decimation:        %d ", config
.decimation
); 
  25         Dbprintf("  [a] averaging:         %d ", config
.averaging
); 
  26         Dbprintf("  [t] trigger threshold: %d ", config
.trigger_threshold
); 
  31  * Called from the USB-handler to set the sampling configuration 
  32  * The sampling config is used for std reading and snooping. 
  34  * Other functions may read samples and ignore the sampling config, 
  35  * such as functions to read the UID from a prox tag or similar. 
  37  * Values set to '0' implies no change (except for averaging) 
  38  * @brief setSamplingConfig 
  41 void setSamplingConfig(sample_config 
*sc
) 
  43         if(sc
->divisor 
!= 0) config
.divisor 
= sc
->divisor
; 
  44         if(sc
->bits_per_sample
!= 0) config
.bits_per_sample
= sc
->bits_per_sample
; 
  45         if(sc
->decimation
!= 0) config
.decimation
= sc
->decimation
; 
  46         if(sc
->trigger_threshold 
!= -1) config
.trigger_threshold
= sc
->trigger_threshold
; 
  48         config
.averaging
= sc
->averaging
; 
  49         if(config
.bits_per_sample 
> 8)  config
.bits_per_sample 
= 8; 
  50         if(config
.decimation 
< 1)       config
.decimation 
= 1; 
  55 sample_config
* getSamplingConfig() 
  67  * @brief Pushes bit onto the stream 
  71 void pushBit( BitstreamOut
* stream
, uint8_t bit
) 
  73         int bytepos 
= stream
->position 
>> 3; // divide by 8 
  74         int bitpos 
= stream
->position 
& 7; 
  75         *(stream
->buffer
+bytepos
) |= (bit 
> 0) <<  (7 - bitpos
); 
  81 * Setup the FPGA to listen for samples. This method downloads the FPGA bitstream 
  82 * if not already loaded, sets divisor and starts up the antenna. 
  83 * @param divisor : 1, 88> 255 or negative ==> 134.8 KHz 
  87 void LFSetupFPGAForADC(int divisor
, bool lf_field
) 
  89         FpgaDownloadAndGo(FPGA_BITSTREAM_LF
); 
  90         if ( (divisor 
== 1) || (divisor 
< 0) || (divisor 
> 255) ) 
  91                 FpgaSendCommand(FPGA_CMD_SET_DIVISOR
, 88); //134.8Khz 
  92         else if (divisor 
== 0) 
  93                 FpgaSendCommand(FPGA_CMD_SET_DIVISOR
, 95); //125Khz 
  95                 FpgaSendCommand(FPGA_CMD_SET_DIVISOR
, divisor
); 
  97         FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC 
| (lf_field 
? FPGA_LF_ADC_READER_FIELD 
: 0)); 
  99         // Connect the A/D to the peak-detected low-frequency path. 
 100         SetAdcMuxFor(GPIO_MUXSEL_LOPKD
); 
 101         // Give it a bit of time for the resonant antenna to settle. 
 103         // Now set up the SSC to get the ADC samples that are now streaming at us. 
 104         FpgaSetupSsc(FPGA_MAJOR_MODE_LF_ADC
); 
 108  * Does the sample acquisition. If threshold is specified, the actual sampling 
 109  * is not commenced until the threshold has been reached. 
 110  * This method implements decimation and quantization in order to 
 111  * be able to provide longer sample traces. 
 112  * Uses the following global settings: 
 113  * @param decimation - how much should the signal be decimated. A decimation of N means we keep 1 in N samples, etc. 
 114  * @param bits_per_sample - bits per sample. Max 8, min 1 bit per sample. 
 115  * @param averaging If set to true, decimation will use averaging, so that if e.g. decimation is 3, the sample 
 116  * value that will be used is the average value of the three samples. 
 117  * @param trigger_threshold - a threshold. The sampling won't commence until this threshold has been reached. Set 
 118  * to -1 to ignore threshold. 
 119  * @param silent - is true, now outputs are made. If false, dbprints the status 
 120  * @return the number of bits occupied by the samples. 
 122 uint32_t DoAcquisition(uint8_t decimation
, uint32_t bits_per_sample
, bool averaging
, int trigger_threshold
, bool silent
, int bufsize
, int cancel_after
) 
 125         uint8_t *dest 
= BigBuf_get_addr(); 
 126         bufsize 
= (bufsize 
> 0 && bufsize 
< BigBuf_max_traceLen()) ? bufsize 
: BigBuf_max_traceLen(); 
 128         //memset(dest, 0, bufsize); //creates issues with cmdread (marshmellow) 
 130         if(bits_per_sample 
< 1) bits_per_sample 
= 1; 
 131         if(bits_per_sample 
> 8) bits_per_sample 
= 8; 
 133         if(decimation 
< 1) decimation 
= 1; 
 135         // Use a bit stream to handle the output 
 136         BitstreamOut data 
= { dest 
, 0, 0}; 
 137         int sample_counter 
= 0; 
 139         //If we want to do averaging 
 140         uint32_t sample_sum 
=0 ; 
 141         uint32_t sample_total_numbers 
=0 ; 
 142         uint32_t sample_total_saved 
=0 ; 
 143         uint32_t cancel_counter 
= 0; 
 145         while(!BUTTON_PRESS() && !usb_poll_validate_length() ) { 
 147                 if (AT91C_BASE_SSC
->SSC_SR 
& AT91C_SSC_TXRDY
) { 
 148                         AT91C_BASE_SSC
->SSC_THR 
= 0x43; 
 151                 if (AT91C_BASE_SSC
->SSC_SR 
& AT91C_SSC_RXRDY
) { 
 152                         sample 
= (uint8_t)AT91C_BASE_SSC
->SSC_RHR
; 
 154                         // threshold either high or low values 128 = center 0.  if trigger = 178  
 155                         if ((trigger_threshold 
> 0) && (sample 
< (trigger_threshold
+128)) && (sample 
> (128-trigger_threshold
))) { //  
 156                                 if (cancel_after 
> 0) { 
 158                                         if (cancel_after 
== cancel_counter
) break; 
 162                         trigger_threshold 
= 0; 
 163                         sample_total_numbers
++; 
 167                                 sample_sum 
+= sample
; 
 173                                 if(sample_counter 
< decimation
) continue; 
 177                         if(averaging 
&& decimation 
> 1) { 
 178                                 sample 
= sample_sum 
/ decimation
; 
 182                         sample_total_saved 
++; 
 183                         if(bits_per_sample 
== 8){ 
 184                                 dest
[sample_total_saved
-1] = sample
; 
 185                                 data
.numbits 
= sample_total_saved 
<< 3;//Get the return value correct 
 186                                 if(sample_total_saved 
>= bufsize
) break; 
 189                                 pushBit(&data
, sample 
& 0x80); 
 190                                 if(bits_per_sample 
> 1) pushBit(&data
, sample 
& 0x40); 
 191                                 if(bits_per_sample 
> 2) pushBit(&data
, sample 
& 0x20); 
 192                                 if(bits_per_sample 
> 3) pushBit(&data
, sample 
& 0x10); 
 193                                 if(bits_per_sample 
> 4) pushBit(&data
, sample 
& 0x08); 
 194                                 if(bits_per_sample 
> 5) pushBit(&data
, sample 
& 0x04); 
 195                                 if(bits_per_sample 
> 6) pushBit(&data
, sample 
& 0x02); 
 196                                 //Not needed, 8bps is covered above 
 197                                 //if(bits_per_sample > 7)       pushBit(&data, sample & 0x01); 
 198                                 if((data
.numbits 
>> 3) +1  >= bufsize
) break; 
 205                 Dbprintf("Done, saved %d out of %d seen samples at %d bits/sample",sample_total_saved
, sample_total_numbers
,bits_per_sample
); 
 206                 Dbprintf("buffer samples: %02x %02x %02x %02x %02x %02x %02x %02x ...", 
 207                                         dest
[0], dest
[1], dest
[2], dest
[3], dest
[4], dest
[5], dest
[6], dest
[7]); 
 212  * @brief Does sample acquisition, ignoring the config values set in the sample_config. 
 213  * This method is typically used by tag-specific readers who just wants to read the samples 
 215  * @param trigger_threshold 
 217  * @return number of bits sampled 
 219 uint32_t DoAcquisition_default(int trigger_threshold
, bool silent
) 
 221         return DoAcquisition(1,8,0,trigger_threshold
,silent
,0,0); 
 223 uint32_t DoAcquisition_config(bool silent
, int sample_size
) 
 225         return DoAcquisition(config
.decimation
 
 226                                   ,config
.bits_per_sample
 
 228                                   ,config
.trigger_threshold
 
 234 uint32_t DoPartialAcquisition(int trigger_threshold
, bool silent
, int sample_size
, int cancel_after
) { 
 235         return DoAcquisition(1,8,0,trigger_threshold
,silent
,sample_size
,cancel_after
); 
 238 uint32_t ReadLF(bool activeField
, bool silent
, int sample_size
) 
 240         if (!silent
) printConfig(); 
 241         LFSetupFPGAForADC(config
.divisor
, activeField
); 
 242         // Now call the acquisition routine 
 243         return DoAcquisition_config(silent
, sample_size
); 
 247 * Initializes the FPGA for reader-mode (field on), and acquires the samples. 
 248 * @return number of bits sampled 
 250 uint32_t SampleLF(bool printCfg
, int sample_size
) 
 252         uint32_t ret 
= ReadLF(true, printCfg
, sample_size
); 
 253         FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
); 
 257 * Initializes the FPGA for snoop-mode (field off), and acquires the samples. 
 258 * @return number of bits sampled 
 263         uint32_t ret 
= ReadLF(false, true, 0); 
 264         FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
); 
 269 * acquisition of Cotag LF signal. Similar to other LF,  since the Cotag has such long datarate RF/384 
 270 * and is Manchester?,  we directly gather the manchester data into bigbuff 
 273 #define COTAG_T2 (COTAG_T1>>1) 
 274 #define COTAG_ONE_THRESHOLD 128+30 
 275 #define COTAG_ZERO_THRESHOLD 128-30 
 277 #define COTAG_BITS 264 
 279 void doCotagAcquisition(size_t sample_size
) { 
 281         uint8_t *dest 
= BigBuf_get_addr(); 
 282         uint16_t bufsize 
= BigBuf_max_traceLen(); 
 284         if ( bufsize 
> sample_size 
) 
 285                 bufsize 
= sample_size
; 
 288         uint8_t sample 
= 0, firsthigh 
= 0, firstlow 
= 0;  
 291         while (!BUTTON_PRESS() && !usb_poll_validate_length() && (i 
< bufsize
) ) { 
 293                 if (AT91C_BASE_SSC
->SSC_SR 
& AT91C_SSC_TXRDY
) { 
 294                         AT91C_BASE_SSC
->SSC_THR 
= 0x43; 
 298                 if (AT91C_BASE_SSC
->SSC_SR 
& AT91C_SSC_RXRDY
) { 
 299                         sample 
= (uint8_t)AT91C_BASE_SSC
->SSC_RHR
; 
 304                                 if (sample 
< COTAG_ONE_THRESHOLD
)  
 309                                 if (sample 
> COTAG_ZERO_THRESHOLD 
) 
 316                         if ( sample 
> COTAG_ONE_THRESHOLD
) 
 318                         else if ( sample 
< COTAG_ZERO_THRESHOLD
) 
 326 uint32_t doCotagAcquisitionManchester() { 
 328         uint8_t *dest 
= BigBuf_get_addr(); 
 329         uint16_t bufsize 
= BigBuf_max_traceLen(); 
 331         if ( bufsize 
> COTAG_BITS 
) 
 332                 bufsize 
= COTAG_BITS
; 
 335         uint8_t sample 
= 0, firsthigh 
= 0, firstlow 
= 0;  
 336         uint16_t sample_counter 
= 0, period 
= 0; 
 337         uint8_t curr 
= 0, prev 
= 0; 
 338         uint16_t noise_counter 
= 0; 
 339         while (!BUTTON_PRESS() && !usb_poll_validate_length() && (sample_counter 
< bufsize
) && (noise_counter 
< (COTAG_T1
<<1)) ) { 
 341                 if (AT91C_BASE_SSC
->SSC_SR 
& AT91C_SSC_TXRDY
) { 
 342                         AT91C_BASE_SSC
->SSC_THR 
= 0x43; 
 346                 if (AT91C_BASE_SSC
->SSC_SR 
& AT91C_SSC_RXRDY
) { 
 347                         sample 
= (uint8_t)AT91C_BASE_SSC
->SSC_RHR
; 
 352                                 if (sample 
< COTAG_ONE_THRESHOLD
) { 
 361                                 if (sample 
> COTAG_ZERO_THRESHOLD 
) { 
 369                         // set sample 255, 0,  or previous 
 370                         if ( sample 
> COTAG_ONE_THRESHOLD
){ 
 374                         else if ( sample 
< COTAG_ZERO_THRESHOLD
) { 
 388                         dest
[sample_counter
] = curr
; 
 393         return sample_counter
;