mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-23 05:24:46 -07:00
switch to DigitalSequence
This commit is contained in:
@@ -14,6 +14,9 @@
|
|||||||
#include <lib/nfc/nfc_device.h>
|
#include <lib/nfc/nfc_device.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include <lib/digital_signal/digital_signal.h>
|
||||||
|
#include <lib/pulse_reader/pulse_reader.h>
|
||||||
|
|
||||||
|
|
||||||
static void nfc_cli_print_usage() {
|
static void nfc_cli_print_usage() {
|
||||||
printf("Usage:\r\n");
|
printf("Usage:\r\n");
|
||||||
@@ -23,10 +26,6 @@ static void nfc_cli_print_usage() {
|
|||||||
printf("\temulate\t - emulate predefined nfca card\r\n");
|
printf("\temulate\t - emulate predefined nfca card\r\n");
|
||||||
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) {
|
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) {
|
||||||
printf("\tfield\t - turn field on\r\n");
|
printf("\tfield\t - turn field on\r\n");
|
||||||
printf("\tst25r_read\t - read ST25R3916 register\r\n");
|
|
||||||
printf("\tst25r_write\t - write ST25R3916 register\r\n");
|
|
||||||
printf("\tst25r_cmd\t - execute ST25R3916 command\r\n");
|
|
||||||
printf("\tst25r_fifo\t - wait for FIFO data\r\n");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,199 +110,6 @@ static void nfc_cli_field(Cli* cli, FuriString* args) {
|
|||||||
furi_hal_nfc_sleep();
|
furi_hal_nfc_sleep();
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t hexdigit(char hex) {
|
|
||||||
return (hex <= '9') ? hex - '0' : toupper(hex) - 'A' + 10 ;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t hexbyte(const char* hex) {
|
|
||||||
return (hexdigit(*hex) << 4) | hexdigit(*(hex+1));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nfc_cli_st25r_write(Cli* cli, FuriString* args) {
|
|
||||||
UNUSED(cli);
|
|
||||||
FuriString* reg = furi_string_alloc();
|
|
||||||
FuriString* value = furi_string_alloc();
|
|
||||||
|
|
||||||
// Check if nfc worker is not busy
|
|
||||||
if(furi_hal_nfc_is_busy()) {
|
|
||||||
printf("Nfc is busy\r\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!args_read_string_and_trim(args, reg) || !args_read_string_and_trim(args, value)) {
|
|
||||||
printf("You didn't specify <reg> and <value>\r\n");
|
|
||||||
nfc_cli_print_usage();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(furi_string_utf8_length(reg) != 2 || furi_string_utf8_length(value) != 2) {
|
|
||||||
printf("You didn't specify <reg> and <value> as 2-character hex values\r\n");
|
|
||||||
nfc_cli_print_usage();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t reg_val = hexbyte(furi_string_get_cstr(reg));
|
|
||||||
uint8_t value_val = hexbyte(furi_string_get_cstr(value));
|
|
||||||
|
|
||||||
printf("W %02X <- %02X\r\n", reg_val, value_val);
|
|
||||||
if(st25r3916WriteRegister(reg_val, value_val) != ERR_NONE) {
|
|
||||||
printf("Failed to write register\r\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nfc_cli_st25r_read(Cli* cli, FuriString* args) {
|
|
||||||
UNUSED(cli);
|
|
||||||
FuriString* reg = furi_string_alloc();
|
|
||||||
|
|
||||||
// Check if nfc worker is not busy
|
|
||||||
if(furi_hal_nfc_is_busy()) {
|
|
||||||
printf("Nfc is busy\r\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!args_read_string_and_trim(args, reg)) {
|
|
||||||
printf("You didn't specify <reg>\r\n");
|
|
||||||
nfc_cli_print_usage();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(furi_string_utf8_length(reg) != 2) {
|
|
||||||
printf("You didn't specify <reg> as 2-character hex value\r\n");
|
|
||||||
nfc_cli_print_usage();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t reg_val = hexbyte(furi_string_get_cstr(reg));
|
|
||||||
uint8_t value_val = 0;
|
|
||||||
|
|
||||||
if(st25r3916ReadRegister(reg_val, &value_val) != ERR_NONE) {
|
|
||||||
printf("Failed to read register\r\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("R %02X -> %02X\r\n", reg_val, value_val);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nfc_cli_st25r_cmd(Cli* cli, FuriString* args) {
|
|
||||||
UNUSED(cli);
|
|
||||||
FuriString* cmd = furi_string_alloc();
|
|
||||||
|
|
||||||
// Check if nfc worker is not busy
|
|
||||||
if(furi_hal_nfc_is_busy()) {
|
|
||||||
printf("Nfc is busy\r\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!args_read_string_and_trim(args, cmd)) {
|
|
||||||
printf("You didn't specify <cmd>\r\n");
|
|
||||||
nfc_cli_print_usage();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(furi_string_utf8_length(cmd) != 2) {
|
|
||||||
printf("You didn't specify <cmd> as 2-character hex value\r\n");
|
|
||||||
nfc_cli_print_usage();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t cmd_val = hexbyte(furi_string_get_cstr(cmd));
|
|
||||||
|
|
||||||
if(st25r3916ExecuteCommand(cmd_val) != ERR_NONE) {
|
|
||||||
printf("Failed to execute\r\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("X %02X\r\n", cmd_val);
|
|
||||||
}
|
|
||||||
|
|
||||||
static FuriHalNfcTxRxContext tx_rx = {};
|
|
||||||
|
|
||||||
static void nfc_cli_st25r_fifo(Cli* cli, FuriString* args) {
|
|
||||||
UNUSED(args);
|
|
||||||
|
|
||||||
// Check if nfc worker is not busy
|
|
||||||
if(furi_hal_nfc_is_busy()) {
|
|
||||||
printf("Nfc is busy\r\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool field = false;
|
|
||||||
|
|
||||||
tx_rx.sniff_tx = NULL;
|
|
||||||
tx_rx.sniff_rx = NULL;
|
|
||||||
tx_rx.tx_bits = 0;
|
|
||||||
tx_rx.tx_rx_type = FuriHalNfcTxRxTypeRxRaw;
|
|
||||||
|
|
||||||
rfal_platform_spi_acquire();
|
|
||||||
|
|
||||||
furi_hal_nfcv_listen_start();
|
|
||||||
|
|
||||||
printf("Reading FIFO...\r\nPress Ctrl+C to abort\r\n");
|
|
||||||
while(!cli_cmd_interrupt_received(cli)) {
|
|
||||||
|
|
||||||
if(st25r3916IsExtFieldOn() && !field) {
|
|
||||||
printf("Field entered\r\n");
|
|
||||||
field = true;
|
|
||||||
}
|
|
||||||
if(!st25r3916IsExtFieldOn() && field) {
|
|
||||||
printf("Field left\r\n");
|
|
||||||
field = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(furi_hal_nfc_listen_rx(&tx_rx, 50)) {
|
|
||||||
for(int pos = 0; pos < tx_rx.rx_bits / 8; pos++) {
|
|
||||||
printf(" %02X", tx_rx.rx_data[pos]);
|
|
||||||
}
|
|
||||||
printf("\r\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
furi_delay_ms(50);
|
|
||||||
}
|
|
||||||
rfal_platform_spi_release();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void nfc_cli_st25r_trans(Cli* cli, FuriString* args) {
|
|
||||||
UNUSED(args);
|
|
||||||
|
|
||||||
// Check if nfc worker is not busy
|
|
||||||
if(furi_hal_nfc_is_busy()) {
|
|
||||||
printf("Nfc is busy\r\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("ISO15693 emulator...\r\nPress Ctrl+C to abort\r\n");
|
|
||||||
|
|
||||||
FuriHalNfcDevData nfc_data = {
|
|
||||||
.uid = { 0xE0, 0x04, 0x45, 0x03, 0x50, 0x0E, 0x78, 0x36 },
|
|
||||||
.uid_len = 8,
|
|
||||||
.type = FuriHalNfcTypeV,
|
|
||||||
};
|
|
||||||
NfcVData nfcv_data = {
|
|
||||||
.afi = 0,
|
|
||||||
.dsfid = 0,
|
|
||||||
.block_num = 8,
|
|
||||||
.block_size = 4,
|
|
||||||
.ic_ref = 3,
|
|
||||||
.type = NfcVTypeSlixL,
|
|
||||||
.sub_data.slix_l = {
|
|
||||||
.key_privacy = { 0x0F, 0x0F, 0x0F, 0x0F },
|
|
||||||
.privacy = false
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
memset(nfcv_data.data, 0xAE, 4 * 8);
|
|
||||||
|
|
||||||
nfcv_emu_init(&nfc_data, &nfcv_data);
|
|
||||||
while(!cli_cmd_interrupt_received(cli)) {
|
|
||||||
if(nfcv_emu_loop(&nfc_data, &nfcv_data, 1000)) {
|
|
||||||
printf("[NfcV-Emu] %s\r\n", nfcv_data.last_command);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nfcv_emu_deinit();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nfc_cli(Cli* cli, FuriString* args, void* context) {
|
static void nfc_cli(Cli* cli, FuriString* args, void* context) {
|
||||||
UNUSED(context);
|
UNUSED(context);
|
||||||
@@ -329,26 +135,6 @@ static void nfc_cli(Cli* cli, FuriString* args, void* context) {
|
|||||||
nfc_cli_field(cli, args);
|
nfc_cli_field(cli, args);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(furi_string_cmp_str(cmd, "st25r_read") == 0) {
|
|
||||||
nfc_cli_st25r_read(cli, args);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(furi_string_cmp_str(cmd, "st25r_write") == 0) {
|
|
||||||
nfc_cli_st25r_write(cli, args);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(furi_string_cmp_str(cmd, "st25r_cmd") == 0) {
|
|
||||||
nfc_cli_st25r_cmd(cli, args);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(furi_string_cmp_str(cmd, "st25r_fifo") == 0) {
|
|
||||||
nfc_cli_st25r_fifo(cli, args);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(furi_string_cmp_str(cmd, "st25r_trans") == 0) {
|
|
||||||
nfc_cli_st25r_trans(cli, args);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nfc_cli_print_usage();
|
nfc_cli_print_usage();
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ DigitalSignal* digital_signal_alloc(uint32_t max_edges_cnt) {
|
|||||||
signal->edge_cnt = 0;
|
signal->edge_cnt = 0;
|
||||||
signal->reload_reg_buff = malloc(signal->edges_max_cnt * sizeof(uint32_t));
|
signal->reload_reg_buff = malloc(signal->edges_max_cnt * sizeof(uint32_t));
|
||||||
signal->reload_reg_entries = 0;
|
signal->reload_reg_entries = 0;
|
||||||
|
signal->reload_reg_remainder = 0;
|
||||||
|
|
||||||
return signal;
|
return signal;
|
||||||
}
|
}
|
||||||
@@ -98,10 +99,6 @@ uint32_t digital_signal_get_edge(DigitalSignal* signal, uint32_t edge_num) {
|
|||||||
void digital_signal_prepare(DigitalSignal* signal) {
|
void digital_signal_prepare(DigitalSignal* signal) {
|
||||||
furi_assert(signal);
|
furi_assert(signal);
|
||||||
|
|
||||||
if(signal->prepared) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* set up signal polarities */
|
/* set up signal polarities */
|
||||||
uint32_t bit_set = signal->gpio->pin;
|
uint32_t bit_set = signal->gpio->pin;
|
||||||
uint32_t bit_reset = signal->gpio->pin << 16;
|
uint32_t bit_reset = signal->gpio->pin << 16;
|
||||||
@@ -115,20 +112,30 @@ void digital_signal_prepare(DigitalSignal* signal) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* set up edge timings */
|
/* set up edge timings */
|
||||||
uint32_t remainder = 0;
|
|
||||||
signal->reload_reg_entries = 0;
|
signal->reload_reg_entries = 0;
|
||||||
|
|
||||||
for(size_t pos = 0; pos < signal->edge_cnt; pos++) {
|
for(size_t pos = 0; pos < signal->edge_cnt; pos++) {
|
||||||
uint32_t pulse_duration = signal->edge_timings[pos] + remainder;
|
uint32_t pulse_duration = signal->edge_timings[pos] + signal->reload_reg_remainder;
|
||||||
uint32_t pulse_ticks = (pulse_duration + T_TIM_DIV2) / T_TIM;
|
uint32_t pulse_ticks = (pulse_duration + T_TIM_DIV2) / T_TIM;
|
||||||
remainder = pulse_duration - (pulse_ticks * T_TIM);
|
signal->reload_reg_remainder = pulse_duration - (pulse_ticks * T_TIM);
|
||||||
|
|
||||||
if(pulse_ticks > 1) {
|
if(pulse_ticks > 1) {
|
||||||
signal->reload_reg_buff[signal->reload_reg_entries++] = pulse_ticks - 1;
|
signal->reload_reg_buff[signal->reload_reg_entries++] = pulse_ticks - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
signal->prepared = true;
|
|
||||||
|
void digital_signal_stop_dma() {
|
||||||
|
LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_1);
|
||||||
|
LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_2);
|
||||||
|
LL_DMA_ClearFlag_TC1(DMA1);
|
||||||
|
LL_DMA_ClearFlag_TC2(DMA1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void digital_signal_stop_timer() {
|
||||||
|
LL_TIM_DisableCounter(TIM2);
|
||||||
|
LL_TIM_SetCounter(TIM2, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool digital_signal_setup_dma(DigitalSignal* signal) {
|
bool digital_signal_setup_dma(DigitalSignal* signal) {
|
||||||
@@ -166,6 +173,8 @@ bool digital_signal_setup_dma(DigitalSignal* signal) {
|
|||||||
dma_config_timer.PeriphRequest = LL_DMAMUX_REQ_TIM2_UP;
|
dma_config_timer.PeriphRequest = LL_DMAMUX_REQ_TIM2_UP;
|
||||||
dma_config_timer.Priority = LL_DMA_PRIORITY_HIGH;
|
dma_config_timer.Priority = LL_DMA_PRIORITY_HIGH;
|
||||||
|
|
||||||
|
digital_signal_stop_dma();
|
||||||
|
|
||||||
/* set up DMA channel 1 and 2 for GPIO and timer copy operations */
|
/* set up DMA channel 1 and 2 for GPIO and timer copy operations */
|
||||||
LL_DMA_Init(DMA1, LL_DMA_CHANNEL_1, &dma_config_gpio);
|
LL_DMA_Init(DMA1, LL_DMA_CHANNEL_1, &dma_config_gpio);
|
||||||
LL_DMA_Init(DMA1, LL_DMA_CHANNEL_2, &dma_config_timer);
|
LL_DMA_Init(DMA1, LL_DMA_CHANNEL_2, &dma_config_timer);
|
||||||
@@ -178,13 +187,14 @@ bool digital_signal_setup_dma(DigitalSignal* signal) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void digital_signal_update_dma(DigitalSignal* signal) {
|
bool digital_signal_update_dma(DigitalSignal* signal) {
|
||||||
furi_assert(signal);
|
furi_assert(signal);
|
||||||
|
|
||||||
LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_1);
|
if(!signal->reload_reg_entries) {
|
||||||
LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_2);
|
return false;
|
||||||
LL_DMA_ClearFlag_TC1(DMA1);
|
}
|
||||||
LL_DMA_ClearFlag_TC2(DMA1);
|
|
||||||
|
digital_signal_stop_dma();
|
||||||
|
|
||||||
LL_DMA_SetMemoryAddress(DMA1, LL_DMA_CHANNEL_1, (uint32_t)signal->gpio_buff);
|
LL_DMA_SetMemoryAddress(DMA1, LL_DMA_CHANNEL_1, (uint32_t)signal->gpio_buff);
|
||||||
LL_DMA_SetMemoryAddress(DMA1, LL_DMA_CHANNEL_2, (uint32_t)signal->reload_reg_buff);
|
LL_DMA_SetMemoryAddress(DMA1, LL_DMA_CHANNEL_2, (uint32_t)signal->reload_reg_buff);
|
||||||
@@ -193,18 +203,8 @@ void digital_signal_update_dma(DigitalSignal* signal) {
|
|||||||
|
|
||||||
LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1);
|
LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1);
|
||||||
LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_2);
|
LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_2);
|
||||||
}
|
|
||||||
|
|
||||||
void digital_signal_stop_dma() {
|
return true;
|
||||||
LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_1);
|
|
||||||
LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_2);
|
|
||||||
LL_DMA_ClearFlag_TC1(DMA1);
|
|
||||||
LL_DMA_ClearFlag_TC2(DMA1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void digital_signal_stop_timer() {
|
|
||||||
LL_TIM_DisableCounter(TIM2);
|
|
||||||
LL_TIM_SetCounter(TIM2, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void digital_signal_setup_timer() {
|
void digital_signal_setup_timer() {
|
||||||
@@ -231,7 +231,6 @@ void digital_signal_send(DigitalSignal* signal, const GpioPin* gpio) {
|
|||||||
/* if selected GPIO changed, force reconfiguration of buffers */
|
/* if selected GPIO changed, force reconfiguration of buffers */
|
||||||
if(gpio && (signal->gpio != gpio)) {
|
if(gpio && (signal->gpio != gpio)) {
|
||||||
signal->gpio = gpio;
|
signal->gpio = gpio;
|
||||||
signal->prepared = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Configure gpio as output */
|
/* Configure gpio as output */
|
||||||
@@ -303,7 +302,7 @@ void digital_sequence_add(DigitalSequence* sequence, uint8_t signal_index) {
|
|||||||
bool digital_sequence_send_signal(DigitalSignal* signal) {
|
bool digital_sequence_send_signal(DigitalSignal* signal) {
|
||||||
furi_assert(signal);
|
furi_assert(signal);
|
||||||
|
|
||||||
/* the first iteration has to set up the whol machinery */
|
/* the first iteration has to set up the whole machinery */
|
||||||
if(!LL_DMA_IsEnabledChannel(DMA1, LL_DMA_CHANNEL_1)) {
|
if(!LL_DMA_IsEnabledChannel(DMA1, LL_DMA_CHANNEL_1)) {
|
||||||
furi_hal_gpio_init(signal->gpio, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh);
|
furi_hal_gpio_init(signal->gpio, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh);
|
||||||
|
|
||||||
@@ -314,12 +313,15 @@ bool digital_sequence_send_signal(DigitalSignal* signal) {
|
|||||||
digital_signal_setup_timer();
|
digital_signal_setup_timer();
|
||||||
digital_signal_start_timer();
|
digital_signal_start_timer();
|
||||||
} else {
|
} else {
|
||||||
/* it was already active, wait till DMA is done and the last timer ticks are running */
|
/* transfer was already active, wait till DMA is done and the last timer ticks are running */
|
||||||
while(!LL_DMA_IsActiveFlag_TC2(DMA1)) {
|
while(!LL_DMA_IsActiveFlag_TC2(DMA1)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* configure next polarities and timings */
|
/* configure next polarities and timings */
|
||||||
digital_signal_update_dma(signal);
|
if(!digital_signal_update_dma(signal)) {
|
||||||
|
FURI_LOG_D(TAG, "Signal has no entries, aborting");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -328,9 +330,15 @@ bool digital_sequence_send_signal(DigitalSignal* signal) {
|
|||||||
bool digital_sequence_send(DigitalSequence* sequence) {
|
bool digital_sequence_send(DigitalSequence* sequence) {
|
||||||
furi_assert(sequence);
|
furi_assert(sequence);
|
||||||
|
|
||||||
|
uint32_t remainder = 0;
|
||||||
|
|
||||||
for(uint32_t pos = 0; pos < sequence->sequence_used; pos++) {
|
for(uint32_t pos = 0; pos < sequence->sequence_used; pos++) {
|
||||||
DigitalSignal *sig = sequence->signals[sequence->sequence[pos]];
|
DigitalSignal *sig = sequence->signals[sequence->sequence[pos]];
|
||||||
|
|
||||||
|
/* take over previous remainder */
|
||||||
|
sig->reload_reg_remainder = remainder;
|
||||||
|
digital_signal_prepare(sig);
|
||||||
|
|
||||||
if(!digital_sequence_send_signal(sig)) {
|
if(!digital_sequence_send_signal(sig)) {
|
||||||
digital_signal_stop_timer();
|
digital_signal_stop_timer();
|
||||||
digital_signal_stop_dma();
|
digital_signal_stop_dma();
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ typedef struct {
|
|||||||
uint32_t* edge_timings;
|
uint32_t* edge_timings;
|
||||||
uint32_t* reload_reg_buff;
|
uint32_t* reload_reg_buff;
|
||||||
uint32_t reload_reg_entries;
|
uint32_t reload_reg_entries;
|
||||||
|
uint32_t reload_reg_remainder;
|
||||||
uint32_t gpio_buff[2];
|
uint32_t gpio_buff[2];
|
||||||
const GpioPin* gpio;
|
const GpioPin* gpio;
|
||||||
} DigitalSignal;
|
} DigitalSignal;
|
||||||
|
|||||||
@@ -161,6 +161,11 @@ DigitalSignal* nfcv_resp_eof = NULL;
|
|||||||
DigitalSignal* nfcv_resp_unmod_256 = NULL;
|
DigitalSignal* nfcv_resp_unmod_256 = NULL;
|
||||||
DigitalSignal* nfcv_resp_unmod_768 = NULL;
|
DigitalSignal* nfcv_resp_unmod_768 = NULL;
|
||||||
|
|
||||||
|
//DigitalSignal* nfcv_signal = NULL;
|
||||||
|
|
||||||
|
//const GpioPin* nfcv_out_io = &gpio_ext_pb2;
|
||||||
|
const GpioPin* nfcv_out_io = &gpio_spi_r_mosi;
|
||||||
|
|
||||||
DigitalSequence* nfcv_signal = NULL;
|
DigitalSequence* nfcv_signal = NULL;
|
||||||
|
|
||||||
#define SIG_SOF 0
|
#define SIG_SOF 0
|
||||||
@@ -192,6 +197,7 @@ void nfcv_crc(uint8_t* data, uint32_t length, uint8_t* out) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void nfcv_emu_free() {
|
void nfcv_emu_free() {
|
||||||
|
//digital_signal_free(nfcv_signal);
|
||||||
digital_sequence_free(nfcv_signal);
|
digital_sequence_free(nfcv_signal);
|
||||||
digital_signal_free(nfcv_resp_unmod_256);
|
digital_signal_free(nfcv_resp_unmod_256);
|
||||||
digital_signal_free(nfcv_resp_pulse_32);
|
digital_signal_free(nfcv_resp_pulse_32);
|
||||||
@@ -212,8 +218,9 @@ void nfcv_emu_free() {
|
|||||||
void nfcv_emu_alloc() {
|
void nfcv_emu_alloc() {
|
||||||
|
|
||||||
if(!nfcv_signal) {
|
if(!nfcv_signal) {
|
||||||
|
//nfcv_signal = digital_signal_alloc(8192);
|
||||||
/* assuming max frame length is 255 bytes */
|
/* assuming max frame length is 255 bytes */
|
||||||
nfcv_signal = digital_sequence_alloc(8 * 255 + 2, &gpio_spi_r_mosi);
|
nfcv_signal = digital_sequence_alloc(8 * 255 + 2, nfcv_out_io);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!nfcv_resp_unmod_256) {
|
if(!nfcv_resp_unmod_256) {
|
||||||
@@ -283,11 +290,10 @@ void nfcv_emu_send_raw(uint8_t* data, uint8_t length) {
|
|||||||
|
|
||||||
int bits = length * 8;
|
int bits = length * 8;
|
||||||
|
|
||||||
furi_hal_gpio_write(&gpio_spi_r_mosi, false);
|
//nfcv_signal->start_level = false;
|
||||||
furi_delay_us(10);
|
//nfcv_signal->edge_cnt = 0;
|
||||||
furi_hal_gpio_write(&gpio_spi_r_mosi, true);
|
|
||||||
furi_delay_us(10);
|
//digital_signal_append(nfcv_signal, nfcv_resp_sof);
|
||||||
furi_hal_gpio_write(&gpio_spi_r_mosi, false);
|
|
||||||
|
|
||||||
digital_sequence_clear(nfcv_signal);
|
digital_sequence_clear(nfcv_signal);
|
||||||
digital_sequence_add(nfcv_signal, SIG_SOF);
|
digital_sequence_add(nfcv_signal, SIG_SOF);
|
||||||
@@ -297,26 +303,17 @@ void nfcv_emu_send_raw(uint8_t* data, uint8_t length) {
|
|||||||
uint32_t bit_pos = bit_total % 8;
|
uint32_t bit_pos = bit_total % 8;
|
||||||
uint8_t bit_val = 0x01 << bit_pos;
|
uint8_t bit_val = 0x01 << bit_pos;
|
||||||
|
|
||||||
if(data[byte_pos] & bit_val) {
|
//digital_signal_append(nfcv_signal, nfcv_resp_one);
|
||||||
digital_sequence_add(nfcv_signal, SIG_BIT1);
|
digital_sequence_add(nfcv_signal, (data[byte_pos] & bit_val) ? SIG_BIT1 : SIG_BIT0);
|
||||||
} else {
|
|
||||||
digital_sequence_add(nfcv_signal, SIG_BIT0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//digital_signal_append(nfcv_signal, nfcv_resp_eof);
|
||||||
digital_sequence_add(nfcv_signal, SIG_EOF);
|
digital_sequence_add(nfcv_signal, SIG_EOF);
|
||||||
|
|
||||||
/* digital signal setup will take some time. win some time by tricking the VCD into thinking that something happens */
|
|
||||||
furi_hal_gpio_write(&gpio_spi_r_mosi, false);
|
|
||||||
furi_delay_us(10);
|
|
||||||
furi_hal_gpio_write(&gpio_spi_r_mosi, true);
|
|
||||||
furi_delay_us(10);
|
|
||||||
furi_hal_gpio_write(&gpio_spi_r_mosi, false);
|
|
||||||
|
|
||||||
FURI_CRITICAL_ENTER();
|
FURI_CRITICAL_ENTER();
|
||||||
|
//digital_signal_send(nfcv_signal, nfcv_out_io);
|
||||||
digital_sequence_send(nfcv_signal);
|
digital_sequence_send(nfcv_signal);
|
||||||
FURI_CRITICAL_EXIT();
|
FURI_CRITICAL_EXIT();
|
||||||
furi_hal_gpio_write(&gpio_spi_r_mosi, false);
|
furi_hal_gpio_write(nfcv_out_io, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nfcv_emu_send(uint8_t* data, uint8_t length) {
|
void nfcv_emu_send(uint8_t* data, uint8_t length) {
|
||||||
@@ -579,7 +576,7 @@ void nfcv_emu_handle_packet(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data, ui
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(strlen(nfcv_data->last_command) > 0) {
|
if(strlen(nfcv_data->last_command) > 0) {
|
||||||
//FURI_LOG_D(TAG, "Received command %s", nfcv_data->last_command);
|
FURI_LOG_D(TAG, "Received command %s", nfcv_data->last_command);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -594,7 +591,6 @@ void nfcv_emu_init(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data) {
|
|||||||
|
|
||||||
furi_hal_spi_bus_handle_deinit(&furi_hal_spi_bus_handle_nfc);
|
furi_hal_spi_bus_handle_deinit(&furi_hal_spi_bus_handle_nfc);
|
||||||
|
|
||||||
|
|
||||||
FURI_LOG_D(TAG, "Starting NfcV emulation");
|
FURI_LOG_D(TAG, "Starting NfcV emulation");
|
||||||
FURI_LOG_D(TAG, " UID: %02X %02X %02X %02X %02X %02X %02X %02X",
|
FURI_LOG_D(TAG, " 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[0], nfc_data->uid[1], nfc_data->uid[2], nfc_data->uid[3],
|
||||||
@@ -676,7 +672,6 @@ bool nfcv_emu_loop(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data, uint32_t ti
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case NFCV_FRAME_STATE_CODING_256:
|
case NFCV_FRAME_STATE_CODING_256:
|
||||||
|
|
||||||
if(periods_previous > periods) {
|
if(periods_previous > periods) {
|
||||||
snprintf(reset_reason, sizeof(reset_reason), "1oo256: Missing %lu periods from previous symbol, got %lu", periods_previous, periods);
|
snprintf(reset_reason, sizeof(reset_reason), "1oo256: Missing %lu periods from previous symbol, got %lu", periods_previous, periods);
|
||||||
frame_state = NFCV_FRAME_STATE_RESET;
|
frame_state = NFCV_FRAME_STATE_RESET;
|
||||||
@@ -758,13 +753,9 @@ bool nfcv_emu_loop(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data, uint32_t ti
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(frame_state == NFCV_FRAME_STATE_EOF) {
|
if(frame_state == NFCV_FRAME_STATE_EOF) {
|
||||||
/* we know that this code uses TIM2, so stop pulse reader */
|
FURI_LOG_D(TAG, "Received valid frame");
|
||||||
furi_hal_gpio_write(&gpio_spi_r_mosi, false);
|
|
||||||
furi_delay_us(10);
|
|
||||||
furi_hal_gpio_write(&gpio_spi_r_mosi, true);
|
|
||||||
furi_delay_us(10);
|
|
||||||
furi_hal_gpio_write(&gpio_spi_r_mosi, false);
|
|
||||||
|
|
||||||
|
/* we know that this code uses TIM2, so stop pulse reader */
|
||||||
pulse_reader_stop(reader_signal);
|
pulse_reader_stop(reader_signal);
|
||||||
nfcv_emu_handle_packet(nfc_data, nfcv_data, frame_payload, frame_pos);
|
nfcv_emu_handle_packet(nfc_data, nfcv_data, frame_payload, frame_pos);
|
||||||
pulse_reader_start(reader_signal);
|
pulse_reader_start(reader_signal);
|
||||||
|
|||||||
Reference in New Issue
Block a user