diff --git a/lib/nfc/nfc_worker.c b/lib/nfc/nfc_worker.c index eb7329f05..1538b2177 100644 --- a/lib/nfc/nfc_worker.c +++ b/lib/nfc/nfc_worker.c @@ -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(); } diff --git a/lib/nfc/protocols/nfcv.c b/lib/nfc/protocols/nfcv.c index 2e35a5a98..b14baa2d2 100644 --- a/lib/nfc/protocols/nfcv.c +++ b/lib/nfc/protocols/nfcv.c @@ -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; diff --git a/lib/nfc/protocols/nfcv.h b/lib/nfc/protocols/nfcv.h index 25a8550bd..6253fa1a6 100644 --- a/lib/nfc/protocols/nfcv.h +++ b/lib/nfc/protocols/nfcv.h @@ -9,16 +9,20 @@ #include -#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 diff --git a/lib/pulse_reader/pulse_reader.c b/lib/pulse_reader/pulse_reader.c index 25add2caa..c5729c42a 100644 --- a/lib/pulse_reader/pulse_reader.c +++ b/lib/pulse_reader/pulse_reader.c @@ -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 */ diff --git a/lib/pulse_reader/pulse_reader.h b/lib/pulse_reader/pulse_reader.h index 1042fab89..a53e666b0 100644 --- a/lib/pulse_reader/pulse_reader.h +++ b/lib/pulse_reader/pulse_reader.h @@ -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;