mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-06-11 19:33:30 -07:00
switch to scalable timebase for digital reader to prevent overflows
added yielding to emulation loop
This commit is contained in:
@@ -632,6 +632,7 @@ void nfc_worker_emulate_nfcv(NfcWorker* nfc_worker) {
|
||||
nfc_worker->callback(NfcWorkerEventSuccess, nfc_worker->context);
|
||||
}
|
||||
}
|
||||
furi_delay_ms(0);
|
||||
}
|
||||
nfcv_emu_deinit();
|
||||
}
|
||||
|
||||
+21
-17
@@ -150,10 +150,6 @@ bool nfcv_read_card(
|
||||
|
||||
/* emulation part */
|
||||
|
||||
#define F_SC 13560000 /* MHz */
|
||||
#define PULSE_DURATION_PS (128*1000000000000/F_SC) /* ps */
|
||||
|
||||
|
||||
PulseReader *reader_signal = NULL;
|
||||
|
||||
DigitalSignal* nfcv_resp_pulse_32 = NULL;
|
||||
@@ -372,9 +368,9 @@ void nfcv_emu_handle_packet(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data, ui
|
||||
uint8_t *address = &payload[address_offset];
|
||||
|
||||
if(addressed && nfcv_uidcmp(address, nfc_data->uid)) {
|
||||
printf("addressed packet, but not for us:\r\n");
|
||||
printf(" destination: %02X%02X%02X%02X%02X%02X%02X%02X\r\n", address[7], address[6], address[5], address[4], address[3], address[2], address[1], address[0]);
|
||||
printf(" our UID: %02X%02X%02X%02X%02X%02X%02X%02X\r\n", nfc_data->uid[0], nfc_data->uid[1], nfc_data->uid[2], nfc_data->uid[3], nfc_data->uid[4], nfc_data->uid[5], nfc_data->uid[6], nfc_data->uid[7]);
|
||||
FURI_LOG_D(TAG, "addressed command 0x%02X, but not for us:", command);
|
||||
FURI_LOG_D(TAG, " dest: %02X%02X%02X%02X%02X%02X%02X%02X", address[7], address[6], address[5], address[4], address[3], address[2], address[1], address[0]);
|
||||
FURI_LOG_D(TAG, " our UID: %02X%02X%02X%02X%02X%02X%02X%02X", nfc_data->uid[0], nfc_data->uid[1], nfc_data->uid[2], nfc_data->uid[3], nfc_data->uid[4], nfc_data->uid[5], nfc_data->uid[6], nfc_data->uid[7]);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -400,7 +396,7 @@ void nfcv_emu_handle_packet(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data, ui
|
||||
case ISO15693_INVENTORY:
|
||||
{
|
||||
response_buffer[0] = ISO15693_NOERROR;
|
||||
response_buffer[1] = nfcv_data->dsfid; /* DSFID */
|
||||
response_buffer[1] = nfcv_data->dsfid;
|
||||
nfcv_uidcpy(&response_buffer[2], nfc_data->uid);
|
||||
|
||||
nfcv_emu_send(response_buffer, 10);
|
||||
@@ -491,15 +487,18 @@ void nfcv_emu_handle_packet(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data, ui
|
||||
|
||||
case ISO15693_CMD_NXP_GET_RANDOM_NUMBER:
|
||||
{
|
||||
nfcv_data->sub_data.slix_l.rand[0] = 0x00;
|
||||
nfcv_data->sub_data.slix_l.rand[1] = 0x00;
|
||||
nfcv_data->sub_data.slix_l.rand[0] = furi_hal_random_get();
|
||||
nfcv_data->sub_data.slix_l.rand[1] = furi_hal_random_get();
|
||||
|
||||
response_buffer[0] = ISO15693_NOERROR;
|
||||
response_buffer[1] = nfcv_data->sub_data.slix_l.rand[1];
|
||||
response_buffer[2] = nfcv_data->sub_data.slix_l.rand[0];
|
||||
|
||||
nfcv_emu_send(response_buffer, 3);
|
||||
snprintf(nfcv_data->last_command, sizeof(nfcv_data->last_command), "GET_RANDOM_NUMBER");
|
||||
snprintf(nfcv_data->last_command, sizeof(nfcv_data->last_command),
|
||||
"GET_RANDOM_NUMBER -> 0x%02X%02X",
|
||||
nfcv_data->sub_data.slix_l.rand[0],
|
||||
nfcv_data->sub_data.slix_l.rand[1]);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -535,14 +534,15 @@ void nfcv_emu_handle_packet(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data, ui
|
||||
if(pass_expect == pass_received) {
|
||||
status = ISO15693_NOERROR;
|
||||
nfcv_data->sub_data.slix_l.privacy = false;
|
||||
FURI_LOG_D(TAG, "SET_PASSWORD #%d received correct password 0x%08lX", password_id, pass_received);
|
||||
} else {
|
||||
FURI_LOG_D(TAG, "Password #%d mismatch. Expected 0x%08lX, got 0x%08lX", password_id, pass_expect, pass_received);
|
||||
FURI_LOG_D(TAG, "SET_PASSWORD #%d mismatch. Expected password 0x%08lX, got 0x%08lX", password_id, pass_expect, pass_received);
|
||||
}
|
||||
|
||||
response_buffer[0] = status;
|
||||
|
||||
nfcv_emu_send(response_buffer, 1);
|
||||
snprintf(nfcv_data->last_command, sizeof(nfcv_data->last_command), "SET_PASSWORD #%02X", password_id);
|
||||
snprintf(nfcv_data->last_command, sizeof(nfcv_data->last_command), "SET_PASSWORD #%02X %s", password_id, (status == ISO15693_NOERROR) ? "SUCCESS" : "FAIL");
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -562,6 +562,10 @@ void nfcv_emu_handle_packet(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data, ui
|
||||
snprintf(nfcv_data->last_command, sizeof(nfcv_data->last_command), "unsupported: %02X", command);
|
||||
break;
|
||||
}
|
||||
|
||||
if(strlen(nfcv_data->last_command) > 0) {
|
||||
FURI_LOG_D(TAG, "Received command %s", nfcv_data->last_command);
|
||||
}
|
||||
}
|
||||
|
||||
void nfcv_emu_init(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data) {
|
||||
@@ -586,10 +590,10 @@ void nfcv_emu_init(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data) {
|
||||
|
||||
/* allocate a 512 edge buffer, more than enough */
|
||||
reader_signal = pulse_reader_alloc(&gpio_spi_r_miso, 512);
|
||||
/* timebase shall be 1ps */
|
||||
pulse_reader_set_timebase(reader_signal, PulseReaderUnitPicosecond);
|
||||
/* timebase shall be 1 ns */
|
||||
pulse_reader_set_timebase(reader_signal, PulseReaderUnitNanosecond);
|
||||
/* and configure to already calculate the number of bits */
|
||||
pulse_reader_set_bittime(reader_signal, PULSE_DURATION_PS);
|
||||
pulse_reader_set_bittime(reader_signal, PULSE_DURATION_NS);
|
||||
pulse_reader_start(reader_signal);
|
||||
}
|
||||
|
||||
@@ -651,7 +655,7 @@ bool nfcv_emu_loop(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data, uint32_t ti
|
||||
periods_previous = 2;
|
||||
wait_for_pulse = true;
|
||||
} else {
|
||||
//snprintf(reset_reason, sizeof(reset_reason), "SOF: Expected 4/6 periods, got %lu", periods);
|
||||
snprintf(reset_reason, sizeof(reset_reason), "SOF: Expected 4/6 periods, got %lu", periods);
|
||||
frame_state = NFCV_FRAME_STATE_SOF1;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -9,16 +9,20 @@
|
||||
#include <furi_hal_nfc.h>
|
||||
|
||||
|
||||
#define NFCV_FC (13560000.0f)
|
||||
|
||||
|
||||
#define NFCV_FC (13560000.0f) /* MHz */
|
||||
#define NFCV_RESP_SUBC1_PULSE_32 (1.0f / (NFCV_FC/32) / 2.0f) /* 1.1799 µs */
|
||||
#define NFCV_RESP_SUBC1_UNMOD_256 (256.0f / NFCV_FC) /* 18.8791 µs */
|
||||
|
||||
#define PULSE_DURATION_NS (128.0f * 1000000000.0f / NFCV_FC) /* ns */
|
||||
|
||||
#define DIGITAL_SIGNAL_UNIT_S (100000000000.0f)
|
||||
#define DIGITAL_SIGNAL_UNIT_US (100000.0f)
|
||||
|
||||
#define NFCV_TOTAL_BLOCKS_MAX 256
|
||||
#define NFCV_BLOCK_SIZE 4
|
||||
#define NFCV_MAX_DUMP_SIZE (NFCV_BLOCK_SIZE*NFCV_TOTAL_BLOCKS_MAX)
|
||||
#define NFCV_TOTAL_BLOCKS_MAX 256
|
||||
#define NFCV_BLOCK_SIZE 4
|
||||
#define NFCV_MAX_DUMP_SIZE (NFCV_BLOCK_SIZE*NFCV_TOTAL_BLOCKS_MAX)
|
||||
|
||||
|
||||
#define NFCV_FRAME_STATE_SOF1 0
|
||||
|
||||
@@ -33,8 +33,8 @@
|
||||
|
||||
|
||||
PulseReader* pulse_reader_alloc(const GpioPin* gpio, uint32_t size) {
|
||||
PulseReader* signal = malloc(sizeof(PulseReader));
|
||||
|
||||
PulseReader* signal = malloc(sizeof(PulseReader));
|
||||
signal->timer_buffer = malloc(size * sizeof(uint32_t));
|
||||
signal->dma_channel = LL_DMA_CHANNEL_4;
|
||||
signal->gpio = gpio;
|
||||
@@ -42,14 +42,31 @@ PulseReader* pulse_reader_alloc(const GpioPin* gpio, uint32_t size) {
|
||||
signal->timer_value = 0;
|
||||
signal->pos = 0;
|
||||
|
||||
signal->unit = PulseReaderUnitPicosecond;
|
||||
signal->bit_time = 1;
|
||||
pulse_reader_set_timebase(signal, PulseReaderUnit64MHz);
|
||||
pulse_reader_set_bittime(signal, 1);
|
||||
|
||||
return signal;
|
||||
}
|
||||
|
||||
void pulse_reader_set_timebase(PulseReader* signal, PulseReaderUnit unit) {
|
||||
signal->unit = unit;
|
||||
switch(unit) {
|
||||
case PulseReaderUnit64MHz:
|
||||
signal->unit_multiplier = 1;
|
||||
signal->unit_divider = 1;
|
||||
break;
|
||||
case PulseReaderUnitPicosecond:
|
||||
signal->unit_multiplier = 15625;
|
||||
signal->unit_divider = 1;
|
||||
break;
|
||||
case PulseReaderUnitNanosecond:
|
||||
signal->unit_multiplier = 15625;
|
||||
signal->unit_divider = 1000;
|
||||
break;
|
||||
case PulseReaderUnitMicrosecond:
|
||||
signal->unit_multiplier = 15625;
|
||||
signal->unit_divider = 1000000;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void pulse_reader_set_bittime(PulseReader* signal, uint32_t bit_time) {
|
||||
@@ -127,7 +144,7 @@ void pulse_reader_start(PulseReader* signal) {
|
||||
uint32_t pulse_reader_receive(PulseReader* signal, int timeout_us) {
|
||||
|
||||
uint32_t start_time = DWT->CYCCNT;
|
||||
uint32_t timeout_ticks = timeout_us * (F_CPU/1000000);
|
||||
uint32_t timeout_ticks = timeout_us * (F_TIM2/1000000);
|
||||
|
||||
do {
|
||||
/* get the DMA's next write position by reading "remaining length" register */
|
||||
@@ -142,10 +159,21 @@ uint32_t pulse_reader_receive(PulseReader* signal, int timeout_us) {
|
||||
signal->pos++;
|
||||
signal->pos %= signal->size;
|
||||
|
||||
uint32_t delta_unit = delta * signal->unit;
|
||||
uint32_t bits = (delta_unit + signal->bit_time / 2) / signal->bit_time;
|
||||
uint32_t delta_unit = 0;
|
||||
|
||||
return bits;
|
||||
/* probably larger values, so choose a wider data type */
|
||||
if(signal->unit_divider > 1) {
|
||||
delta_unit = (uint32_t)((uint64_t)delta * (uint64_t)signal->unit_multiplier / signal->unit_divider);
|
||||
} else {
|
||||
delta_unit = delta * signal->unit_multiplier;
|
||||
}
|
||||
|
||||
/* if to be scaled to bit times, save a few instructions. should be faster */
|
||||
if(signal->bit_time > 1) {
|
||||
return (delta_unit + signal->bit_time / 2) / signal->bit_time;
|
||||
}
|
||||
|
||||
return delta_unit;
|
||||
}
|
||||
|
||||
/* check for timeout */
|
||||
|
||||
@@ -11,14 +11,16 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#define PULSE_READER_NO_EDGE 0xFFFFFFFFUL
|
||||
#define F_CPU 64000000UL
|
||||
#define F_TIM2 64000000UL
|
||||
|
||||
/**
|
||||
* unit of the edge durations to return
|
||||
*/
|
||||
typedef enum {
|
||||
PulseReaderUnit64MHz = 1,
|
||||
PulseReaderUnitPicosecond = 15625
|
||||
PulseReaderUnit64MHz,
|
||||
PulseReaderUnitPicosecond,
|
||||
PulseReaderUnitNanosecond,
|
||||
PulseReaderUnitMicrosecond,
|
||||
} PulseReaderUnit;
|
||||
|
||||
|
||||
@@ -28,7 +30,8 @@ typedef struct {
|
||||
uint32_t size;
|
||||
uint32_t pos;
|
||||
uint32_t timer_value;
|
||||
PulseReaderUnit unit;
|
||||
uint32_t unit_multiplier;
|
||||
uint32_t unit_divider;
|
||||
uint32_t bit_time;
|
||||
uint32_t dma_channel;
|
||||
const GpioPin* gpio;
|
||||
|
||||
Reference in New Issue
Block a user