This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

NFC tag stops working suddenly in very rare cases

We are using nRF52840 on a custom board with nRF5 SDK v15.3.0.

Our application uses the NFCT driver (nrfx_nfct) along with nfc_t2t_lib_gcc.a to emulate a NFC tag with some text records. I am using an Android phone to read the tag. This is working fine most of the time. But in very rare cases the NFC tag stops working suddenly and cannot be read anymore. Only a Reset helps.

If I enable the debug build (DEBUG_NRF macro), the processor runs into an assertion in nrf_drv_clock.c, line 328 ( ASSERT(m_clock_cb.hfclk_requests > 0); ). After a long debug session I found out, that in the error case the NFCT driver sends 2 times in a row the NRFX_NFCT_EVT_FIELD_LOST event. This event is handled in nfc_platform.c and calls nrf_drv_clock_hfclk_release(). This leads to the assertion in nrf_drv_clock.c, because the hfclk_requests counter is decremented twice.

The reason, why the NRFX_NFCT_EVT_FIELD_LOST event occurs twice, is that the NFCT IRQ handler got a FIELDDETECTED and a FIELDLOST IRQ at the same time. The handler ignores the FIELDDETECTED IRQ and just handle the FIELDLOST IRQ. Since the field was already off and the HF clock was already released, a second HF clock release leads to the error.

A possible solution for this bug is to add an if clause, which checks the field state in the nrfx_nfct_field_event_handler()  function, like this:

        case NRFX_NFC_FIELD_STATE_OFF:
            if (m_nfct_cb.field_on)
            {
                nrfx_nfct_state_force(NRFX_NFCT_STATE_SENSING);
#ifdef NRF52840_XXAA
                /* Begin: Bugfix for FTPAN-116 (IC-12886) */
                if (m_nrf52840.eng_a)
                {
                    *(volatile uint32_t *)0x40005010 = 1;
                }
                /* END: Bugfix for FTPAN-116 (IC-12886) */
#endif // NRF52840_XXAA
                nrf_nfct_int_disable(NRFX_NFCT_RX_INT_MASK | NRFX_NFCT_TX_INT_MASK);
                m_nfct_cb.field_on = false;
                nfct_evt.evt_id    = NRFX_NFCT_EVT_FIELD_LOST;
    
                NRFX_NFCT_CB_HANDLE(m_nfct_cb.config.cb, nfct_evt);
            }
            break;

Is this bug is already known?

I guess this bug is also present in older SDK's.

Related