mirror of
https://github.com/Proxmark/proxmark3.git
synced 2025-07-06 21:21:17 -07:00
Added client-side support for recording longer samples, fixed last (?) issues on device-side
This commit is contained in:
parent
7c676e7269
commit
f6d9fb173f
8 changed files with 260 additions and 106 deletions
|
@ -630,7 +630,7 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
||||||
switch(c->cmd) {
|
switch(c->cmd) {
|
||||||
#ifdef WITH_LF
|
#ifdef WITH_LF
|
||||||
case CMD_ACQUIRE_RAW_ADC_SAMPLES_125K:
|
case CMD_ACQUIRE_RAW_ADC_SAMPLES_125K:
|
||||||
AcquireRawAdcSamples125k(c->arg[0]);
|
AcquireRawAdcSamples125k(c->arg[0], c->arg[1], c->arg[2]);
|
||||||
cmd_send(CMD_ACK,0,0,0,0,0);
|
cmd_send(CMD_ACK,0,0,0,0,0);
|
||||||
break;
|
break;
|
||||||
case CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K:
|
case CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K:
|
||||||
|
@ -910,7 +910,7 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
||||||
cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K,i,len,0,((byte_t*)BigBuf)+c->arg[0]+i,len);
|
cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K,i,len,0,((byte_t*)BigBuf)+c->arg[0]+i,len);
|
||||||
}
|
}
|
||||||
// Trigger a finish downloading signal with an ACK frame
|
// Trigger a finish downloading signal with an ACK frame
|
||||||
cmd_send(CMD_ACK,0,0,0,0,0);
|
cmd_send(CMD_ACK,bits_per_sample,decimation,0,0,0);
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -81,7 +81,6 @@ int AvgAdc(int ch);
|
||||||
void ToSendStuffBit(int b);
|
void ToSendStuffBit(int b);
|
||||||
void ToSendReset(void);
|
void ToSendReset(void);
|
||||||
void ListenReaderField(int limit);
|
void ListenReaderField(int limit);
|
||||||
void AcquireRawAdcSamples125k(int at134khz);
|
|
||||||
void SnoopLFRawAdcSamples(int divisor, int trigger_threshold);
|
void SnoopLFRawAdcSamples(int divisor, int trigger_threshold);
|
||||||
void DoAcquisition125k(int trigger_threshold);
|
void DoAcquisition125k(int trigger_threshold);
|
||||||
extern int ToSendMax;
|
extern int ToSendMax;
|
||||||
|
@ -144,7 +143,11 @@ void SetAdcMuxFor(uint32_t whichGpio);
|
||||||
#define FPGA_HF_ISO14443A_READER_MOD (4<<0)
|
#define FPGA_HF_ISO14443A_READER_MOD (4<<0)
|
||||||
|
|
||||||
/// lfops.h
|
/// lfops.h
|
||||||
void AcquireRawAdcSamples125k(int divisor);
|
extern uint8_t decimation;
|
||||||
|
extern uint8_t bits_per_sample ;
|
||||||
|
extern bool averaging;
|
||||||
|
|
||||||
|
void AcquireRawAdcSamples125k(int divisor,int arg1, int arg2);
|
||||||
void ModThenAcquireRawAdcSamples125k(int delay_off,int period_0,int period_1,uint8_t *command);
|
void ModThenAcquireRawAdcSamples125k(int delay_off,int period_0,int period_1,uint8_t *command);
|
||||||
void ReadTItag(void);
|
void ReadTItag(void);
|
||||||
void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc);
|
void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc);
|
||||||
|
|
128
armsrc/lfops.c
128
armsrc/lfops.c
|
@ -16,47 +16,58 @@
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "lfdemod.h"
|
#include "lfdemod.h"
|
||||||
|
|
||||||
|
uint8_t decimation = 1;
|
||||||
|
uint8_t bits_per_sample = 8;
|
||||||
|
bool averaging = 1;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t * buffer;
|
uint8_t * buffer;
|
||||||
uint32_t numbits;
|
uint32_t numbits;
|
||||||
uint8_t position;
|
uint32_t position;
|
||||||
} BitstreamOut;
|
} BitstreamOut;
|
||||||
/**
|
/**
|
||||||
* @brief Pushes bit onto the stream
|
* @brief Pushes bit onto the stream
|
||||||
* @param stream
|
* @param stream
|
||||||
* @param bit
|
* @param bit
|
||||||
*/
|
*/
|
||||||
void pushBit( BitstreamOut* stream, bool bit)
|
void pushBit( BitstreamOut* stream, uint8_t bit)
|
||||||
{
|
{
|
||||||
int bytepos = stream->position >> 3; // divide by 8
|
int bytepos = stream->position >> 3; // divide by 8
|
||||||
int bitpos = stream->position & 7;
|
int bitpos = stream->position & 7;
|
||||||
*(stream->buffer+bytepos) |= (bit & 1) << (7 - bitpos);
|
*(stream->buffer+bytepos) |= (bit > 0) << (7 - bitpos);
|
||||||
stream->position++;
|
stream->position++;
|
||||||
stream->numbits++;
|
stream->numbits++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Does LF sample acquisition, this method implements decimation and quantization in order to
|
* 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.
|
* 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
|
* Uses the following global settings:
|
||||||
* every other sample, etc.
|
* - 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.
|
* - bits_per_sample - bits per sample. Max 8, min 1 bit per sample.
|
||||||
|
* - 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
|
* @param trigger_threshold - a threshold. The sampling won't commence until this threshold has been reached. Set
|
||||||
* to -1 to ignore threshold.
|
* 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
|
* @param silent - is true, now outputs are made. If false, dbprints the status
|
||||||
* value that will be used is the average value of the three samples.
|
|
||||||
* @return the number of bits occupied by the samples.
|
* @return the number of bits occupied by the samples.
|
||||||
*/
|
*/
|
||||||
uint8_t DoAcquisition(int decimation, int bits_per_sample, int trigger_threshold, bool averaging)
|
uint32_t DoAcquisition125k_internal(int trigger_threshold,bool silent)
|
||||||
{
|
{
|
||||||
//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;
|
uint8_t *dest = (uint8_t *)BigBuf;
|
||||||
int bufsize = BIGBUF_SIZE;
|
int bufsize = BIGBUF_SIZE;
|
||||||
memset(dest, 0, bufsize);
|
memset(dest, 0, bufsize);
|
||||||
|
|
||||||
if(bits_per_sample < 1) bits_per_sample = 1;
|
if(bits_per_sample < 1) bits_per_sample = 1;
|
||||||
if(bits_per_sample > 8) bits_per_sample = 8;
|
if(bits_per_sample > 8) bits_per_sample = 8;
|
||||||
|
|
||||||
|
if(decimation < 1) decimation = 1;
|
||||||
|
|
||||||
// Use a bit stream to handle the output
|
// Use a bit stream to handle the output
|
||||||
BitstreamOut data = { dest , 0, 0};
|
BitstreamOut data = { dest , 0, 0};
|
||||||
int sample_counter = 0;
|
int sample_counter = 0;
|
||||||
|
@ -66,7 +77,7 @@ uint8_t DoAcquisition(int decimation, int bits_per_sample, int trigger_threshold
|
||||||
uint32_t sample_total_numbers =0 ;
|
uint32_t sample_total_numbers =0 ;
|
||||||
uint32_t sample_total_saved =0 ;
|
uint32_t sample_total_saved =0 ;
|
||||||
|
|
||||||
for(;;) {
|
while(!BUTTON_PRESS()) {
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
|
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
|
||||||
AT91C_BASE_SSC->SSC_THR = 0x43;
|
AT91C_BASE_SSC->SSC_THR = 0x43;
|
||||||
|
@ -74,22 +85,37 @@ uint8_t DoAcquisition(int decimation, int bits_per_sample, int trigger_threshold
|
||||||
}
|
}
|
||||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
||||||
sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||||
|
LED_D_OFF();
|
||||||
if (trigger_threshold != -1 && sample < trigger_threshold)
|
if (trigger_threshold != -1 && sample < trigger_threshold)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
trigger_threshold = -1;
|
||||||
sample_total_numbers++;
|
sample_total_numbers++;
|
||||||
|
|
||||||
LED_D_OFF();
|
if(averaging)
|
||||||
trigger_threshold = -1;
|
{
|
||||||
sample_counter++;
|
|
||||||
sample_sum += sample;
|
sample_sum += sample;
|
||||||
|
}
|
||||||
//Check decimation
|
//Check decimation
|
||||||
|
if(decimation > 1)
|
||||||
|
{
|
||||||
|
sample_counter++;
|
||||||
if(sample_counter < decimation) continue;
|
if(sample_counter < decimation) continue;
|
||||||
//Averaging
|
|
||||||
if(averaging) sample = sample_sum / decimation;
|
|
||||||
|
|
||||||
sample_counter = 0;
|
sample_counter = 0;
|
||||||
|
}
|
||||||
|
//Averaging
|
||||||
|
if(averaging && decimation > 1) {
|
||||||
|
sample = sample_sum / decimation;
|
||||||
sample_sum =0;
|
sample_sum =0;
|
||||||
|
}
|
||||||
|
//Store the sample
|
||||||
sample_total_saved ++;
|
sample_total_saved ++;
|
||||||
|
if(bits_per_sample == 8){
|
||||||
|
dest[sample_total_saved-1] = sample;
|
||||||
|
data.numbits = sample_total_saved << 3;//Get the return value correct
|
||||||
|
if(sample_total_saved >= bufsize) break;
|
||||||
|
}
|
||||||
|
else{
|
||||||
pushBit(&data, sample & 0x80);
|
pushBit(&data, sample & 0x80);
|
||||||
if(bits_per_sample > 1) pushBit(&data, sample & 0x40);
|
if(bits_per_sample > 1) pushBit(&data, sample & 0x40);
|
||||||
if(bits_per_sample > 2) pushBit(&data, sample & 0x20);
|
if(bits_per_sample > 2) pushBit(&data, sample & 0x20);
|
||||||
|
@ -97,52 +123,20 @@ uint8_t DoAcquisition(int decimation, int bits_per_sample, int trigger_threshold
|
||||||
if(bits_per_sample > 4) pushBit(&data, sample & 0x08);
|
if(bits_per_sample > 4) pushBit(&data, sample & 0x08);
|
||||||
if(bits_per_sample > 5) pushBit(&data, sample & 0x04);
|
if(bits_per_sample > 5) pushBit(&data, sample & 0x04);
|
||||||
if(bits_per_sample > 6) pushBit(&data, sample & 0x02);
|
if(bits_per_sample > 6) pushBit(&data, sample & 0x02);
|
||||||
if(bits_per_sample > 7) pushBit(&data, sample & 0x01);
|
//Not needed, 8bps is covered above
|
||||||
|
//if(bits_per_sample > 7) pushBit(&data, sample & 0x01);
|
||||||
if((data.numbits >> 3) +1 >= bufsize) break;
|
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)
|
if(!silent)
|
||||||
{
|
{
|
||||||
|
Dbprintf("Done, saved %d out of %d seen samples at %d bits/sample",sample_total_saved, sample_total_numbers,bits_per_sample);
|
||||||
Dbprintf("buffer samples: %02x %02x %02x %02x %02x %02x %02x %02x ...",
|
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]);
|
dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
return data.numbits;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Perform sample aquisition.
|
* Perform sample aquisition.
|
||||||
|
@ -181,8 +175,24 @@ void LFSetupFPGAForADC(int divisor, bool lf_field)
|
||||||
/**
|
/**
|
||||||
* Initializes the FPGA, and acquires the samples.
|
* Initializes the FPGA, and acquires the samples.
|
||||||
**/
|
**/
|
||||||
void AcquireRawAdcSamples125k(int divisor)
|
void AcquireRawAdcSamples125k(int divisor,int arg1, int arg2)
|
||||||
{
|
{
|
||||||
|
if (arg1 != 0)
|
||||||
|
{
|
||||||
|
averaging = (arg1 & 0x80) != 0;
|
||||||
|
bits_per_sample = (arg1 & 0x0F);
|
||||||
|
}
|
||||||
|
if(arg2 != 0)
|
||||||
|
{
|
||||||
|
decimation = arg2;
|
||||||
|
}
|
||||||
|
|
||||||
|
Dbprintf("Sampling config: ");
|
||||||
|
Dbprintf(" divisor: %d ", divisor);
|
||||||
|
Dbprintf(" bps: %d ", bits_per_sample);
|
||||||
|
Dbprintf(" decimation: %d ", decimation);
|
||||||
|
Dbprintf(" averaging: %d ", averaging);
|
||||||
|
|
||||||
LFSetupFPGAForADC(divisor, true);
|
LFSetupFPGAForADC(divisor, true);
|
||||||
// Now call the acquisition routine
|
// Now call the acquisition routine
|
||||||
DoAcquisition125k_internal(-1,false);
|
DoAcquisition125k_internal(-1,false);
|
||||||
|
@ -1479,7 +1489,7 @@ int DemodPCF7931(uint8_t **outBlocks) {
|
||||||
int lmin=128, lmax=128;
|
int lmin=128, lmax=128;
|
||||||
uint8_t dir;
|
uint8_t dir;
|
||||||
|
|
||||||
AcquireRawAdcSamples125k(0);
|
AcquireRawAdcSamples125k(0,0,0);
|
||||||
|
|
||||||
lmin = 64;
|
lmin = 64;
|
||||||
lmax = 192;
|
lmax = 192;
|
||||||
|
|
|
@ -1051,6 +1051,29 @@ int CmdHpf(const char *Cmd)
|
||||||
RepaintGraphWindow();
|
RepaintGraphWindow();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
typedef struct {
|
||||||
|
uint8_t * buffer;
|
||||||
|
uint32_t numbits;
|
||||||
|
uint32_t position;
|
||||||
|
}BitstreamOut;
|
||||||
|
|
||||||
|
bool _headBit( BitstreamOut *stream)
|
||||||
|
{
|
||||||
|
int bytepos = stream->position >> 3; // divide by 8
|
||||||
|
int bitpos = (stream->position++) & 7; // mask out 00000111
|
||||||
|
return (*(stream->buffer + bytepos) >> (7-bitpos)) & 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t getByte(uint8_t bits_per_sample, BitstreamOut* b)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
uint8_t val = 0;
|
||||||
|
for(i =0 ; i < bits_per_sample; i++)
|
||||||
|
{
|
||||||
|
val |= (_headBit(b) << (7-i));
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
int CmdSamples(const char *Cmd)
|
int CmdSamples(const char *Cmd)
|
||||||
{
|
{
|
||||||
|
@ -1063,13 +1086,33 @@ int CmdSamples(const char *Cmd)
|
||||||
if (n > sizeof(got))
|
if (n > sizeof(got))
|
||||||
n = sizeof(got);
|
n = sizeof(got);
|
||||||
|
|
||||||
PrintAndLog("Reading %d samples from device memory\n", n);
|
PrintAndLog("Reading %d bytes from device memory\n", n);
|
||||||
GetFromBigBuf(got,n,0);
|
GetFromBigBuf(got,n,0);
|
||||||
WaitForResponse(CMD_ACK,NULL);
|
PrintAndLog("Data fetched");
|
||||||
|
UsbCommand response;
|
||||||
|
WaitForResponse(CMD_ACK, &response);
|
||||||
|
uint8_t bits_per_sample = response.arg[0];
|
||||||
|
PrintAndLog("Samples packed at %d bits per sample", bits_per_sample);
|
||||||
|
if(bits_per_sample < 8)
|
||||||
|
{
|
||||||
|
PrintAndLog("Unpacking...");
|
||||||
|
BitstreamOut bout = { got, bits_per_sample * n, 0};
|
||||||
|
int j =0;
|
||||||
|
for (j = 0; j * bits_per_sample < n * 8 && j < GraphTraceLen; j++) {
|
||||||
|
uint8_t sample = getByte(bits_per_sample, &bout);
|
||||||
|
GraphBuffer[j] = ((int) sample )- 128;
|
||||||
|
}
|
||||||
|
GraphTraceLen = j;
|
||||||
|
PrintAndLog("Unpacked %d samples" , j );
|
||||||
|
}else
|
||||||
|
{
|
||||||
for (int j = 0; j < n; j++) {
|
for (int j = 0; j < n; j++) {
|
||||||
GraphBuffer[j] = ((int)got[j]) - 128;
|
GraphBuffer[j] = ((int)got[j]) - 128;
|
||||||
}
|
}
|
||||||
GraphTraceLen = n;
|
GraphTraceLen = n;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
RepaintGraphWindow();
|
RepaintGraphWindow();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -356,21 +356,88 @@ int CmdIndalaClone(const char *Cmd)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CmdLFReadUsage()
|
||||||
|
{
|
||||||
|
PrintAndLog("Usage: lf read [H|<divisor>] [b <bps>] [d <decim>] [a 0|1]");
|
||||||
|
PrintAndLog("Options: ");
|
||||||
|
PrintAndLog(" h This help");
|
||||||
|
PrintAndLog(" H High frequency (134 KHz). Defaults to 125 KHz");
|
||||||
|
PrintAndLog(" <divisor> Manually set divisor. 88-> 134KHz, 95-> 125 Hz");
|
||||||
|
PrintAndLog(" b <bps> Sets resolution of bits per sample. Default (max): 8");
|
||||||
|
PrintAndLog(" d <decim> Sets decimation. A value of N saves only 1 in N samples. Default: 1");
|
||||||
|
PrintAndLog(" a [0|1] Averaging - if set, will average the stored sample value when decimating. Default: 1");
|
||||||
|
PrintAndLog("Examples:");
|
||||||
|
PrintAndLog(" lf read");
|
||||||
|
PrintAndLog(" Samples at 125KHz, 8bps.");
|
||||||
|
PrintAndLog(" lf read h b 4 d 3");
|
||||||
|
PrintAndLog(" Samples at 134KHz, averages three samples into one, stored with ");
|
||||||
|
PrintAndLog(" a resolution of 4 bits per sample.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
int CmdLFRead(const char *Cmd)
|
int CmdLFRead(const char *Cmd)
|
||||||
{
|
{
|
||||||
UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K};
|
uint8_t divisor = 95;//Frequency divisor
|
||||||
|
uint8_t bps = 8; // Bits per sample
|
||||||
|
uint8_t decimation = 1; //How many to keep
|
||||||
|
bool averaging = 1; // Should we use averaging when discarding samples?
|
||||||
|
bool errors = FALSE;
|
||||||
|
|
||||||
// 'h' means higher-low-frequency, 134 kHz
|
uint8_t cmdp =0;
|
||||||
if(*Cmd == 'h') {
|
if(param_getchar(Cmd, cmdp) == 'h')
|
||||||
c.arg[0] = 1;
|
{
|
||||||
} else if (*Cmd == '\0') {
|
return CmdLFReadUsage();
|
||||||
c.arg[0] = 0;
|
|
||||||
} else if (sscanf(Cmd, "%"lli, &c.arg[0]) != 1) {
|
|
||||||
PrintAndLog("Samples 1: 'lf read'");
|
|
||||||
PrintAndLog(" 2: 'lf read h'");
|
|
||||||
PrintAndLog(" 3: 'lf read <divisor>'");
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Divisor
|
||||||
|
if(param_getchar(Cmd, cmdp) == 'H') {
|
||||||
|
divisor = 88;
|
||||||
|
cmdp++;
|
||||||
|
}else if(param_isdec(Cmd,cmdp) )
|
||||||
|
{
|
||||||
|
errors |= param_getdec(Cmd,cmdp, &divisor);
|
||||||
|
}
|
||||||
|
//BPS
|
||||||
|
if(param_getchar(Cmd, cmdp) == 'b') {
|
||||||
|
errors |= param_getdec(Cmd,cmdp+1,&bps);
|
||||||
|
cmdp+=2;
|
||||||
|
}
|
||||||
|
//Decimation
|
||||||
|
if(param_getchar(Cmd, cmdp) == 'd')
|
||||||
|
{
|
||||||
|
errors |= param_getdec(Cmd,cmdp+1,&decimation);
|
||||||
|
cmdp+=2;
|
||||||
|
}
|
||||||
|
//Averaging
|
||||||
|
if(param_getchar(Cmd, cmdp) == 'a')
|
||||||
|
{
|
||||||
|
averaging = param_getchar(Cmd,cmdp+1) == '1';
|
||||||
|
cmdp+=2;
|
||||||
|
}
|
||||||
|
//Validations
|
||||||
|
if(errors)
|
||||||
|
{
|
||||||
|
return CmdLFReadUsage();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Bps is limited to 8, so fits in lower half of arg1
|
||||||
|
if(bps > 8) bps = 8;
|
||||||
|
|
||||||
|
//Feedback
|
||||||
|
PrintAndLog("Sampling config: ");
|
||||||
|
PrintAndLog(" divisor: %d ", divisor);
|
||||||
|
PrintAndLog(" bps: %d ", bps);
|
||||||
|
PrintAndLog(" decimation: %d ", decimation);
|
||||||
|
PrintAndLog(" averaging: %d ", averaging);
|
||||||
|
PrintAndLog("OBS, this is sticky on the device and affects all LF listening operations");
|
||||||
|
PrintAndLog("To reset, issue 'lf read'");
|
||||||
|
|
||||||
|
//And ship it to device
|
||||||
|
//Averaging is a flag on high-bit of arg[1]
|
||||||
|
UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K};
|
||||||
|
c.arg[0] = divisor;
|
||||||
|
c.arg[1] = bps | (averaging << 7) ;
|
||||||
|
c.arg[2] = decimation;
|
||||||
|
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
WaitForResponse(CMD_ACK,NULL);
|
WaitForResponse(CMD_ACK,NULL);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -20,7 +20,8 @@ int GetClock(const char *str, int peak, int verbose);
|
||||||
int GetNRZpskClock(const char *str, int peak, int verbose);
|
int GetNRZpskClock(const char *str, int peak, int verbose);
|
||||||
void setGraphBuf(uint8_t *buff, size_t size);
|
void setGraphBuf(uint8_t *buff, size_t size);
|
||||||
|
|
||||||
#define MAX_GRAPH_TRACE_LEN (1024*128)
|
// Max graph trace len: 40000 (bigbuf) * 8 (at 1 bit per sample)
|
||||||
|
#define MAX_GRAPH_TRACE_LEN (40000 * 8 )
|
||||||
extern int GraphBuffer[MAX_GRAPH_TRACE_LEN];
|
extern int GraphBuffer[MAX_GRAPH_TRACE_LEN];
|
||||||
extern int GraphTraceLen;
|
extern int GraphTraceLen;
|
||||||
|
|
||||||
|
|
|
@ -227,6 +227,34 @@ uint8_t param_get8(const char *line, int paramnum)
|
||||||
return param_get8ex(line, paramnum, 10, 0);
|
return param_get8ex(line, paramnum, 10, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reads a decimal integer
|
||||||
|
* @param line
|
||||||
|
* @param paramnum
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
uint8_t param_getdec(const char *line, int paramnum, uint8_t *destination)
|
||||||
|
{
|
||||||
|
uint8_t val = param_get8ex(line, paramnum, 10, 10);
|
||||||
|
(*destination) = val;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @brief Checks if param is decimal
|
||||||
|
* @param line
|
||||||
|
* @param paramnum
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
uint8_t param_isdec(const char *line, int paramnum)
|
||||||
|
{
|
||||||
|
int bg, en;
|
||||||
|
//TODO, check more thorougly
|
||||||
|
if (!param_getptr(line, &bg, &en, paramnum)) return 1;
|
||||||
|
// return strtoul(&line[bg], NULL, 10) & 0xff;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t param_get8ex(const char *line, int paramnum, int deflt, int base)
|
uint8_t param_get8ex(const char *line, int paramnum, int deflt, int base)
|
||||||
{
|
{
|
||||||
int bg, en;
|
int bg, en;
|
||||||
|
|
|
@ -49,6 +49,8 @@ uint8_t param_get8(const char *line, int paramnum);
|
||||||
uint8_t param_get8ex(const char *line, int paramnum, int deflt, int base);
|
uint8_t param_get8ex(const char *line, int paramnum, int deflt, int base);
|
||||||
uint32_t param_get32ex(const char *line, int paramnum, int deflt, int base);
|
uint32_t param_get32ex(const char *line, int paramnum, int deflt, int base);
|
||||||
uint64_t param_get64ex(const char *line, int paramnum, int deflt, int base);
|
uint64_t param_get64ex(const char *line, int paramnum, int deflt, int base);
|
||||||
|
uint8_t param_getdec(const char *line, int paramnum, uint8_t *destination);
|
||||||
|
uint8_t param_isdec(const char *line, int paramnum);
|
||||||
int param_gethex(const char *line, int paramnum, uint8_t * data, int hexcnt);
|
int param_gethex(const char *line, int paramnum, uint8_t * data, int hexcnt);
|
||||||
int param_getstr(const char *line, int paramnum, char * str);
|
int param_getstr(const char *line, int paramnum, char * str);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue