nRF52833-based board, software is based on Zephyr and Nordic SDK 2.1.2.
Using Tag 2 type driver library, nfc_t2t
Occasionally, when NFC coil is tapped, we observe one of the NFC pins stuck driving 1.75V when it is expected to float.
Board recovers on reset, but we would like to understand why it is happening and how to work around it in software
We managed to connect JTAG to board in this "stuck" state, read some NFC related registers,
noticed that EVENTS_RXFRAMESTART event has been generated but EVENTS_RXFRAMEEND hasn't been.
Also noticed that RXD.AMOUNT that in successful case reads 0xFFF and 0x7 in stuck case, i.e. the RXDATABYTES is the same (7) in both cases but RXDATABITS is 0 in stuck case
indicating that last byte has not been received properly (framing error) ?
Also browsed nrfx_nfct driver code, and I don't see how would it get past the situation where nrfx_nfct_irq_handler NEVER RECEIVES RXFRAMEEND event...
So my 1st question is - how can I prevent this condition from happening ?
2nd question - if it can't be prevented - how can I recover from it in firmware ? I don't know when device will be tapped, so can't set timers of my own
My NFC T2T init code
nt nfc_init(void) { int err; uint32_t len = sizeof(ndef_msg_buf); /* Set up NFC */ err = nfc_t2t_setup(nfc_callback, NULL); if (err) { printk("NFC: Cannot setup NFC T2T library!\n"); return err; } /* Create NFC NDEF text record description in English */ NFC_NDEF_TEXT_RECORD_DESC_DEF(nfc_en_text_rec, UTF_8, en_code, sizeof(en_code), fetch_serial_num(), SERIAL_NUMBER_LENGTH); /* Create NFC NDEF message description, capacity - 1 */ NFC_NDEF_MSG_DEF(nfc_text_msg, 1); /* Add text records to NDEF text message */ err = nfc_ndef_msg_record_add(&NFC_NDEF_MSG(nfc_text_msg), &NFC_NDEF_TEXT_RECORD_DESC(nfc_en_text_rec)); if (err < 0) { printk("Cannot add serial number in NFC!\n"); return err; } err = nfc_ndef_msg_encode(&NFC_NDEF_MSG(nfc_text_msg), ndef_msg_buf, &len); if (err < 0) { printk("Cannot encode message!\n"); } /* Set created message as the NFC payload */ err = nfc_t2t_payload_set(ndef_msg_buf, len); if (err) { printk("NFC: Cannot set payload!\n"); return err; } k_work_init(&start_ble_advertising_worker, start_ble_advertising); return err; }
Which is followed by call to
int nfc_sense_start(void) { int err; err = nfc_t2t_emulation_start(); if (err) { printk("Cannot start emulation!\n"); return err; } return err; }
The callback
static void nfc_callback(void *context, nfc_t2t_event_t event, const uint8_t *data, size_t data_length) { ARG_UNUSED(context); ARG_UNUSED(data); ARG_UNUSED(data_length); switch (event) { case NFC_T2T_EVENT_FIELD_ON: printk("NFC: Field ON\n"); if (true == ble_init_success) { k_work_submit(&start_ble_advertising_worker); } else { printk("Don't start advertising on connectable profile - BLE failed to initialize\n"); } break; case NFC_T2T_EVENT_FIELD_OFF: printk("NFC: Field OFF\n"); default: break; } }