diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index 9623807ce..ea96eac8c 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.26,, +Version,+,7.28,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -708,12 +708,12 @@ Function,+,dialog_message_show,DialogMessageButton,"DialogsApp*, const DialogMes 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_alloc,DigitalSequence*,uint32_t Function,-,digital_sequence_clear,void,DigitalSequence* Function,-,digital_sequence_free,void,DigitalSequence* +Function,-,digital_sequence_send,_Bool,"DigitalSequence*, const GpioPin*" 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*" diff --git a/firmware/targets/f7/furi_hal/furi_hal_nfc.c b/firmware/targets/f7/furi_hal/furi_hal_nfc.c index b95d490af..c14016fc2 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_nfc.c +++ b/firmware/targets/f7/furi_hal/furi_hal_nfc.c @@ -536,7 +536,7 @@ static bool furi_hal_nfc_transparent_tx_rx(FuriHalNfcTxRxContext* tx_rx, uint16_ // Send signal FURI_CRITICAL_ENTER(); nfca_signal_encode(tx_rx->nfca_signal, tx_rx->tx_data, tx_rx->tx_bits, tx_rx->tx_parity); - digital_signal_send(tx_rx->nfca_signal->tx_signal, &gpio_spi_r_mosi); + digital_sequence_send(tx_rx->nfca_signal->tx_signal, &gpio_spi_r_mosi); FURI_CRITICAL_EXIT(); furi_hal_gpio_write(&gpio_spi_r_mosi, false); diff --git a/lib/digital_signal/digital_signal.c b/lib/digital_signal/digital_signal.c index 6dd29eff5..de79c2962 100644 --- a/lib/digital_signal/digital_signal.c +++ b/lib/digital_signal/digital_signal.c @@ -15,7 +15,6 @@ 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(signal->edges_max_cnt * sizeof(uint32_t)); @@ -65,8 +64,6 @@ 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; } @@ -236,6 +233,8 @@ void digital_signal_send(DigitalSignal* signal, const GpioPin* gpio) { /* Configure gpio as output */ furi_hal_gpio_init(signal->gpio, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); + /* single signal, add a temporary, terminating edge at the end */ + signal->edge_timings[signal->edge_cnt++] = 10; digital_signal_prepare(signal); digital_signal_setup_dma(signal); @@ -247,14 +246,15 @@ void digital_signal_send(DigitalSignal* signal, const GpioPin* gpio) { digital_signal_stop_timer(); digital_signal_stop_dma(); + + signal->edge_cnt--; } -DigitalSequence* digital_sequence_alloc(uint32_t size, const GpioPin* gpio) { +DigitalSequence* digital_sequence_alloc(uint32_t size) { DigitalSequence* sequence = malloc(sizeof(DigitalSequence)); - sequence->gpio = gpio; sequence->signals_size = 32; sequence->signals = malloc(sequence->signals_size * sizeof(DigitalSignal*)); @@ -282,7 +282,6 @@ void digital_sequence_set_signal(DigitalSequence* sequence, uint8_t signal_index /* all signals will use the sequence's GPIO */ signal->gpio = sequence->gpio; - signal->prepared = false; digital_signal_prepare(signal); } @@ -327,11 +326,13 @@ bool digital_sequence_send_signal(DigitalSignal* signal) { return true; } -bool digital_sequence_send(DigitalSequence* sequence) { +bool digital_sequence_send(DigitalSequence* sequence, const GpioPin* gpio) { furi_assert(sequence); uint32_t remainder = 0; + sequence->gpio = gpio; + for(uint32_t pos = 0; pos < sequence->sequence_used; pos++) { DigitalSignal *sig = sequence->signals[sequence->sequence[pos]]; diff --git a/lib/digital_signal/digital_signal.h b/lib/digital_signal/digital_signal.h index 583105e47..83ccbad30 100644 --- a/lib/digital_signal/digital_signal.h +++ b/lib/digital_signal/digital_signal.h @@ -14,10 +14,10 @@ extern "C" { #define DIGITAL_SIGNAL_MS(x) (x*100000000UL) #define DIGITAL_SIGNAL_US(x) (x*100000UL) #define DIGITAL_SIGNAL_NS(x) (x*100UL) +#define DIGITAL_SIGNAL_PS(x) (x/10UL) typedef struct { - bool prepared; bool start_level; uint32_t edge_cnt; uint32_t edges_max_cnt; @@ -50,12 +50,12 @@ 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); +DigitalSequence* digital_sequence_alloc(uint32_t size); 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); +bool digital_sequence_send(DigitalSequence* sequence, const GpioPin* gpio); void digital_sequence_clear(DigitalSequence* sequence); diff --git a/lib/nfc/protocols/nfca.c b/lib/nfc/protocols/nfca.c index c401f8cc5..94f6a9e70 100644 --- a/lib/nfc/protocols/nfca.c +++ b/lib/nfc/protocols/nfca.c @@ -7,11 +7,10 @@ #define NFCA_CRC_INIT (0x6363) -#define NFCA_F_SIG (13560000.0) -#define T_SIG 7374 //73.746ns*100 -#define T_SIG_x8 58992 //T_SIG*8 -#define T_SIG_x8_x8 471936 //T_SIG*8*8 -#define T_SIG_x8_x9 530928 //T_SIG*8*9 +#define NFCA_F_SIG (13560000.0) /* [Hz] NFC frequency */ +#define NFCA_F_SUB (NFCA_F_SIG/16) /* [Hz] NFC subcarrier frequency fs/16 */ +#define T_SUB (1000000000000.0f / NFCA_F_SUB) /* [ps] subcarrier period = 1/NFCA_F_SUB */ +#define T_SUB_PHASE (T_SUB/2) /* [ps] a single subcarrier phase */ #define NFCA_SIGNAL_MAX_EDGES (1350) @@ -64,35 +63,25 @@ bool nfca_emulation_handler( } static void nfca_add_bit(DigitalSignal* signal, bool bit) { - if(bit) { - signal->start_level = true; - for(size_t i = 0; i < 7; i++) { - signal->edge_timings[i] = T_SIG_x8; - } - signal->edge_timings[7] = T_SIG_x8_x9; - signal->edge_cnt = 8; - } else { - signal->start_level = false; - signal->edge_timings[0] = T_SIG_x8_x8; - for(size_t i = 1; i < 9; i++) { - signal->edge_timings[i] = T_SIG_x8; - } - signal->edge_cnt = 9; + + signal->start_level = bit; + for(size_t i = 0; i < 16; i++) { + signal->edge_timings[signal->edge_cnt++] = T_SUB_PHASE; } } static void nfca_add_byte(NfcaSignal* nfca_signal, uint8_t byte, bool parity) { for(uint8_t i = 0; i < 8; i++) { if(byte & (1 << i)) { - digital_signal_append(nfca_signal->tx_signal, nfca_signal->one); + digital_sequence_add(nfca_signal->tx_signal, 1); } else { - digital_signal_append(nfca_signal->tx_signal, nfca_signal->zero); + digital_sequence_add(nfca_signal->tx_signal, 0); } } if(parity) { - digital_signal_append(nfca_signal->tx_signal, nfca_signal->one); + digital_sequence_add(nfca_signal->tx_signal, 1); } else { - digital_signal_append(nfca_signal->tx_signal, nfca_signal->zero); + digital_sequence_add(nfca_signal->tx_signal, 0); } } @@ -102,7 +91,7 @@ NfcaSignal* nfca_signal_alloc() { nfca_signal->zero = digital_signal_alloc(10); nfca_add_bit(nfca_signal->one, true); nfca_add_bit(nfca_signal->zero, false); - nfca_signal->tx_signal = digital_signal_alloc(NFCA_SIGNAL_MAX_EDGES); + nfca_signal->tx_signal = digital_sequence_alloc(NFCA_SIGNAL_MAX_EDGES); return nfca_signal; } @@ -112,7 +101,7 @@ void nfca_signal_free(NfcaSignal* nfca_signal) { digital_signal_free(nfca_signal->one); digital_signal_free(nfca_signal->zero); - digital_signal_free(nfca_signal->tx_signal); + digital_sequence_free(nfca_signal->tx_signal); free(nfca_signal); } @@ -121,17 +110,19 @@ void nfca_signal_encode(NfcaSignal* nfca_signal, uint8_t* data, uint16_t bits, u furi_assert(data); furi_assert(parity); - nfca_signal->tx_signal->edge_cnt = 0; - nfca_signal->tx_signal->start_level = true; - // Start of frame - digital_signal_append(nfca_signal->tx_signal, nfca_signal->one); + digital_sequence_clear(nfca_signal->tx_signal); + + /* add a >80/fs phase with no transition, which is >10 1-bits */ + for(int tr1_bit = 0; tr1_bit < 11; tr1_bit++) { + digital_sequence_add(nfca_signal->tx_signal, 1); + } if(bits < 8) { for(size_t i = 0; i < bits; i++) { if(FURI_BIT(data[0], i)) { - digital_signal_append(nfca_signal->tx_signal, nfca_signal->one); + digital_sequence_add(nfca_signal->tx_signal, 1); } else { - digital_signal_append(nfca_signal->tx_signal, nfca_signal->zero); + digital_sequence_add(nfca_signal->tx_signal, 0); } } } else { diff --git a/lib/nfc/protocols/nfca.h b/lib/nfc/protocols/nfca.h index 498ef2843..aad1a4fd8 100644 --- a/lib/nfc/protocols/nfca.h +++ b/lib/nfc/protocols/nfca.h @@ -8,7 +8,7 @@ typedef struct { DigitalSignal* one; DigitalSignal* zero; - DigitalSignal* tx_signal; + DigitalSequence* tx_signal; } NfcaSignal; uint16_t nfca_get_crc16(uint8_t* buff, uint16_t len); diff --git a/lib/nfc/protocols/nfcv.c b/lib/nfc/protocols/nfcv.c index aed0023cd..42dbd0ded 100644 --- a/lib/nfc/protocols/nfcv.c +++ b/lib/nfc/protocols/nfcv.c @@ -215,7 +215,7 @@ void nfcv_emu_alloc() { if(!nfcv_signal) { /* assuming max frame length is 255 bytes */ - nfcv_signal = digital_sequence_alloc(8 * 255 + 2, nfcv_out_io); + nfcv_signal = digital_sequence_alloc(8 * 255 + 2); } if(!nfcv_resp_unmod_256) { @@ -297,7 +297,7 @@ void nfcv_emu_send_raw(uint8_t* data, uint8_t length) { digital_sequence_add(nfcv_signal, SIG_EOF); FURI_CRITICAL_ENTER(); - digital_sequence_send(nfcv_signal); + digital_sequence_send(nfcv_signal, nfcv_out_io); FURI_CRITICAL_EXIT(); furi_hal_gpio_write(nfcv_out_io, false); }