diff --git a/lib/nfc/protocols/nfca.c b/lib/nfc/protocols/nfca.c index 9c3a74575..6d0fc20b3 100644 --- a/lib/nfc/protocols/nfca.c +++ b/lib/nfc/protocols/nfca.c @@ -8,19 +8,12 @@ #define NFCA_CRC_INIT (0x6363) #define NFCA_F_SIG (13560000.0) /* [Hz] NFC frequency */ -#define NFCA_F_SUB (NFCA_F_SIG/16) /* [Hz] NFC subcarrier frequency fs/16 (847500 Hz) */ +#define NFCA_F_SUB (NFCA_F_SIG / 16) /* [Hz] NFC subcarrier frequency fs/16 (847500 Hz) */ #define T_SUB (1000000000000.0f / NFCA_F_SUB) /* [ps] subcarrier period = 1/NFCA_F_SUB (1.18 µs) */ -#define T_SUB_PHASE (T_SUB/2) /* [ps] a single subcarrier phase (590 µs) */ +#define T_SUB_PHASE (T_SUB / 2) /* [ps] a single subcarrier phase (590 µs) */ #define NFCA_SIGNAL_MAX_EDGES (1350) -#define SEQ_SOF 0 -#define SEQ_BIT0 1 -#define SEQ_BIT1 2 -#define SEQ_EOF 3 -#define SEQ_IDLE 4 - - typedef struct { uint8_t cmd; uint8_t param; @@ -72,32 +65,27 @@ bool nfca_emulation_handler( 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_sequence_add(nfca_signal->tx_signal, SEQ_BIT1); + digital_signal_append(nfca_signal->tx_signal, nfca_signal->seq_d); } else { - digital_sequence_add(nfca_signal->tx_signal, SEQ_BIT0); + digital_signal_append(nfca_signal->tx_signal, nfca_signal->seq_e); } } if(parity) { - digital_sequence_add(nfca_signal->tx_signal, SEQ_BIT1); + digital_signal_append(nfca_signal->tx_signal, nfca_signal->seq_d); } else { - digital_sequence_add(nfca_signal->tx_signal, SEQ_BIT0); + digital_signal_append(nfca_signal->tx_signal, nfca_signal->seq_e); } } static void nfca_add_modulation(DigitalSignal* signal, size_t phases) { for(size_t i = 0; i < phases; i++) { - signal->edge_timings[signal->edge_cnt++] = DIGITAL_SIGNAL_PS(T_SUB_PHASE); + bool modulated = (i % 2 == 0); + digital_signal_add_pulse(signal, DIGITAL_SIGNAL_PS(T_SUB_PHASE), modulated); } } static void nfca_add_silence(DigitalSignal* signal, size_t phases) { - bool end_level = signal->start_level ^ ((signal->edge_cnt % 2) == 0); - - if((signal->edge_cnt == 0) || end_level) { - signal->edge_timings[signal->edge_cnt++] = DIGITAL_SIGNAL_PS(phases * T_SUB_PHASE); - } else { - signal->edge_timings[signal->edge_cnt - 1] += DIGITAL_SIGNAL_PS(phases * T_SUB_PHASE); - } + digital_signal_add_pulse(signal, DIGITAL_SIGNAL_PS(phases*T_SUB_PHASE), false); } NfcaSignal* nfca_signal_alloc() { @@ -109,29 +97,16 @@ NfcaSignal* nfca_signal_alloc() { nfca_signal->seq_f = digital_signal_alloc(10); /* SEQ D has the first half modulated, used as SOF */ - nfca_signal->seq_d->start_level = true; nfca_add_modulation(nfca_signal->seq_d, 8); nfca_add_silence(nfca_signal->seq_d, 8); /* SEQ E has the second half modulated */ - nfca_signal->seq_e->start_level = false; nfca_add_silence(nfca_signal->seq_e, 8); nfca_add_modulation(nfca_signal->seq_e, 8); /* SEQ F is just no modulation, used as EOF */ - nfca_signal->seq_f->start_level = false; nfca_add_silence(nfca_signal->seq_f, 16); - - nfca_signal->tx_signal = digital_sequence_alloc(NFCA_SIGNAL_MAX_EDGES); - - /* we are dealing with shorter sequences, enable bake-before-sending */ - nfca_signal->tx_signal->bake = true; - - digital_sequence_set_signal(nfca_signal->tx_signal, SEQ_SOF, nfca_signal->seq_d); - digital_sequence_set_signal(nfca_signal->tx_signal, SEQ_BIT0, nfca_signal->seq_e); - digital_sequence_set_signal(nfca_signal->tx_signal, SEQ_BIT1, nfca_signal->seq_d); - digital_sequence_set_signal(nfca_signal->tx_signal, SEQ_EOF, nfca_signal->seq_f); - digital_sequence_set_signal(nfca_signal->tx_signal, SEQ_IDLE, nfca_signal->seq_f); + nfca_signal->tx_signal = digital_signal_alloc(NFCA_SIGNAL_MAX_EDGES); return nfca_signal; } @@ -142,7 +117,7 @@ void nfca_signal_free(NfcaSignal* nfca_signal) { digital_signal_free(nfca_signal->seq_d); digital_signal_free(nfca_signal->seq_e); digital_signal_free(nfca_signal->seq_f); - digital_sequence_free(nfca_signal->tx_signal); + digital_signal_free(nfca_signal->tx_signal); free(nfca_signal); } @@ -151,18 +126,21 @@ void nfca_signal_encode(NfcaSignal* nfca_signal, uint8_t* data, uint16_t bits, u furi_assert(data); furi_assert(parity); - digital_sequence_clear(nfca_signal->tx_signal); + nfca_signal->tx_signal->edge_cnt = 0; + nfca_signal->tx_signal->start_level = true; - /* add some idle bit times before SOF in case the GPIO was active */ - digital_sequence_add(nfca_signal->tx_signal, SEQ_IDLE); - digital_sequence_add(nfca_signal->tx_signal, SEQ_SOF); + // Start of frame + digital_signal_append(nfca_signal->tx_signal, nfca_signal->seq_f); + digital_signal_append(nfca_signal->tx_signal, nfca_signal->seq_f); + digital_signal_append(nfca_signal->tx_signal, nfca_signal->seq_f); + digital_signal_append(nfca_signal->tx_signal, nfca_signal->seq_d); if(bits < 8) { for(size_t i = 0; i < bits; i++) { if(FURI_BIT(data[0], i)) { - digital_sequence_add(nfca_signal->tx_signal, SEQ_BIT1); + digital_signal_append(nfca_signal->tx_signal, nfca_signal->seq_d); } else { - digital_sequence_add(nfca_signal->tx_signal, SEQ_BIT0); + digital_signal_append(nfca_signal->tx_signal, nfca_signal->seq_e); } } } else { @@ -170,6 +148,5 @@ void nfca_signal_encode(NfcaSignal* nfca_signal, uint8_t* data, uint16_t bits, u nfca_add_byte(nfca_signal, data[i], parity[i / 8] & (1 << (7 - (i & 0x07)))); } } - - digital_sequence_add(nfca_signal->tx_signal, SEQ_EOF); + digital_signal_append(nfca_signal->tx_signal, nfca_signal->seq_f); } diff --git a/lib/nfc/protocols/nfca.h b/lib/nfc/protocols/nfca.h index 82fb3e334..7acd1fb95 100644 --- a/lib/nfc/protocols/nfca.h +++ b/lib/nfc/protocols/nfca.h @@ -9,7 +9,7 @@ typedef struct { DigitalSignal* seq_d; /* sequence D, modulation with subcarrier during first half */ DigitalSignal* seq_e; /* sequence E, modulation with subcarrier during second half */ DigitalSignal* seq_f; /* sequence F, no modulation at all */ - DigitalSequence* tx_signal; + DigitalSignal* tx_signal; } NfcaSignal; uint16_t nfca_get_crc16(uint8_t* buff, uint16_t len);