Add support for trigger threshold

This commit is contained in:
wh201906 2023-11-14 13:12:35 +08:00
commit 835b7a9150
No known key found for this signature in database
2 changed files with 44 additions and 17 deletions

View file

@ -66,8 +66,6 @@
#include "crc.h"
#include "pm3_cmd.h" // for LF_CMDREAD_MAX_EXTRA_SYMBOLS
static bool gs_lf_threshold_set = false;
static int CmdHelp(const char *Cmd);
// Informative user function.
@ -646,7 +644,6 @@ int CmdLFConfig(const char *Cmd) {
config.divisor = LF_DIVISOR_125;
config.samples_to_skip = 0;
config.trigger_threshold = 0;
gs_lf_threshold_set = false;
}
if (use_125)
@ -691,7 +688,6 @@ int CmdLFConfig(const char *Cmd) {
if (trigg > -1) {
config.trigger_threshold = trigg;
gs_lf_threshold_set = (config.trigger_threshold > 0);
}
config.samples_to_skip = skip;
@ -713,6 +709,7 @@ static int lf_read_internal(bool realtime, bool verbose, uint64_t samples) {
}
clearCommandBuffer();
const uint8_t bits_per_sample = current_config.bits_per_sample;
const bool is_trigger_threshold_set = (current_config.trigger_threshold > 0);
if (realtime) {
uint8_t *realtimeBuf = calloc(samples, sizeof(uint8_t));
@ -721,16 +718,27 @@ static int lf_read_internal(bool realtime, bool verbose, uint64_t samples) {
sample_bytes = (sample_bytes / 8) + (sample_bytes % 8 != 0);
SendCommandNG(CMD_LF_ACQ_RAW_ADC, (uint8_t *)&payload, sizeof(payload));
if (is_trigger_threshold_set) {
size_t first_receive_len = 32; // larger than the response of CMD_WTX
// wait until a bunch of data arrives
first_receive_len = WaitForRawDataTimeout(realtimeBuf, first_receive_len, -1, false);
sample_bytes = WaitForRawDataTimeout(realtimeBuf + first_receive_len, sample_bytes - first_receive_len, 1000 + FPGA_LOAD_WAIT_TIME, true);
sample_bytes += first_receive_len;
} else {
sample_bytes = WaitForRawDataTimeout(realtimeBuf, sample_bytes, 1000 + FPGA_LOAD_WAIT_TIME, true);
}
samples = sample_bytes * 8 / bits_per_sample;
PrintAndLogEx(INFO, "Done: %" PRIu64 " samples (%zu bytes)", samples, sample_bytes);
if (samples != 0) {
getSamplesFromBufEx(realtimeBuf, samples, bits_per_sample, verbose);
}
free(realtimeBuf);
} else {
payload.samples = (samples > MAX_LF_SAMPLES) ? MAX_LF_SAMPLES : samples;
SendCommandNG(CMD_LF_ACQ_RAW_ADC, (uint8_t *)&payload, sizeof(payload));
PacketResponseNG resp;
if (gs_lf_threshold_set) {
if (is_trigger_threshold_set) {
WaitForResponse(CMD_LF_ACQ_RAW_ADC, &resp);
} else {
if (!WaitForResponseTimeout(CMD_LF_ACQ_RAW_ADC, &resp, 2500)) {
@ -809,6 +817,7 @@ int lf_sniff(bool realtime, bool verbose, uint64_t samples) {
}
clearCommandBuffer();
const uint8_t bits_per_sample = current_config.bits_per_sample;
const bool is_trigger_threshold_set = (current_config.trigger_threshold > 0);
if (realtime) {
uint8_t *realtimeBuf = calloc(samples, sizeof(uint8_t));
@ -817,16 +826,27 @@ int lf_sniff(bool realtime, bool verbose, uint64_t samples) {
sample_bytes = (sample_bytes / 8) + (sample_bytes % 8 != 0);
SendCommandNG(CMD_LF_SNIFF_RAW_ADC, (uint8_t *)&payload, sizeof(payload));
if (is_trigger_threshold_set) {
size_t first_receive_len = 32; // larger than the response of CMD_WTX
// wait until a bunch of data arrives
first_receive_len = WaitForRawDataTimeout(realtimeBuf, first_receive_len, -1, false);
sample_bytes = WaitForRawDataTimeout(realtimeBuf + first_receive_len, sample_bytes - first_receive_len, 1000 + FPGA_LOAD_WAIT_TIME, true);
sample_bytes += first_receive_len;
} else {
sample_bytes = WaitForRawDataTimeout(realtimeBuf, sample_bytes, 1000 + FPGA_LOAD_WAIT_TIME, true);
}
samples = sample_bytes * 8 / bits_per_sample;
PrintAndLogEx(INFO, "Done: %" PRIu64 " samples (%zu bytes)", samples, sample_bytes);
if (samples != 0) {
getSamplesFromBufEx(realtimeBuf, samples, bits_per_sample, verbose);
}
free(realtimeBuf);
} else {
payload.samples = (samples > MAX_LF_SAMPLES) ? MAX_LF_SAMPLES : samples;
SendCommandNG(CMD_LF_SNIFF_RAW_ADC, (uint8_t *)&payload, sizeof(payload));
PacketResponseNG resp;
if (gs_lf_threshold_set) {
if (is_trigger_threshold_set) {
WaitForResponse(CMD_LF_SNIFF_RAW_ADC, &resp);
} else {
if (WaitForResponseTimeout(CMD_LF_SNIFF_RAW_ADC, &resp, 2500) == false) {

View file

@ -402,10 +402,6 @@ __attribute__((force_align_arg_pointer))
uint8_t dummyData[64];
uint32_t dummyLen;
uart_receive(sp, dummyData, sizeof(dummyData), &dummyLen);
// set the buffer as undefined
// comm_raw_data == NULL is used in SetCommunicationReceiveMode()
__atomic_store_n(&comm_raw_data, NULL, __ATOMIC_SEQ_CST);
}
} else {
if (is_receiving_raw_last) {
@ -856,6 +852,12 @@ size_t WaitForRawDataTimeout(uint8_t *buffer, size_t len, size_t ms_timeout, boo
// send anything to stop the transfer
PrintAndLogEx(INFO, "Stopping");
SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
// for ms_timeout == -1, pos < len might always be true
// so user need a spectial way to break this loop
if (ms_timeout == (size_t) - 1) {
break;
}
}
pos = __atomic_load_n(&comm_raw_pos, __ATOMIC_SEQ_CST);
@ -863,7 +865,8 @@ size_t WaitForRawDataTimeout(uint8_t *buffer, size_t len, size_t ms_timeout, boo
// check the timeout if pos is not updated
if (last_pos == pos) {
uint64_t tmp_clk = __atomic_load_n(&timeout_start_time, __ATOMIC_SEQ_CST);
if ((msclock() - tmp_clk > ms_timeout)) {
// if ms_timeout == -1, the loop can only be breaked by pressing Enter or receiving enough data
if ((ms_timeout != (size_t) - 1) && (msclock() - tmp_clk > ms_timeout)) {
break;
}
} else {
@ -877,13 +880,17 @@ size_t WaitForRawDataTimeout(uint8_t *buffer, size_t len, size_t ms_timeout, boo
last_pos = pos;
msleep(10);
}
if (pos == len) {
if (pos == len && (ms_timeout != (size_t) - 1)) {
// if ms_timeout != -1, when the desired data is received, tell the arm side
// to stop the current process, and wait for some time to make sure the process
// has been stopped
// if ms_timeout == -1, the user might not want to break the existing process
// on the arm side
SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
msleep(ms_timeout);
}
SetCommunicationReceiveMode(false);
pos = __atomic_load_n(&comm_raw_pos, __ATOMIC_SEQ_CST);
PrintAndLogEx(INFO, "Done: [%zu/%zu]", pos, len);
return pos;
}