From 820ccb9775cd1349761caf2099faaef78fcc0f5f Mon Sep 17 00:00:00 2001 From: g3gg0 Date: Mon, 21 Nov 2022 01:21:15 +0100 Subject: [PATCH] switch to signal sequence (nonfunc) --- firmware/targets/f7/api_symbols.csv | 12 +- lib/digital_signal/digital_signal.c | 314 ++++++++++++++++++++++------ lib/digital_signal/digital_signal.h | 41 +++- lib/nfc/protocols/nfcv.c | 43 +++- 4 files changed, 320 insertions(+), 90 deletions(-) diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index a3ad98dad..9623807ce 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,7.20,, +Version,+,7.26,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -707,13 +707,21 @@ Function,+,dialog_message_set_text,void,"DialogMessage*, const char*, uint8_t, u Function,+,dialog_message_show,DialogMessageButton,"DialogsApp*, const DialogMessage*" Function,+,dialog_message_show_storage_error,void,"DialogsApp*, const char*" Function,-,difftime,double,"time_t, time_t" +Function,-,digital_sequence_add,void,"DigitalSequence*, uint8_t" +Function,-,digital_sequence_alloc,DigitalSequence*,"uint32_t, const GpioPin*" +Function,-,digital_sequence_clear,void,DigitalSequence* +Function,-,digital_sequence_free,void,DigitalSequence* +Function,-,digital_sequence_send_signal,_Bool,DigitalSignal* +Function,-,digital_sequence_set_signal,void,"DigitalSequence*, uint8_t, DigitalSignal*" +Function,-,digital_sequence_send,_Bool,DigitalSequence* +Function,-,digital_signal_add,void,"DigitalSignal*, uint32_t" Function,-,digital_signal_alloc,DigitalSignal*,uint32_t Function,-,digital_signal_append,_Bool,"DigitalSignal*, DigitalSignal*" Function,-,digital_signal_free,void,DigitalSignal* Function,-,digital_signal_get_edge,uint32_t,"DigitalSignal*, uint32_t" Function,-,digital_signal_get_edges_cnt,uint32_t,DigitalSignal* Function,-,digital_signal_get_start_level,_Bool,DigitalSignal* -Function,-,digital_signal_prepare_arr,void,DigitalSignal* +Function,-,digital_signal_prepare,void,DigitalSignal* Function,-,digital_signal_send,void,"DigitalSignal*, const GpioPin*" Function,-,diprintf,int,"int, const char*, ..." Function,+,dir_walk_alloc,DirWalk*,Storage* diff --git a/lib/digital_signal/digital_signal.c b/lib/digital_signal/digital_signal.c index c855f188b..76cfe9c39 100644 --- a/lib/digital_signal/digital_signal.c +++ b/lib/digital_signal/digital_signal.c @@ -5,6 +5,8 @@ #include #include +#define TAG "[DigitalSignal]" + #pragma GCC optimize("O3,unroll-loops,Ofast") #define F_TIM (64000000.0) @@ -13,11 +15,13 @@ DigitalSignal* digital_signal_alloc(uint32_t max_edges_cnt) { DigitalSignal* signal = malloc(sizeof(DigitalSignal)); + signal->prepared = false; signal->start_level = true; signal->edges_max_cnt = max_edges_cnt; - signal->edge_timings = malloc(max_edges_cnt * sizeof(uint32_t)); - signal->reload_reg_buff = malloc(signal->edges_max_cnt * sizeof(uint32_t)); + signal->edge_timings = malloc(signal->edges_max_cnt * sizeof(uint32_t)); signal->edge_cnt = 0; + signal->reload_reg_buff = malloc(signal->edges_max_cnt * sizeof(uint32_t)); + signal->reload_reg_entries = 0; return signal; } @@ -60,6 +64,8 @@ bool digital_signal_append(DigitalSignal* signal_a, DigitalSignal* signal_b) { } signal_a->edge_cnt += signal_b->edge_cnt - start_copy; + signal_a->prepared = false; + return true; } @@ -75,6 +81,13 @@ uint32_t digital_signal_get_edges_cnt(DigitalSignal* signal) { return signal->edge_cnt; } +void digital_signal_add(DigitalSignal* signal, uint32_t ticks) { + furi_assert(signal); + furi_assert(signal->edge_cnt < signal->edges_max_cnt); + + signal->edge_timings[signal->edge_cnt++] = ticks; +} + uint32_t digital_signal_get_edge(DigitalSignal* signal, uint32_t edge_num) { furi_assert(signal); furi_assert(edge_num < signal->edge_cnt); @@ -82,77 +95,122 @@ uint32_t digital_signal_get_edge(DigitalSignal* signal, uint32_t edge_num) { return signal->edge_timings[edge_num]; } -void digital_signal_prepare_arr(DigitalSignal* signal) { - uint32_t t_signal_rest = signal->edge_timings[0]; - uint32_t r_count_tick_arr = 0; - uint32_t r_rest_div = 0; +void digital_signal_prepare(DigitalSignal* signal) { + furi_assert(signal); + + if(signal->prepared) { + return; + } + /* set up signal polarities */ + uint32_t bit_set = signal->gpio->pin; + uint32_t bit_reset = signal->gpio->pin << 16; - for(size_t i = 0; i < signal->edge_cnt - 1; i++) { - r_count_tick_arr = t_signal_rest / T_TIM; - r_rest_div = t_signal_rest % T_TIM; - t_signal_rest = signal->edge_timings[i + 1] + r_rest_div; + if(signal->start_level) { + signal->gpio_buff[0] = bit_set; + signal->gpio_buff[1] = bit_reset; + } else { + signal->gpio_buff[0] = bit_reset; + signal->gpio_buff[1] = bit_set; + } - if(r_rest_div < T_TIM_DIV2) { - signal->reload_reg_buff[i] = r_count_tick_arr - 1; - } else { - signal->reload_reg_buff[i] = r_count_tick_arr; - t_signal_rest -= T_TIM; + /* set up edge timings */ + uint32_t remainder = 0; + signal->reload_reg_entries = 0; + + for(size_t pos = 0; pos < signal->edge_cnt; pos++) { + uint32_t pulse_duration = signal->edge_timings[pos] + remainder; + uint32_t pulse_ticks = (pulse_duration + T_TIM_DIV2) / T_TIM; + remainder = pulse_duration - (pulse_ticks * T_TIM); + + if(pulse_ticks > 0) { + signal->reload_reg_buff[signal->reload_reg_entries++] = pulse_ticks; } } + + signal->prepared = true; } -void digital_signal_send(DigitalSignal* signal, const GpioPin* gpio) { +bool digital_signal_setup_dma(DigitalSignal* signal) { furi_assert(signal); - furi_assert(gpio); - // Configure gpio as output - furi_hal_gpio_init(gpio, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); - - // Init gpio buffer and DMA channel - uint16_t gpio_reg = gpio->port->ODR; - uint16_t gpio_buff[2]; - if(signal->start_level) { - gpio_buff[0] = gpio_reg | gpio->pin; - gpio_buff[1] = gpio_reg & ~(gpio->pin); - } else { - gpio_buff[0] = gpio_reg & ~(gpio->pin); - gpio_buff[1] = gpio_reg | gpio->pin; + if(!signal->reload_reg_entries) { + return false; } - LL_DMA_InitTypeDef dma_config = {}; - dma_config.MemoryOrM2MDstAddress = (uint32_t)gpio_buff; - dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (gpio->port->ODR); - dma_config.Direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH; - dma_config.Mode = LL_DMA_MODE_CIRCULAR; - dma_config.PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT; - dma_config.MemoryOrM2MDstIncMode = LL_DMA_MEMORY_INCREMENT; - dma_config.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_HALFWORD; - dma_config.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_HALFWORD; - dma_config.NbData = 2; - dma_config.PeriphRequest = LL_DMAMUX_REQ_TIM2_UP; - dma_config.Priority = LL_DMA_PRIORITY_VERYHIGH; - LL_DMA_Init(DMA1, LL_DMA_CHANNEL_1, &dma_config); - LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_1, 2); - LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1); + + LL_DMA_InitTypeDef dma_config_gpio = {}; + LL_DMA_InitTypeDef dma_config_timer = {}; + + dma_config_gpio.MemoryOrM2MDstAddress = (uint32_t) signal->gpio_buff; + dma_config_gpio.PeriphOrM2MSrcAddress = (uint32_t) &(signal->gpio->port->BSRR); + dma_config_gpio.Direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH; + dma_config_gpio.Mode = LL_DMA_MODE_CIRCULAR; + dma_config_gpio.PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT; + dma_config_gpio.MemoryOrM2MDstIncMode = LL_DMA_MEMORY_INCREMENT; + dma_config_gpio.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_WORD; + dma_config_gpio.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_WORD; + dma_config_gpio.NbData = 2; + dma_config_gpio.PeriphRequest = LL_DMAMUX_REQ_TIM2_UP; + dma_config_gpio.Priority = LL_DMA_PRIORITY_VERYHIGH; // Init timer arr register buffer and DMA channel - digital_signal_prepare_arr(signal); - dma_config.MemoryOrM2MDstAddress = (uint32_t)signal->reload_reg_buff; - dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (TIM2->ARR); - dma_config.Direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH; - dma_config.Mode = LL_DMA_MODE_NORMAL; - dma_config.PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT; - dma_config.MemoryOrM2MDstIncMode = LL_DMA_MEMORY_INCREMENT; - dma_config.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_WORD; - dma_config.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_WORD; - dma_config.NbData = signal->edge_cnt - 2; - dma_config.PeriphRequest = LL_DMAMUX_REQ_TIM2_UP; - dma_config.Priority = LL_DMA_PRIORITY_HIGH; - LL_DMA_Init(DMA1, LL_DMA_CHANNEL_2, &dma_config); - LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_2, signal->edge_cnt - 2); + dma_config_timer.MemoryOrM2MDstAddress = (uint32_t)signal->reload_reg_buff; + dma_config_timer.PeriphOrM2MSrcAddress = (uint32_t) &(TIM2->ARR); + dma_config_timer.Direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH; + dma_config_timer.Mode = LL_DMA_MODE_NORMAL; + dma_config_timer.PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT; + dma_config_timer.MemoryOrM2MDstIncMode = LL_DMA_MEMORY_INCREMENT; + dma_config_timer.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_WORD; + dma_config_timer.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_WORD; + dma_config_timer.NbData = signal->reload_reg_entries; + dma_config_timer.PeriphRequest = LL_DMAMUX_REQ_TIM2_UP; + dma_config_timer.Priority = LL_DMA_PRIORITY_HIGH; + + /* 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_2, &dma_config_timer); + + /* enable both DMA channels */ + LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1); LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_2); - // Set up timer + return true; +} + + +void digital_signal_update_dma(DigitalSignal* signal) { + furi_assert(signal); + + 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); + + 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_SetDataLength(DMA1, LL_DMA_CHANNEL_1, 2); + LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_2, signal->reload_reg_entries); + + LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1); + LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_2); +} + +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); +} + +void digital_signal_setup_timer() { + + digital_signal_stop_timer(); + LL_TIM_SetCounterMode(TIM2, LL_TIM_COUNTERMODE_UP); LL_TIM_SetClockDivision(TIM2, LL_TIM_CLOCKDIVISION_DIV1); LL_TIM_SetPrescaler(TIM2, 0); @@ -160,19 +218,137 @@ void digital_signal_send(DigitalSignal* signal, const GpioPin* gpio) { LL_TIM_SetCounter(TIM2, 0); LL_TIM_EnableUpdateEvent(TIM2); LL_TIM_EnableDMAReq_UPDATE(TIM2); +} - // Start transactions - LL_TIM_GenerateEvent_UPDATE(TIM2); // Do we really need it? +void digital_signal_start_timer() { + LL_TIM_GenerateEvent_UPDATE(TIM2); LL_TIM_EnableCounter(TIM2); +} - while(!LL_DMA_IsActiveFlag_TC2(DMA1)) - { +void digital_signal_send(DigitalSignal* signal, const GpioPin* gpio) { + furi_assert(signal); + + /* if selected GPIO changed, force reconfiguration of buffers */ + if(gpio && (signal->gpio != gpio)) { + signal->gpio = gpio; + signal->prepared = false; } - LL_DMA_ClearFlag_TC1(DMA1); - LL_DMA_ClearFlag_TC2(DMA1); - LL_TIM_DisableCounter(TIM2); - LL_TIM_SetCounter(TIM2, 0); - LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_1); - LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_2); + /* Configure gpio as output */ + furi_hal_gpio_init(signal->gpio, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); + + digital_signal_prepare(signal); + + digital_signal_setup_dma(signal); + digital_signal_setup_timer(); + digital_signal_start_timer(); + + while(!LL_DMA_IsActiveFlag_TC2(DMA1)) { + } + + digital_signal_stop_timer(); + digital_signal_stop_dma(); +} + + +DigitalSequence* digital_sequence_alloc(uint32_t size, const GpioPin* gpio) { + + DigitalSequence* sequence = malloc(sizeof(DigitalSequence)); + + sequence->gpio = gpio; + sequence->signals_size = 32; + sequence->signals = malloc(sequence->signals_size * sizeof(DigitalSignal*)); + + sequence->sequence_used = 0; + sequence->sequence_size = size; + sequence->sequence = malloc(sequence->sequence_size); + + return sequence; +} + +void digital_sequence_free(DigitalSequence* sequence) { + furi_assert(sequence); + + free(sequence->signals); + free(sequence->sequence); + free(sequence); +} + +void digital_sequence_set_signal(DigitalSequence* sequence, uint8_t signal_index, DigitalSignal* signal) { + furi_assert(sequence); + furi_assert(signal); + furi_assert(signal_index < sequence->signals_size); + + sequence->signals[signal_index] = signal; + + /* all signals will use the sequence's GPIO */ + signal->gpio = sequence->gpio; + signal->prepared = false; + + digital_signal_prepare(signal); +} + +void digital_sequence_add(DigitalSequence* sequence, uint8_t signal_index) { + furi_assert(sequence); + furi_assert(signal_index < sequence->signals_size); + + if(sequence->sequence_used >= sequence->sequence_size) { + sequence->sequence_size += 256; + sequence->sequence = realloc(sequence->sequence, sequence->sequence_size); + } + + sequence->sequence[sequence->sequence_used++] = signal_index; +} + +bool digital_sequence_send_signal(DigitalSignal* signal) { + furi_assert(signal); + + /* the first iteration has to set up the whol machinery */ + if(!LL_DMA_IsEnabledChannel(DMA1, LL_DMA_CHANNEL_1)) { + furi_hal_gpio_init(signal->gpio, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); + + if(!digital_signal_setup_dma(signal)) { + FURI_LOG_D(TAG, "Signal has no entries, aborting"); + return false; + } + digital_signal_setup_timer(); + digital_signal_start_timer(); + } else { + /* it was already active, wait till DMA is done and the last timer ticks are running */ + while(!LL_DMA_IsActiveFlag_TC2(DMA1)) { + } + + /* configure next polarities and timings */ + digital_signal_update_dma(signal); + } + + return true; +} + +bool digital_sequence_send(DigitalSequence* sequence) { + furi_assert(sequence); + + for(uint32_t pos = 0; pos < sequence->sequence_used; pos++) { + DigitalSignal *sig = sequence->signals[sequence->sequence[pos]]; + + if(!digital_sequence_send_signal(sig)) { + digital_signal_stop_timer(); + digital_signal_stop_dma(); + return false; + } + } + + while(!LL_DMA_IsActiveFlag_TC2(DMA1)) { + } + + digital_signal_stop_timer(); + digital_signal_stop_dma(); + + return true; +} + +void digital_sequence_clear(DigitalSequence* sequence) { + furi_assert(sequence); + + sequence->sequence_used = 0; } diff --git a/lib/digital_signal/digital_signal.h b/lib/digital_signal/digital_signal.h index 90905d74b..00376466e 100644 --- a/lib/digital_signal/digital_signal.h +++ b/lib/digital_signal/digital_signal.h @@ -10,30 +10,55 @@ extern "C" { #endif +/* helper for easier signal generation */ +#define DIGITAL_SIGNAL_MS(x) (x*100000000UL) +#define DIGITAL_SIGNAL_US(x) (x*100000UL) +#define DIGITAL_SIGNAL_NS(x) (x*100UL) + + typedef struct { + bool prepared; bool start_level; uint32_t edge_cnt; uint32_t edges_max_cnt; uint32_t* edge_timings; uint32_t* reload_reg_buff; + uint32_t reload_reg_entries; + uint32_t gpio_buff[2]; + const GpioPin* gpio; } DigitalSignal; +typedef struct { + uint8_t signals_size; + uint32_t sequence_used; + uint32_t sequence_size; + const GpioPin* gpio; + DigitalSignal** signals; + uint8_t* sequence; +} DigitalSequence; + + DigitalSignal* digital_signal_alloc(uint32_t max_edges_cnt); - void digital_signal_free(DigitalSignal* signal); - +void digital_signal_add(DigitalSignal* signal, uint32_t ticks); bool digital_signal_append(DigitalSignal* signal_a, DigitalSignal* signal_b); - -void digital_signal_prepare_arr(DigitalSignal* signal); - +void digital_signal_prepare(DigitalSignal* signal); bool digital_signal_get_start_level(DigitalSignal* signal); - uint32_t digital_signal_get_edges_cnt(DigitalSignal* signal); - uint32_t digital_signal_get_edge(DigitalSignal* signal, uint32_t edge_num); - void digital_signal_send(DigitalSignal* signal, const GpioPin* gpio); + +DigitalSequence* digital_sequence_alloc(uint32_t size, const GpioPin* gpio); +void digital_sequence_free(DigitalSequence* sequence); +void digital_sequence_set_signal(DigitalSequence* sequence, uint8_t signal_index, DigitalSignal* signal); +void digital_sequence_add(DigitalSequence* sequence, uint8_t signal_index); +bool digital_sequence_send_signal(DigitalSignal* signal); +bool digital_sequence_send(DigitalSequence* sequence); +void digital_sequence_clear(DigitalSequence* sequence); + + + #ifdef __cplusplus } #endif diff --git a/lib/nfc/protocols/nfcv.c b/lib/nfc/protocols/nfcv.c index b14baa2d2..bce179dba 100644 --- a/lib/nfc/protocols/nfcv.c +++ b/lib/nfc/protocols/nfcv.c @@ -161,7 +161,12 @@ DigitalSignal* nfcv_resp_eof = NULL; DigitalSignal* nfcv_resp_unmod_256 = NULL; DigitalSignal* nfcv_resp_unmod_768 = NULL; -DigitalSignal* nfcv_signal = NULL; +DigitalSequence* nfcv_signal = NULL; + +#define SIG_SOF 0 +#define SIG_BIT0 1 +#define SIG_BIT1 2 +#define SIG_EOF 3 void nfcv_crc(uint8_t* data, uint32_t length, uint8_t* out) { @@ -187,7 +192,7 @@ void nfcv_crc(uint8_t* data, uint32_t length, uint8_t* out) { } void nfcv_emu_free() { - digital_signal_free(nfcv_signal); + digital_sequence_free(nfcv_signal); digital_signal_free(nfcv_resp_unmod_256); digital_signal_free(nfcv_resp_pulse_32); digital_signal_free(nfcv_resp_one); @@ -207,7 +212,8 @@ void nfcv_emu_free() { void nfcv_emu_alloc() { if(!nfcv_signal) { - nfcv_signal = digital_signal_alloc(8192); + /* assuming max frame length is 255 bytes */ + nfcv_signal = digital_sequence_alloc(8 * 255 + 2, &gpio_spi_r_mosi); } if(!nfcv_resp_unmod_256) { @@ -265,6 +271,11 @@ void nfcv_emu_alloc() { /* add extra silence */ digital_signal_append(nfcv_resp_eof, nfcv_resp_unmod_256); } + + digital_sequence_set_signal(nfcv_signal, SIG_SOF, nfcv_resp_sof); + digital_sequence_set_signal(nfcv_signal, SIG_BIT0, nfcv_resp_zero); + digital_sequence_set_signal(nfcv_signal, SIG_BIT1, nfcv_resp_one); + digital_sequence_set_signal(nfcv_signal, SIG_EOF, nfcv_resp_eof); } @@ -272,10 +283,14 @@ void nfcv_emu_send_raw(uint8_t* data, uint8_t length) { int bits = length * 8; - nfcv_signal->start_level = false; - nfcv_signal->edge_cnt = 0; + 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); - digital_signal_append(nfcv_signal, nfcv_resp_sof); + digital_sequence_clear(nfcv_signal); + digital_sequence_add(nfcv_signal, SIG_SOF); for(int bit_total = 0; bit_total < bits; bit_total++) { uint32_t byte_pos = bit_total / 8; @@ -283,13 +298,13 @@ void nfcv_emu_send_raw(uint8_t* data, uint8_t length) { 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); } else { - digital_signal_append(nfcv_signal, nfcv_resp_zero); + digital_sequence_add(nfcv_signal, SIG_BIT0); } } - digital_signal_append(nfcv_signal, nfcv_resp_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); @@ -299,7 +314,7 @@ void nfcv_emu_send_raw(uint8_t* data, uint8_t length) { furi_hal_gpio_write(&gpio_spi_r_mosi, false); FURI_CRITICAL_ENTER(); - digital_signal_send(nfcv_signal, &gpio_spi_r_mosi); + digital_sequence_send(nfcv_signal); FURI_CRITICAL_EXIT(); furi_hal_gpio_write(&gpio_spi_r_mosi, false); } @@ -564,7 +579,7 @@ void nfcv_emu_handle_packet(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data, ui } 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); } } @@ -744,6 +759,12 @@ bool nfcv_emu_loop(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data, uint32_t ti if(frame_state == NFCV_FRAME_STATE_EOF) { /* we know that this code uses TIM2, so stop pulse reader */ + 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); + pulse_reader_stop(reader_signal); nfcv_emu_handle_packet(nfc_data, nfcv_data, frame_payload, frame_pos); pulse_reader_start(reader_signal);