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"
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
*/
2019-10-12 05:14:57 +08:00
sample_config config = { 1 , 8 , 1 , LF_DIVISOR_125 , 0 , 0 , 1 } ;
2015-01-31 06:03:44 +08:00
2019-03-10 18:20:22 +08:00
void printConfig ( ) {
2019-10-03 23:45:43 +08:00
uint32_t d = config . divisor ;
2019-04-30 19:02:27 +08:00
DbpString ( _BLUE_ ( " LF Sampling config " ) ) ;
2019-10-13 06:48:26 +08:00
Dbprintf ( " [q] divisor.............%d ( " _GREEN_ ( " %d.%02d kHz " ) " ) " , d , 12000 / ( d + 1 ) , ( ( 1200000 + ( d + 1 ) / 2 ) / ( d + 1 ) ) - ( ( 12000 / ( d + 1 ) ) * 100 ) ) ;
2019-03-10 03:34:41 +08:00
Dbprintf ( " [b] bps.................%d " , config . bits_per_sample ) ;
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 ) ;
2015-01-31 06:03:44 +08:00
}
/**
* Called from the USB - handler to set the sampling configuration
2019-03-12 20:15:39 +08:00
* The sampling config is used for std 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 .
*
* Values set to ' 0 ' implies no change ( except for averaging )
* @ brief setSamplingConfig
* @ param sc
*/
2019-03-10 18:20:22 +08:00
void setSamplingConfig ( sample_config * sc ) {
2019-03-10 07:00:59 +08:00
if ( sc - > divisor ! = 0 ) config . divisor = sc - > divisor ;
if ( sc - > bits_per_sample ! = 0 ) config . bits_per_sample = sc - > bits_per_sample ;
if ( sc - > trigger_threshold ! = - 1 ) config . trigger_threshold = sc - > trigger_threshold ;
2019-10-13 06:48:26 +08:00
// if (sc->samples_to_skip == 0xffffffff) // if needed to not update if not supplied
2019-03-09 15:59:13 +08:00
2019-09-30 17:22:26 +08:00
config . samples_to_skip = sc - > samples_to_skip ;
2019-03-10 03:34:41 +08:00
config . decimation = ( sc - > decimation ! = 0 ) ? sc - > decimation : 1 ;
config . averaging = sc - > averaging ;
2019-03-10 07:00:59 +08:00
if ( config . bits_per_sample > 8 ) config . bits_per_sample = 8 ;
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
}
2019-03-10 18:20:22 +08:00
sample_config * getSamplingConfig ( ) {
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
2017-01-25 07:33:03 +08:00
struct BitstreamOut {
2019-03-10 07:00:59 +08:00
uint8_t * buffer ;
2019-03-10 03:34:41 +08:00
uint32_t numbits ;
uint32_t position ;
2017-01-25 07:33:03 +08:00
} ;
2015-01-31 06:03:44 +08:00
/**
* @ brief Pushes bit onto the stream
* @ param stream
* @ param bit
*/
2019-03-10 18:20:22 +08:00
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 ;
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
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
*
* */
2019-03-10 18:20:22 +08:00
void LFSetupFPGAForADC ( int divisor , bool lf_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 ) ;
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 ) ;
// 50ms 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 ( ) ;
// 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 .
* @ param silent - is true , now outputs are made . If false , dbprints the status
* @ return the number of bits occupied by the samples .
*/
2019-09-30 17:22:26 +08:00
uint32_t DoAcquisition ( uint8_t decimation , uint32_t bits_per_sample , bool averaging , int trigger_threshold , bool silent , int bufsize , uint32_t cancel_after , uint32_t samples_to_skip ) {
2019-01-12 19:10:31 +08:00
2019-03-10 03:34:41 +08:00
uint8_t * dest = BigBuf_get_addr ( ) ;
2017-02-24 22:45:24 +08:00
bufsize = ( bufsize > 0 & & bufsize < BigBuf_max_traceLen ( ) ) ? bufsize : BigBuf_max_traceLen ( ) ;
2015-02-01 01:21:38 +08:00
2019-03-10 03:34:41 +08:00
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
2019-03-10 07:00:59 +08:00
BitstreamOut data = { dest , 0 , 0 } ;
2019-03-10 03:34:41 +08:00
int sample_counter = 0 ;
2019-04-10 02:37:35 +08:00
uint8_t sample ;
2019-03-10 03:34:41 +08:00
// if we want to do averaging
2019-03-10 07:00:59 +08:00
uint32_t sample_sum = 0 ;
2019-03-10 03:34:41 +08:00
uint32_t sample_total_numbers = 0 ;
uint32_t sample_total_saved = 0 ;
uint32_t cancel_counter = 0 ;
2019-07-13 06:38:30 +08:00
2019-10-04 16:24:04 +08:00
uint16_t checked = 0 ;
2019-07-13 06:38:30 +08:00
2019-06-09 20:15:31 +08:00
while ( true ) {
2019-10-04 16:24:04 +08:00
if ( checked = = 1000 ) {
2019-06-09 20:15:31 +08:00
if ( BUTTON_PRESS ( ) | | data_available ( ) )
break ;
else
2019-10-04 16:24:04 +08:00
checked = 0 ;
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 ( ) ;
if ( AT91C_BASE_SSC - > SSC_SR & AT91C_SSC_RXRDY ) {
sample = ( uint8_t ) AT91C_BASE_SSC - > SSC_RHR ;
// 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 ;
}
2019-03-10 03:34:41 +08:00
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 ;
2019-03-10 07:00:59 +08:00
sample_sum = 0 ;
2019-03-10 03:34:41 +08:00
}
// store the sample
sample_total_saved + + ;
2019-09-29 08:43:01 +08:00
2019-03-10 03:34:41 +08:00
if ( bits_per_sample = = 8 ) {
2019-03-10 07:00:59 +08:00
dest [ sample_total_saved - 1 ] = sample ;
2019-03-10 03:34:41 +08:00
// Get the return value correct
data . numbits = sample_total_saved < < 3 ;
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 ) ;
if ( ( data . numbits > > 3 ) + 1 > = bufsize ) break ;
}
}
}
if ( ! silent ) {
2019-05-20 21:15:45 +08:00
Dbprintf ( " Done, saved " _YELLOW_ ( " %d " ) " out of " _YELLOW_ ( " %d " ) " seen samples at " _YELLOW_ ( " %d " ) " bits/sample " , sample_total_saved , sample_total_numbers , bits_per_sample ) ;
2019-03-10 03:34:41 +08:00
Dbprintf ( " buffer samples: %02x %02x %02x %02x %02x %02x %02x %02x ... " ,
2019-03-10 07:00:59 +08:00
dest [ 0 ] , dest [ 1 ] , dest [ 2 ] , dest [ 3 ] , dest [ 4 ] , dest [ 5 ] , dest [ 6 ] , dest [ 7 ] ) ;
2019-03-10 03:34:41 +08:00
}
// Ensure that DC offset removal and noise check is performed for any device-side processing
removeSignalOffset ( dest , bufsize ) ;
computeSignalProperties ( dest , bufsize ) ;
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
* @ param silent
* @ return number of bits sampled
*/
2019-03-10 18:20:22 +08:00
uint32_t DoAcquisition_default ( int trigger_threshold , bool silent ) {
2019-09-30 17:41:25 +08:00
return DoAcquisition ( 1 , 8 , 0 , trigger_threshold , silent , 0 , 0 , 0 ) ;
2015-01-31 06:03:44 +08:00
}
2019-03-10 18:20:22 +08:00
uint32_t DoAcquisition_config ( bool silent , int 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
, silent
, sample_size
2019-09-29 08:43:01 +08:00
, 0
, config . samples_to_skip ) ;
2017-02-24 22:45:24 +08:00
}
2019-03-10 18:20:22 +08:00
uint32_t DoPartialAcquisition ( int trigger_threshold , bool silent , int sample_size , uint32_t cancel_after ) {
2019-09-30 17:41:25 +08:00
return DoAcquisition ( 1 , 8 , 0 , trigger_threshold , silent , sample_size , cancel_after , 0 ) ;
2015-01-31 06:03:44 +08:00
}
2019-03-10 18:20:22 +08:00
uint32_t ReadLF ( bool activeField , bool silent , int sample_size ) {
2019-03-10 03:34:41 +08:00
if ( ! silent )
printConfig ( ) ;
LFSetupFPGAForADC ( config . divisor , activeField ) ;
2019-03-12 06:12:31 +08:00
uint32_t ret = DoAcquisition_config ( silent , sample_size ) ;
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
* */
2019-04-07 02:21:03 +08:00
uint32_t SampleLF ( bool silent , int sample_size ) {
2019-03-10 03:34:41 +08:00
BigBuf_Clear_ext ( false ) ;
2019-04-07 02:21:03 +08:00
return ReadLF ( true , silent , 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
* */
2019-03-12 20:15:39 +08:00
uint32_t SniffLF ( ) {
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 ;
2019-04-10 02:37:35 +08:00
uint8_t curSample , 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 ;
2019-07-13 06:38:30 +08:00
while ( skipCnt < 1000 & & ( i < bufsize ) ) {
if ( checker = = 1000 ) {
2019-06-09 21:32:34 +08:00
if ( BUTTON_PRESS ( ) | | data_available ( ) )
break ;
else
checker = 0 ;
} else {
+ + checker ;
}
2019-03-10 03:34:41 +08:00
WDT_HIT ( ) ;
if ( AT91C_BASE_SSC - > SSC_SR & AT91C_SSC_RXRDY ) {
curSample = ( uint8_t ) AT91C_BASE_SSC - > SSC_RHR ;
LED_D_OFF ( ) ;
// skip until the first high sample above threshold
if ( ! startFound & & curSample > T55xx_READ_UPPER_THRESHOLD ) {
//if (curSample > lastSample)
// lastSample = curSample;
highFound = true ;
} else if ( ! highFound ) {
skipCnt + + ;
continue ;
}
// skip until the first low sample below threshold
if ( ! startFound & & curSample < T55xx_READ_LOWER_THRESHOLD ) {
//if (curSample > lastSample)
lastSample = curSample ;
lowFound = true ;
} else if ( ! lowFound ) {
skipCnt + + ;
continue ;
}
// skip until first high samples begin to change
2019-03-10 07:00:59 +08:00
if ( startFound | | curSample > 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
dest [ i + + ] = curSample ;
}
}
}
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)
# define COTAG_ONE_THRESHOLD 128+30
# define COTAG_ZERO_THRESHOLD 128-30
2017-02-24 22:45:24 +08:00
# ifndef COTAG_BITS
# define COTAG_BITS 264
# endif
2019-03-10 18:20:22 +08:00
void doCotagAcquisition ( size_t sample_size ) {
2017-02-02 22:32:21 +08:00
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 ;
dest [ 0 ] = 0 ;
2019-04-10 02:37:35 +08:00
uint8_t sample , firsthigh = 0 , firstlow = 0 ;
2019-03-10 03:34:41 +08:00
uint16_t i = 0 ;
uint16_t noise_counter = 0 ;
2019-06-09 21:32:34 +08:00
uint16_t checker = 0 ;
2019-07-13 06:38:30 +08:00
2019-06-09 21:32:34 +08:00
while ( ( i < bufsize ) & & ( noise_counter < ( COTAG_T1 < < 1 ) ) ) {
2019-07-13 06:38:30 +08:00
if ( checker = = 1000 ) {
2019-06-09 21:32:34 +08:00
if ( BUTTON_PRESS ( ) | | data_available ( ) )
break ;
else
checker = 0 ;
} else {
+ + checker ;
}
2019-03-10 03:34:41 +08:00
WDT_HIT ( ) ;
if ( AT91C_BASE_SSC - > SSC_SR & AT91C_SSC_RXRDY ) {
sample = ( uint8_t ) AT91C_BASE_SSC - > SSC_RHR ;
// 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
}
}
2017-02-02 22:32:21 +08:00
}
2019-03-10 18:20:22 +08:00
uint32_t doCotagAcquisitionManchester ( ) {
2017-02-02 22:32:21 +08:00
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 > COTAG_BITS )
2019-03-10 03:34:41 +08:00
bufsize = COTAG_BITS ;
dest [ 0 ] = 0 ;
2019-04-10 02:37:35 +08:00
uint8_t sample , firsthigh = 0 , firstlow = 0 ;
2019-03-10 03:34:41 +08:00
uint16_t sample_counter = 0 , period = 0 ;
uint8_t curr = 0 , prev = 0 ;
uint16_t noise_counter = 0 ;
2019-06-09 21:32:34 +08:00
uint16_t checker = 0 ;
2019-07-13 06:38:30 +08:00
2019-06-09 21:32:34 +08:00
while ( ( sample_counter < bufsize ) & & ( noise_counter < ( COTAG_T1 < < 1 ) ) ) {
2019-07-13 06:38:30 +08:00
if ( checker = = 1000 ) {
2019-06-09 21:32:34 +08:00
if ( BUTTON_PRESS ( ) | | data_available ( ) )
break ;
else
checker = 0 ;
} else {
+ + checker ;
}
2019-03-10 03:34:41 +08:00
WDT_HIT ( ) ;
if ( AT91C_BASE_SSC - > SSC_SR & AT91C_SSC_RXRDY ) {
sample = ( uint8_t ) AT91C_BASE_SSC - > SSC_RHR ;
// 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
}