mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 21:03:48 -07:00
Real-time LF sampling mode on armsrc
This commit is contained in:
parent
e1dc17df1a
commit
b4cc7c02cd
6 changed files with 166 additions and 5 deletions
|
@ -852,8 +852,12 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
}
|
}
|
||||||
case CMD_LF_ACQ_RAW_ADC: {
|
case CMD_LF_ACQ_RAW_ADC: {
|
||||||
lf_sample_payload_t *payload = (lf_sample_payload_t *)packet->data.asBytes;
|
lf_sample_payload_t *payload = (lf_sample_payload_t *)packet->data.asBytes;
|
||||||
uint32_t bits = SampleLF(payload->verbose, payload->samples, true);
|
if (payload->realtime) {
|
||||||
reply_ng(CMD_LF_ACQ_RAW_ADC, PM3_SUCCESS, (uint8_t *)&bits, sizeof(bits));
|
ReadLF_realtime(true);
|
||||||
|
} else {
|
||||||
|
uint32_t bits = SampleLF(payload->verbose, payload->samples, true);
|
||||||
|
reply_ng(CMD_LF_ACQ_RAW_ADC, PM3_SUCCESS, (uint8_t *)&bits, sizeof(bits));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_LF_MOD_THEN_ACQ_RAW_ADC: {
|
case CMD_LF_MOD_THEN_ACQ_RAW_ADC: {
|
||||||
|
@ -877,9 +881,12 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
}
|
}
|
||||||
case CMD_LF_SNIFF_RAW_ADC: {
|
case CMD_LF_SNIFF_RAW_ADC: {
|
||||||
lf_sample_payload_t *payload = (lf_sample_payload_t *)packet->data.asBytes;
|
lf_sample_payload_t *payload = (lf_sample_payload_t *)packet->data.asBytes;
|
||||||
|
if (payload->realtime) {
|
||||||
uint32_t bits = SniffLF(payload->verbose, payload->samples, true);
|
ReadLF_realtime(false);
|
||||||
reply_ng(CMD_LF_SNIFF_RAW_ADC, PM3_SUCCESS, (uint8_t *)&bits, sizeof(bits));
|
} else {
|
||||||
|
uint32_t bits = SniffLF(payload->verbose, payload->samples, true);
|
||||||
|
reply_ng(CMD_LF_SNIFF_RAW_ADC, PM3_SUCCESS, (uint8_t *)&bits, sizeof(bits));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_LF_HID_WATCH: {
|
case CMD_LF_HID_WATCH: {
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "lfdemod.h"
|
#include "lfdemod.h"
|
||||||
#include "string.h" // memset
|
#include "string.h" // memset
|
||||||
#include "appmain.h" // print stack
|
#include "appmain.h" // print stack
|
||||||
|
#include "usb_cdc.h" // real-time sampling
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Default LF config is set to:
|
Default LF config is set to:
|
||||||
|
@ -424,6 +425,126 @@ uint32_t SampleLF(bool verbose, uint32_t sample_size, bool ledcontrol) {
|
||||||
BigBuf_Clear_ext(false);
|
BigBuf_Clear_ext(false);
|
||||||
return ReadLF(true, verbose, sample_size, ledcontrol);
|
return ReadLF(true, verbose, sample_size, ledcontrol);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do LF sampling and send samples to the USB
|
||||||
|
*
|
||||||
|
* Uses parameters in config. Only bits_per_sample = 8 is working now
|
||||||
|
*
|
||||||
|
* @param reader_field - true for reading tags, false for sniffing
|
||||||
|
* @return sampling result
|
||||||
|
**/
|
||||||
|
int ReadLF_realtime(bool reader_field) {
|
||||||
|
// parameters from config and constants
|
||||||
|
const uint8_t bits_per_sample = config.bits_per_sample;
|
||||||
|
const int16_t trigger_threshold = config.trigger_threshold;
|
||||||
|
int32_t samples_to_skip = config.samples_to_skip;
|
||||||
|
const uint8_t decimation = config.decimation;
|
||||||
|
|
||||||
|
uint32_t sample_size = 64;
|
||||||
|
const int8_t size_threshold_table[9] = {0, 64, 64, 60, 64, 60, 60, 56, 64};
|
||||||
|
const int8_t size_threshold = size_threshold_table[bits_per_sample];
|
||||||
|
|
||||||
|
// DoAcquisition() start
|
||||||
|
uint8_t last_byte = 0;
|
||||||
|
uint8_t curr_byte = 0;
|
||||||
|
int return_value = PM3_SUCCESS;
|
||||||
|
|
||||||
|
initSampleBuffer(&sample_size); // sample size in bytes
|
||||||
|
if (sample_size != 64) {
|
||||||
|
return PM3_EFAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
sample_size <<= 3; // sample size in bits
|
||||||
|
sample_size /= bits_per_sample; // sample count
|
||||||
|
|
||||||
|
bool trigger_hit = false;
|
||||||
|
int16_t checked = 0;
|
||||||
|
|
||||||
|
return_value = async_usb_write_start();
|
||||||
|
if (return_value != PM3_SUCCESS) {
|
||||||
|
return return_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
BigBuf_Clear_ext(false);
|
||||||
|
LFSetupFPGAForADC(config.divisor, reader_field);
|
||||||
|
|
||||||
|
while (BUTTON_PRESS() == false) {
|
||||||
|
// only every 4000th times, in order to save time when collecting samples.
|
||||||
|
// interruptible only when logging not yet triggered
|
||||||
|
if (unlikely(trigger_hit == false && (checked >= 4000))) {
|
||||||
|
if (data_available()) {
|
||||||
|
checked = -1;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
checked = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++checked;
|
||||||
|
|
||||||
|
WDT_HIT();
|
||||||
|
|
||||||
|
if ((AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY)) {
|
||||||
|
LED_D_ON();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
||||||
|
volatile uint8_t sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||||
|
|
||||||
|
// (RDV4) Test point 8 (TP8) can be used to trigger oscilloscope
|
||||||
|
LED_D_OFF();
|
||||||
|
|
||||||
|
// threshold either high or low values 128 = center 0. if trigger = 178
|
||||||
|
if (unlikely(trigger_hit == false)) {
|
||||||
|
if ((trigger_threshold > 0) && (sample < (trigger_threshold + 128)) && (sample > (128 - trigger_threshold))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
trigger_hit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unlikely(samples_to_skip > 0)) {
|
||||||
|
samples_to_skip--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
logSample(sample, decimation, bits_per_sample, false);
|
||||||
|
|
||||||
|
// write to USB FIFO if byte changed
|
||||||
|
curr_byte = data.numbits >> 3;
|
||||||
|
if (curr_byte > last_byte) {
|
||||||
|
async_usb_write_pushByte(data.buffer[last_byte]);
|
||||||
|
}
|
||||||
|
last_byte = curr_byte;
|
||||||
|
|
||||||
|
if (samples.total_saved == size_threshold) {
|
||||||
|
// request usb transmission and change FIFO bank
|
||||||
|
if (async_usb_write_requestWrite() == false) {
|
||||||
|
return_value = PM3_EIO;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// reset sample
|
||||||
|
last_byte = 0;
|
||||||
|
data.numbits = 0;
|
||||||
|
samples.counter = size_threshold;
|
||||||
|
samples.total_saved = 0;
|
||||||
|
|
||||||
|
} else if (samples.total_saved == 1) {
|
||||||
|
// check if there is any data from client
|
||||||
|
if (data_available_fast()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LED_D_OFF();
|
||||||
|
return_value = async_usb_write_stop();
|
||||||
|
|
||||||
|
// DoAcquisition() end
|
||||||
|
StopTicks();
|
||||||
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
|
return return_value;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Initializes the FPGA for sniffer-mode (field off), and acquires the samples.
|
* Initializes the FPGA for sniffer-mode (field off), and acquires the samples.
|
||||||
* @return number of bits sampled
|
* @return number of bits sampled
|
||||||
|
|
|
@ -51,6 +51,16 @@ void doT55x7Acquisition(size_t sample_size, bool ledcontrol);
|
||||||
**/
|
**/
|
||||||
uint32_t SampleLF(bool verbose, uint32_t sample_size, bool ledcontrol);
|
uint32_t SampleLF(bool verbose, uint32_t sample_size, bool ledcontrol);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do LF sampling and send samples to the USB
|
||||||
|
*
|
||||||
|
* Uses parameters in config. Only bits_per_sample = 8 is working now
|
||||||
|
*
|
||||||
|
* @param reader_field - true for reading tags, false for sniffing
|
||||||
|
* @return sampling result
|
||||||
|
**/
|
||||||
|
int ReadLF_realtime(bool reader_field);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the FPGA for sniff-mode (field off), and acquires the samples.
|
* Initializes the FPGA for sniff-mode (field off), and acquires the samples.
|
||||||
* @return number of bits sampled
|
* @return number of bits sampled
|
||||||
|
|
|
@ -305,3 +305,11 @@ bool data_available(void) {
|
||||||
return usb_poll_validate_length();
|
return usb_poll_validate_length();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool data_available_fast(void) {
|
||||||
|
#ifdef WITH_FPC_USART_HOST
|
||||||
|
return usb_available_length() || (usart_rxdata_available() > 0);
|
||||||
|
#else
|
||||||
|
return usb_available_length();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
|
@ -101,5 +101,6 @@ void SpinUp(uint32_t speed);
|
||||||
int BUTTON_CLICKED(int ms);
|
int BUTTON_CLICKED(int ms);
|
||||||
int BUTTON_HELD(int ms);
|
int BUTTON_HELD(int ms);
|
||||||
bool data_available(void);
|
bool data_available(void);
|
||||||
|
bool data_available_fast(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -196,4 +196,18 @@ extern bool g_tearoff_enabled;
|
||||||
#define CLEAR_BIT(data, i) *(data + (i / 8)) &= ~(1 << (7 - (i % 8)))
|
#define CLEAR_BIT(data, i) *(data + (i / 8)) &= ~(1 << (7 - (i % 8)))
|
||||||
#define FLIP_BIT(data, i) *(data + (i / 8)) ^= (1 << (7 - (i % 8)))
|
#define FLIP_BIT(data, i) *(data + (i / 8)) ^= (1 << (7 - (i % 8)))
|
||||||
|
|
||||||
|
// GCC extension
|
||||||
|
// from client/deps/tinycbor/compilersupport_p.h
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#ifndef likely
|
||||||
|
# define likely(x) __builtin_expect(!!(x), 1)
|
||||||
|
#endif
|
||||||
|
#ifndef unlikely
|
||||||
|
# define unlikely(x) __builtin_expect(!!(x), 0)
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
# define likely(x) (x)
|
||||||
|
# define unlikely(x) (x)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue