mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-06-11 19:33:30 -07:00
reworked nfca signal generation, added idle time before sending response
This commit is contained in:
+21
-44
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user