Real-time LF sampling mode on armsrc

This commit is contained in:
wh201906 2023-11-14 01:40:31 +08:00
commit b4cc7c02cd
No known key found for this signature in database
6 changed files with 166 additions and 5 deletions

View file

@ -852,8 +852,12 @@ static void PacketReceived(PacketCommandNG *packet) {
}
case CMD_LF_ACQ_RAW_ADC: {
lf_sample_payload_t *payload = (lf_sample_payload_t *)packet->data.asBytes;
uint32_t bits = SampleLF(payload->verbose, payload->samples, true);
reply_ng(CMD_LF_ACQ_RAW_ADC, PM3_SUCCESS, (uint8_t *)&bits, sizeof(bits));
if (payload->realtime) {
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;
}
case CMD_LF_MOD_THEN_ACQ_RAW_ADC: {
@ -877,9 +881,12 @@ static void PacketReceived(PacketCommandNG *packet) {
}
case CMD_LF_SNIFF_RAW_ADC: {
lf_sample_payload_t *payload = (lf_sample_payload_t *)packet->data.asBytes;
uint32_t bits = SniffLF(payload->verbose, payload->samples, true);
reply_ng(CMD_LF_SNIFF_RAW_ADC, PM3_SUCCESS, (uint8_t *)&bits, sizeof(bits));
if (payload->realtime) {
ReadLF_realtime(false);
} 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;
}
case CMD_LF_HID_WATCH: {

View file

@ -27,6 +27,7 @@
#include "lfdemod.h"
#include "string.h" // memset
#include "appmain.h" // print stack
#include "usb_cdc.h" // real-time sampling
/*
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);
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.
* @return number of bits sampled

View file

@ -51,6 +51,16 @@ void doT55x7Acquisition(size_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.
* @return number of bits sampled

View file

@ -305,3 +305,11 @@ bool data_available(void) {
return usb_poll_validate_length();
#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
}

View file

@ -101,5 +101,6 @@ void SpinUp(uint32_t speed);
int BUTTON_CLICKED(int ms);
int BUTTON_HELD(int ms);
bool data_available(void);
bool data_available_fast(void);
#endif

View file

@ -196,4 +196,18 @@ extern bool g_tearoff_enabled;
#define CLEAR_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