2015-01-31 06:03:44 +08:00
//-----------------------------------------------------------------------------
// 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 "lfsampling.h"
2015-02-27 03:35:35 +08:00
2019-08-08 22:57:33 +08:00
# include "proxmark3_arm.h"
# include "BigBuf.h"
# include "fpgaloader.h"
# include "ticks.h"
# include "dbprint.h"
# include "util.h"
# include "lfdemod.h"
2020-01-08 05:05:01 +08:00
# include "string.h" // memset
2020-06-23 17:21:17 +08:00
# include "appmain.h" // print stack
2019-08-08 22:57:33 +08:00
2017-02-01 21:11:11 +08:00
/*
Default LF config is set to :
2019-03-10 03:34:41 +08:00
decimation = 1 ( we keep 1 out of 1 samples )
bits_per_sample = 8
averaging = YES
2019-08-06 19:51:10 +08:00
divisor = 95 ( 125 kHz )
2019-03-10 03:34:41 +08:00
trigger_threshold = 0
2019-10-12 05:14:57 +08:00
samples_to_skip = 0
verbose = YES
2019-03-10 03:34:41 +08:00
*/
2020-05-19 23:05:43 +08:00
static sample_config config = { 1 , 8 , 1 , LF_DIVISOR_125 , 0 , 0 , 1 } ;
2015-01-31 06:03:44 +08:00
2020-06-23 17:21:17 +08:00
// Holds bit packed struct of samples.
static BitstreamOut data = { 0 , 0 , 0 } ;
// internal struct to keep track of samples gathered
static sampling_t samples = { 0 , 0 , 0 , 0 } ;
2020-05-10 22:59:38 +08:00
void printConfig ( void ) {
2019-10-03 23:45:43 +08:00
uint32_t d = config . divisor ;
2020-06-12 01:20:59 +08:00
DbpString ( _CYAN_ ( " LF Sampling config " ) ) ;
2020-06-10 14:56:45 +08:00
Dbprintf ( " [q] divisor.............%d ( " _GREEN_ ( " %d.%02d kHz " ) " ) " , d , 12000 / ( d + 1 ) , ( ( 1200000 + ( d + 1 ) / 2 ) / ( d + 1 ) ) - ( ( 12000 / ( d + 1 ) ) * 100 ) ) ;
2020-01-08 05:05:01 +08:00
Dbprintf ( " [b] bits per sample.....%d " , config . bits_per_sample ) ;
2019-03-10 03:34:41 +08:00
Dbprintf ( " [d] decimation..........%d " , config . decimation ) ;
Dbprintf ( " [a] averaging...........%s " , ( config . averaging ) ? " Yes " : " No " ) ;
Dbprintf ( " [t] trigger threshold...%d " , config . trigger_threshold ) ;
2019-09-29 08:43:01 +08:00
Dbprintf ( " [s] samples to skip.....%d " , config . samples_to_skip ) ;
2020-06-23 17:21:17 +08:00
DbpString ( _CYAN_ ( " LF Sampling Stack " ) ) ;
print_stack_usage ( ) ;
}
void printSamples ( void ) {
2020-07-02 18:34:48 +08:00
DbpString ( _CYAN_ ( " LF Sampling memory usage " ) ) ;
// Dbprintf(" decimation counter...%d", samples.dec_counter);
// Dbprintf(" sum..................%u", samples.sum);
Dbprintf ( " counter.............. " _YELLOW_ ( " %u " ) , samples . counter ) ;
Dbprintf ( " total saved.......... " _YELLOW_ ( " %u " ) , samples . total_saved ) ;
2020-06-23 17:21:17 +08:00
print_stack_usage ( ) ;
2015-01-31 06:03:44 +08:00
}
/**
* Called from the USB - handler to set the sampling configuration
2020-01-10 02:28:44 +08:00
* The sampling config is used for standard reading and sniffing .
2015-01-31 06:03:44 +08:00
*
* Other functions may read samples and ignore the sampling config ,
* such as functions to read the UID from a prox tag or similar .
*
2020-01-10 02:28:44 +08:00
* Values set to ' - 1 ' implies no change
2015-01-31 06:03:44 +08:00
* @ brief setSamplingConfig
* @ param sc
*/
2019-03-10 18:20:22 +08:00
void setSamplingConfig ( sample_config * sc ) {
2019-03-09 15:59:13 +08:00
2020-01-10 02:28:44 +08:00
// decimation (1-8) how many bits of adc sample value to save
2020-01-13 00:30:29 +08:00
if ( sc - > decimation > 0 & & sc - > decimation < 8 )
2020-01-10 02:28:44 +08:00
config . decimation = sc - > decimation ;
// bits per sample (1-8)
2020-01-13 00:30:29 +08:00
if ( sc - > bits_per_sample > 0 & & sc - > bits_per_sample < 8 )
2020-01-10 02:28:44 +08:00
config . bits_per_sample = sc - > bits_per_sample ;
//
if ( sc - > averaging > - 1 )
config . averaging = ( sc - > averaging > 0 ) ? 1 : 0 ;
2020-01-13 00:30:29 +08:00
2020-01-10 02:28:44 +08:00
// Frequency divisor (19 - 255)
if ( sc - > divisor > 18 & & sc - > divisor < 256 )
config . divisor = sc - > divisor ;
2020-01-13 00:30:29 +08:00
2020-01-10 02:28:44 +08:00
// Start saving samples when adc value larger than trigger_threshold
2020-01-13 00:30:29 +08:00
if ( sc - > trigger_threshold > - 1 )
2020-01-10 02:28:44 +08:00
config . trigger_threshold = sc - > trigger_threshold ;
2020-01-13 00:30:29 +08:00
// Skip n adc samples before saving
2020-01-10 02:28:44 +08:00
if ( sc - > samples_to_skip > - 1 )
config . samples_to_skip = sc - > samples_to_skip ;
2015-01-31 06:03:44 +08:00
2019-10-12 05:14:57 +08:00
if ( sc - > verbose )
printConfig ( ) ;
2015-01-31 06:03:44 +08:00
}
2020-03-05 18:16:05 +08:00
sample_config * getSamplingConfig ( void ) {
2019-03-10 03:34:41 +08:00
return & config ;
2015-01-31 06:03:44 +08:00
}
2015-02-27 03:35:35 +08:00
2015-01-31 06:03:44 +08:00
/**
* @ brief Pushes bit onto the stream
* @ param stream
* @ param bit
*/
2020-05-10 22:59:38 +08:00
static void pushBit ( BitstreamOut * stream , uint8_t bit ) {
2019-03-10 03:34:41 +08:00
int bytepos = stream - > position > > 3 ; // divide by 8
int bitpos = stream - > position & 7 ;
2020-01-16 00:29:01 +08:00
* ( stream - > buffer + bytepos ) & = ~ ( 1 < < ( 7 - bitpos ) ) ;
2019-03-10 07:00:59 +08:00
* ( stream - > buffer + bytepos ) | = ( bit > 0 ) < < ( 7 - bitpos ) ;
2019-03-10 03:34:41 +08:00
stream - > position + + ;
stream - > numbits + + ;
2015-01-31 06:03:44 +08:00
}
2015-02-27 03:35:35 +08:00
2020-01-08 05:05:01 +08:00
void initSampleBuffer ( uint32_t * sample_size ) {
2020-01-29 11:37:10 +08:00
initSampleBufferEx ( sample_size , false ) ;
}
void initSampleBufferEx ( uint32_t * sample_size , bool use_malloc ) {
2020-05-09 03:13:01 +08:00
if ( sample_size = = NULL ) {
Dbprintf ( " initSampleBufferEx, param NULL " ) ;
return ;
}
2020-01-15 05:08:43 +08:00
BigBuf_free ( ) ;
2020-01-29 11:37:10 +08:00
// We can't erase the buffer now, it would drastically delay the acquisition
if ( use_malloc ) {
2020-01-15 05:08:43 +08:00
2020-05-09 03:13:01 +08:00
if ( * sample_size = = 0 ) {
2020-03-11 00:10:05 +08:00
* sample_size = BigBuf_max_traceLen ( ) ;
2020-01-29 11:37:10 +08:00
data . buffer = BigBuf_get_addr ( ) ;
} else {
* sample_size = MIN ( * sample_size , BigBuf_max_traceLen ( ) ) ;
data . buffer = BigBuf_malloc ( * sample_size ) ;
}
2020-01-08 05:05:01 +08:00
2020-01-29 11:37:10 +08:00
} else {
2020-05-09 03:13:01 +08:00
if ( * sample_size = = 0 ) {
2020-01-29 11:37:10 +08:00
* sample_size = BigBuf_max_traceLen ( ) ;
2020-06-22 18:57:28 +08:00
} else {
* sample_size = MIN ( * sample_size , BigBuf_max_traceLen ( ) ) ;
2020-01-29 11:37:10 +08:00
}
data . buffer = BigBuf_get_addr ( ) ;
2020-01-15 05:08:43 +08:00
}
2020-01-08 05:05:01 +08:00
//
samples . dec_counter = 0 ;
samples . sum = 0 ;
2020-06-23 17:21:17 +08:00
samples . counter = * sample_size ;
2020-01-08 05:05:01 +08:00
samples . total_saved = 0 ;
}
2020-05-10 22:59:38 +08:00
uint32_t getSampleCounter ( void ) {
2020-01-08 05:05:01 +08:00
return samples . total_saved ;
}
2020-01-16 17:42:39 +08:00
void logSampleSimple ( uint8_t sample ) {
logSample ( sample , config . decimation , config . bits_per_sample , config . averaging ) ;
}
2020-01-10 02:28:44 +08:00
void logSample ( uint8_t sample , uint8_t decimation , uint8_t bits_per_sample , bool avg ) {
2020-01-08 05:05:01 +08:00
if ( ! data . buffer ) return ;
2020-06-23 17:21:17 +08:00
// keep track of total gather samples regardless how many was discarded.
if ( samples . counter - - = = 0 ) return ;
if ( bits_per_sample = = 0 ) bits_per_sample = 1 ;
2020-01-08 05:05:01 +08:00
if ( bits_per_sample > 8 ) bits_per_sample = 8 ;
if ( decimation = = 0 ) decimation = 1 ;
if ( avg ) {
samples . sum + = sample ;
}
// check decimation
if ( decimation > 1 ) {
samples . dec_counter + + ;
if ( samples . dec_counter < decimation ) return ;
samples . dec_counter = 0 ;
}
// averaging
if ( avg & & decimation > 1 ) {
sample = samples . sum / decimation ;
samples . sum = 0 ;
}
// store the sample
samples . total_saved + + ;
if ( bits_per_sample = = 8 ) {
data . buffer [ samples . total_saved - 1 ] = sample ;
// add number of bits.
data . numbits = samples . total_saved < < 3 ;
} 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 ) ;
}
}
2015-01-31 06:03:44 +08:00
/**
* Setup the FPGA to listen for samples . This method downloads the FPGA bitstream
* if not already loaded , sets divisor and starts up the antenna .
2019-05-09 07:07:34 +08:00
* @ param divisor : 1 , 88 > 255 or negative = = > 134.8 kHz
* 0 or 95 = = > 125 kHz
2015-01-31 06:03:44 +08:00
*
* */
2020-01-23 00:41:59 +08:00
void LFSetupFPGAForADC ( int divisor , bool reader_field ) {
2019-03-10 03:34:41 +08:00
FpgaDownloadAndGo ( FPGA_BITSTREAM_LF ) ;
2019-03-10 07:00:59 +08:00
if ( ( divisor = = 1 ) | | ( divisor < 0 ) | | ( divisor > 255 ) )
2019-10-09 02:57:35 +08:00
FpgaSendCommand ( FPGA_CMD_SET_DIVISOR , LF_DIVISOR_134 ) ; //~134kHz
2019-03-10 03:34:41 +08:00
else if ( divisor = = 0 )
2019-10-09 02:57:35 +08:00
FpgaSendCommand ( FPGA_CMD_SET_DIVISOR , LF_DIVISOR_125 ) ; //125kHz
2019-03-10 03:34:41 +08:00
else
FpgaSendCommand ( FPGA_CMD_SET_DIVISOR , divisor ) ;
2020-01-23 00:41:59 +08:00
FpgaWriteConfWord ( FPGA_MAJOR_MODE_LF_READER | ( reader_field ? FPGA_LF_ADC_READER_FIELD : 0 ) ) ;
2019-03-10 03:34:41 +08:00
// Connect the A/D to the peak-detected low-frequency path.
SetAdcMuxFor ( GPIO_MUXSEL_LOPKD ) ;
2020-06-23 17:21:17 +08:00
2019-03-10 03:34:41 +08:00
// 50ms for the resonant antenna to settle.
2020-01-23 00:41:59 +08:00
if ( reader_field )
2020-03-11 00:10:05 +08:00
SpinDelay ( 50 ) ;
2020-01-23 00:41:59 +08:00
2019-03-10 03:34:41 +08:00
// Now set up the SSC to get the ADC samples that are now streaming at us.
2020-07-02 18:34:48 +08:00
FpgaSetupSsc ( FPGA_MAJOR_MODE_LF_READER ) ;
2020-01-23 00:41:59 +08:00
2019-03-10 03:34:41 +08:00
// start a 1.5ticks is 1us
StartTicks ( ) ;
2015-01-31 06:03:44 +08:00
}
/**
* 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 .
2020-01-08 05:05:01 +08:00
* @ param verbose - is true , dbprints the status , else no outputs
2015-01-31 06:03:44 +08:00
* @ return the number of bits occupied by the samples .
*/
2020-01-10 02:28:44 +08:00
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 ) {
2019-03-10 03:34:41 +08:00
2020-01-08 05:05:01 +08:00
initSampleBuffer ( & sample_size ) ;
2019-03-10 03:34:41 +08:00
2020-06-23 17:21:17 +08:00
if ( DBGLEVEL > = DBG_DEBUG ) {
Dbprintf ( " lf sampling - after init " ) ;
printSamples ( ) ;
}
2019-03-10 03:34:41 +08:00
uint32_t cancel_counter = 0 ;
2020-01-08 05:05:01 +08:00
int16_t checked = 0 ;
2019-07-13 06:38:30 +08:00
2020-06-22 18:57:28 +08:00
while ( BUTTON_PRESS ( ) = = false ) {
2020-01-08 05:05:01 +08:00
// only every 1000th times, in order to save time when collecting samples.
2020-05-09 06:23:46 +08:00
// interruptible only when logging not yet triggered
2020-06-23 17:21:17 +08:00
if ( ( checked = = 4000 ) & & ( trigger_threshold > 0 ) ) {
2020-02-22 20:32:42 +08:00
if ( data_available ( ) ) {
2020-01-08 05:05:01 +08:00
checked = - 1 ;
2019-06-09 20:15:31 +08:00
break ;
2020-01-08 05:05:01 +08:00
} else {
2019-10-04 16:24:04 +08:00
checked = 0 ;
2020-01-08 05:05:01 +08:00
}
2019-06-09 20:15:31 +08:00
}
2019-10-04 16:24:04 +08:00
+ + checked ;
2019-07-13 06:38:30 +08:00
2019-03-10 03:34:41 +08:00
WDT_HIT ( ) ;
2020-01-08 05:05:01 +08:00
if ( AT91C_BASE_SSC - > SSC_SR & AT91C_SSC_TXRDY ) {
LED_D_ON ( ) ;
}
2019-03-10 03:34:41 +08:00
if ( AT91C_BASE_SSC - > SSC_SR & AT91C_SSC_RXRDY ) {
2020-01-08 05:05:01 +08:00
volatile uint8_t sample = ( uint8_t ) AT91C_BASE_SSC - > SSC_RHR ;
2019-03-10 03:34:41 +08:00
// Testpoint 8 (TP8) can be used to trigger oscilliscope
LED_D_OFF ( ) ;
// threshold either high or low values 128 = center 0. if trigger = 178
if ( ( trigger_threshold > 0 ) & & ( sample < ( trigger_threshold + 128 ) ) & & ( sample > ( 128 - trigger_threshold ) ) ) {
if ( cancel_after > 0 ) {
cancel_counter + + ;
if ( cancel_after = = cancel_counter )
break ;
}
continue ;
}
trigger_threshold = 0 ;
2019-09-29 08:43:01 +08:00
2019-09-30 17:41:25 +08:00
if ( samples_to_skip > 0 ) {
samples_to_skip - - ;
2019-09-29 08:43:01 +08:00
continue ;
}
2020-01-08 05:05:01 +08:00
logSample ( sample , decimation , bits_per_sample , avg ) ;
2019-03-10 03:34:41 +08:00
2020-01-08 05:05:01 +08:00
if ( samples . total_saved > = sample_size ) break ;
2019-03-10 03:34:41 +08:00
}
}
2020-06-23 17:21:17 +08:00
2020-01-08 05:05:01 +08:00
if ( checked = = - 1 & & verbose ) {
Dbprintf ( " lf sampling aborted " ) ;
}
if ( verbose ) {
2020-04-22 08:22:55 +08:00
Dbprintf ( " Done, saved " _YELLOW_ ( " %d " ) " out of " _YELLOW_ ( " %d " ) " seen samples at " _YELLOW_ ( " %d " ) " bits/sample " , samples . total_saved , samples . counter , bits_per_sample ) ;
2019-03-10 03:34:41 +08:00
}
// Ensure that DC offset removal and noise check is performed for any device-side processing
2020-01-08 05:05:01 +08:00
removeSignalOffset ( data . buffer , samples . total_saved ) ;
computeSignalProperties ( data . buffer , samples . total_saved ) ;
2019-03-10 03:34:41 +08:00
return data . numbits ;
2015-01-31 06:03:44 +08:00
}
/**
* @ 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
2020-01-08 05:05:01 +08:00
* @ param verbose
2015-01-31 06:03:44 +08:00
* @ return number of bits sampled
*/
2020-01-08 05:05:01 +08:00
uint32_t DoAcquisition_default ( int trigger_threshold , bool verbose ) {
return DoAcquisition ( 1 , 8 , 0 , trigger_threshold , verbose , 0 , 0 , 0 ) ;
2015-01-31 06:03:44 +08:00
}
2020-01-08 05:05:01 +08:00
uint32_t DoAcquisition_config ( bool verbose , uint32_t sample_size ) {
2019-03-10 03:34:41 +08:00
return DoAcquisition ( config . decimation
2019-03-10 07:00:59 +08:00
, config . bits_per_sample
, config . averaging
, config . trigger_threshold
2020-01-08 05:05:01 +08:00
, verbose
2019-03-10 07:00:59 +08:00
, sample_size
2019-09-29 08:43:01 +08:00
, 0
, config . samples_to_skip ) ;
2017-02-24 22:45:24 +08:00
}
2020-01-08 05:05:01 +08:00
uint32_t DoPartialAcquisition ( int trigger_threshold , bool verbose , uint32_t sample_size , uint32_t cancel_after ) {
return DoAcquisition ( 1 , 8 , 0 , trigger_threshold , verbose , sample_size , cancel_after , 0 ) ;
2015-01-31 06:03:44 +08:00
}
2020-05-10 22:59:38 +08:00
static uint32_t ReadLF ( bool reader_field , bool verbose , uint32_t sample_size ) {
2020-01-08 05:05:01 +08:00
if ( verbose )
2019-03-10 03:34:41 +08:00
printConfig ( ) ;
2020-01-08 05:05:01 +08:00
2020-01-23 00:41:59 +08:00
LFSetupFPGAForADC ( config . divisor , reader_field ) ;
2020-01-08 05:05:01 +08:00
uint32_t ret = DoAcquisition_config ( verbose , sample_size ) ;
2019-03-12 06:12:31 +08:00
FpgaWriteConfWord ( FPGA_MAJOR_MODE_OFF ) ;
return ret ;
2015-01-31 06:03:44 +08:00
}
/**
* Initializes the FPGA for reader - mode ( field on ) , and acquires the samples .
* @ return number of bits sampled
* */
2020-01-08 05:05:01 +08:00
uint32_t SampleLF ( bool verbose , uint32_t sample_size ) {
2019-03-10 03:34:41 +08:00
BigBuf_Clear_ext ( false ) ;
2020-01-08 05:05:01 +08:00
return ReadLF ( true , verbose , sample_size ) ;
2015-01-31 06:03:44 +08:00
}
/**
2019-03-12 20:15:39 +08:00
* Initializes the FPGA for sniffer - mode ( field off ) , and acquires the samples .
2015-01-31 06:03:44 +08:00
* @ return number of bits sampled
* */
2020-05-10 22:59:38 +08:00
uint32_t SniffLF ( void ) {
2019-03-10 03:34:41 +08:00
BigBuf_Clear_ext ( false ) ;
2019-03-12 06:12:31 +08:00
return ReadLF ( false , true , 0 ) ;
2015-01-31 06:03:44 +08:00
}
2015-10-15 16:23:15 +08:00
/**
2018-02-15 04:45:36 +08:00
* acquisition of T55x7 LF signal . Similar to other LF , but adjusted with @ marshmellows thresholds
2015-10-15 16:23:15 +08:00
* the data is collected in BigBuf .
* */
2019-03-10 18:20:22 +08:00
void doT55x7Acquisition ( size_t sample_size ) {
2015-10-15 16:23:15 +08:00
2019-03-10 07:00:59 +08:00
# define T55xx_READ_UPPER_THRESHOLD 128+60 // 60 grph
# define T55xx_READ_LOWER_THRESHOLD 128-60 // -60 grph
# define T55xx_READ_TOL 5
2019-03-10 03:34:41 +08:00
uint8_t * dest = BigBuf_get_addr ( ) ;
uint16_t bufsize = BigBuf_max_traceLen ( ) ;
2019-03-10 07:00:59 +08:00
if ( bufsize > sample_size )
2019-03-10 03:34:41 +08:00
bufsize = sample_size ;
2020-01-08 05:05:01 +08:00
uint8_t lastSample = 0 ;
2019-03-10 03:34:41 +08:00
uint16_t i = 0 , skipCnt = 0 ;
bool startFound = false ;
bool highFound = false ;
bool lowFound = false ;
2019-07-13 06:38:30 +08:00
2019-06-09 21:32:34 +08:00
uint16_t checker = 0 ;
2020-06-23 17:21:17 +08:00
if ( DBGLEVEL > = DBG_DEBUG ) {
Dbprintf ( " doT55x7Acquisition - after init " ) ;
print_stack_usage ( ) ;
}
2019-07-13 06:38:30 +08:00
while ( skipCnt < 1000 & & ( i < bufsize ) ) {
2020-06-23 17:21:17 +08:00
if ( BUTTON_PRESS ( ) )
break ;
if ( checker = = 4000 ) {
if ( data_available ( ) )
2019-06-09 21:32:34 +08:00
break ;
else
checker = 0 ;
} else {
+ + checker ;
}
2019-03-10 03:34:41 +08:00
WDT_HIT ( ) ;
2020-01-08 05:05:01 +08:00
if ( AT91C_BASE_SSC - > SSC_SR & AT91C_SSC_TXRDY ) {
LED_D_ON ( ) ;
}
2019-03-10 03:34:41 +08:00
if ( AT91C_BASE_SSC - > SSC_SR & AT91C_SSC_RXRDY ) {
2020-01-08 05:05:01 +08:00
volatile uint8_t sample = ( uint8_t ) AT91C_BASE_SSC - > SSC_RHR ;
2019-03-10 03:34:41 +08:00
LED_D_OFF ( ) ;
// skip until the first high sample above threshold
2020-01-08 05:05:01 +08:00
if ( ! startFound & & sample > T55xx_READ_UPPER_THRESHOLD ) {
2019-03-10 03:34:41 +08:00
highFound = true ;
} else if ( ! highFound ) {
skipCnt + + ;
continue ;
}
// skip until the first low sample below threshold
2020-01-08 05:05:01 +08:00
if ( ! startFound & & sample < T55xx_READ_LOWER_THRESHOLD ) {
lastSample = sample ;
2019-03-10 03:34:41 +08:00
lowFound = true ;
} else if ( ! lowFound ) {
skipCnt + + ;
continue ;
}
// skip until first high samples begin to change
2020-01-08 05:05:01 +08:00
if ( startFound | | sample > T55xx_READ_LOWER_THRESHOLD + T55xx_READ_TOL ) {
2019-03-10 03:34:41 +08:00
// if just found start - recover last sample
if ( ! startFound ) {
dest [ i + + ] = lastSample ;
startFound = true ;
}
// collect samples
2020-01-08 05:05:01 +08:00
dest [ i + + ] = sample ;
2019-03-10 03:34:41 +08:00
}
}
}
2015-10-28 04:47:21 +08:00
}
2017-02-02 22:32:21 +08:00
/**
* acquisition of Cotag LF signal . Similart to other LF , since the Cotag has such long datarate RF / 384
* and is Manchester ? , we directly gather the manchester data into bigbuff
* */
# define COTAG_T1 384
# define COTAG_T2 (COTAG_T1>>1)
2020-07-02 18:34:48 +08:00
# define COTAG_ONE_THRESHOLD 128+5
# define COTAG_ZERO_THRESHOLD 128-5
2017-02-24 22:45:24 +08:00
# ifndef COTAG_BITS
# define COTAG_BITS 264
# endif
2020-07-02 18:34:48 +08:00
void doCotagAcquisition ( ) {
2017-02-02 22:32:21 +08:00
2019-03-10 03:34:41 +08:00
uint8_t * dest = BigBuf_get_addr ( ) ;
2020-07-02 18:34:48 +08:00
uint16_t bufsize = BigBuf_max_traceLen ( ) ;
2019-03-10 03:34:41 +08:00
dest [ 0 ] = 0 ;
2020-01-08 05:05:01 +08:00
uint8_t firsthigh = 0 , firstlow = 0 ;
2020-07-02 18:34:48 +08:00
uint16_t i = 0 , noise_counter = 0 ;
2020-06-23 17:21:17 +08:00
if ( DBGLEVEL > = DBG_DEBUG ) {
Dbprintf ( " doCotagAcquisition - after init " ) ;
print_stack_usage ( ) ;
}
2019-07-13 06:38:30 +08:00
2019-06-09 21:32:34 +08:00
while ( ( i < bufsize ) & & ( noise_counter < ( COTAG_T1 < < 1 ) ) ) {
2020-06-23 17:21:17 +08:00
if ( BUTTON_PRESS ( ) )
break ;
2019-03-10 03:34:41 +08:00
WDT_HIT ( ) ;
if ( AT91C_BASE_SSC - > SSC_SR & AT91C_SSC_RXRDY ) {
2020-01-08 05:05:01 +08:00
volatile uint8_t sample = ( uint8_t ) AT91C_BASE_SSC - > SSC_RHR ;
2019-03-10 03:34:41 +08:00
// find first peak
2019-03-10 07:00:59 +08:00
if ( ! firsthigh ) {
2019-03-10 03:34:41 +08:00
if ( sample < COTAG_ONE_THRESHOLD ) {
noise_counter + + ;
continue ;
}
noise_counter = 0 ;
firsthigh = 1 ;
}
2019-03-10 07:00:59 +08:00
if ( ! firstlow ) {
if ( sample > COTAG_ZERO_THRESHOLD ) {
2019-03-10 03:34:41 +08:00
noise_counter + + ;
continue ;
}
noise_counter = 0 ;
firstlow = 1 ;
}
+ + i ;
2019-03-10 07:00:59 +08:00
if ( sample > COTAG_ONE_THRESHOLD )
2019-03-10 03:34:41 +08:00
dest [ i ] = 255 ;
2019-03-10 07:00:59 +08:00
else if ( sample < COTAG_ZERO_THRESHOLD )
2019-03-10 03:34:41 +08:00
dest [ i ] = 0 ;
else
2019-03-10 07:00:59 +08:00
dest [ i ] = dest [ i - 1 ] ;
2019-03-10 03:34:41 +08:00
}
}
2019-11-04 22:13:59 +08:00
2020-07-02 18:34:48 +08:00
Dbprintf ( " doCotagAcquisition - %u high %u == 1 low %u == 1 " , i , firsthigh , firstlow ) ;
2019-11-04 22:13:59 +08:00
// Ensure that DC offset removal and noise check is performed for any device-side processing
removeSignalOffset ( dest , bufsize ) ;
2020-07-02 18:34:48 +08:00
printSamples ( ) ;
2019-11-04 22:13:59 +08:00
computeSignalProperties ( dest , bufsize ) ;
2020-07-02 18:34:48 +08:00
printSamples ( ) ;
2017-02-02 22:32:21 +08:00
}
2020-05-10 22:59:38 +08:00
uint32_t doCotagAcquisitionManchester ( void ) {
2017-02-02 22:32:21 +08:00
2019-03-10 03:34:41 +08:00
uint8_t * dest = BigBuf_get_addr ( ) ;
2020-06-23 17:21:17 +08:00
uint16_t bufsize = MIN ( COTAG_BITS , BigBuf_max_traceLen ( ) ) ;
2019-03-10 03:34:41 +08:00
dest [ 0 ] = 0 ;
2020-01-08 05:05:01 +08:00
uint8_t firsthigh = 0 , firstlow = 0 ;
2019-03-10 03:34:41 +08:00
uint8_t curr = 0 , prev = 0 ;
2020-06-23 17:21:17 +08:00
uint16_t sample_counter = 0 , period = 0 ;
2020-07-02 18:34:48 +08:00
uint16_t noise_counter = 0 ;
2020-06-23 17:21:17 +08:00
if ( DBGLEVEL > = DBG_DEBUG ) {
Dbprintf ( " doCotagAcquisitionManchester - after init " ) ;
print_stack_usage ( ) ;
}
2019-06-09 21:32:34 +08:00
while ( ( sample_counter < bufsize ) & & ( noise_counter < ( COTAG_T1 < < 1 ) ) ) {
2020-06-23 17:21:17 +08:00
if ( BUTTON_PRESS ( ) )
break ;
2019-03-10 03:34:41 +08:00
WDT_HIT ( ) ;
2020-01-08 05:05:01 +08:00
if ( AT91C_BASE_SSC - > SSC_SR & AT91C_SSC_TXRDY ) {
LED_D_ON ( ) ;
}
2019-03-10 03:34:41 +08:00
if ( AT91C_BASE_SSC - > SSC_SR & AT91C_SSC_RXRDY ) {
2020-01-08 05:05:01 +08:00
volatile uint8_t sample = ( uint8_t ) AT91C_BASE_SSC - > SSC_RHR ;
2019-03-10 03:34:41 +08:00
// find first peak
2019-03-10 07:00:59 +08:00
if ( ! firsthigh ) {
2019-03-10 03:34:41 +08:00
if ( sample < COTAG_ONE_THRESHOLD ) {
noise_counter + + ;
continue ;
}
noise_counter = 0 ;
firsthigh = 1 ;
}
2019-03-10 07:00:59 +08:00
if ( ! firstlow ) {
if ( sample > COTAG_ZERO_THRESHOLD ) {
2019-03-10 03:34:41 +08:00
noise_counter + + ;
continue ;
}
noise_counter = 0 ;
firstlow = 1 ;
}
// set sample 255, 0, or previous
2019-03-10 07:00:59 +08:00
if ( sample > COTAG_ONE_THRESHOLD ) {
2019-03-10 03:34:41 +08:00
prev = curr ;
curr = 1 ;
2019-03-12 06:12:31 +08:00
} else if ( sample < COTAG_ZERO_THRESHOLD ) {
2019-03-10 03:34:41 +08:00
prev = curr ;
curr = 0 ;
2019-03-12 06:12:31 +08:00
} else {
2019-03-10 03:34:41 +08:00
curr = prev ;
}
// full T1 periods,
2019-03-10 07:00:59 +08:00
if ( period > 0 ) {
2019-03-10 03:34:41 +08:00
- - period ;
continue ;
}
dest [ sample_counter ] = curr ;
+ + sample_counter ;
period = COTAG_T1 ;
}
}
return sample_counter ;
2019-03-09 02:06:55 +08:00
}