Smartbadge epaper custom board using nrf5340/nrf7002, with an NFC loop to allow NFC card emulation/communication. Building using NCS2.9 with sysbuild.
I want to be able to dynamically change my NFC card emulation under user control, between
-off (no emulation response)
- type 2 card with NDEF
- type 4 card with NDEF
- type 4 ISODEP APDU cmd/response
Looking at the NFC samples I created code that looks like this:
bool nfcmgr_enable(nfc_ref_t inst, nfc_card_type_t ctype, nfc_cb_t cb_fn, void* cb_ctx) { if (inst==NULL) { return false; } struct _nfc_ctx* ctx = (struct _nfc_ctx*)inst; ctx->cb_fn = cb_fn; ctx->cb_ctx = cb_ctx; ctx->ctype = ctype; //uint8_t selres = 0x00; // TBD do we need to play with SEL_RES (aka SAK)? //nfc_t4t_parameter_set(NFC_T4T_PARAM_SELRES, &selres, 1); switch (ctype) { case NFC_TYPE4_APDU: { // register with nfc_t4t if (ctx->setupdone==false) { int ret = nfc_t4t_setup(_nfc_t4t_apdu_cb, &_ctx); if (ret!=0) { log_warn("nfcmgr : could not setup nfc_t4t library for APDU operation, error %d", ret); return false; } } nfc_t4t_emulation_start(); ctx->enabled = true; break; } case NFC_TYPE2_NDEF: { // else type 2 also possible as a simple data storage tag only (no ISODEP) // register with nfc_t4t #ifdef CONFIG_NFC_T2T_NRFXLIB if (ctx->setupdone==false) { int ret = nfc_t2t_setup(_nfc_t2t_cb, &_ctx); if (ret==0) { log_warn("nfcmgr : could not setup nfc_t2t library for basic NDEF card, error %d", ret); return false; } } ctx->setupdone = true; nfc_t2t_payload_raw_set(ctx->ndef_buff, MAXLEN_NDEF); //ctx->ndef_sz); nfc_t2t_emulation_start(); ctx->enabled = true; #else /* CONFIG_NFC_T2T_NRFXLIB*/ log_warn("nfcmgr : nfc_t2t library not enabled"); #endif /* CONFIG_NFC_T2T_NRFXLIB*/ break; } case NFC_TYPE4_NDEF: { // register with nfc_t4t if (ctx->setupdone==false) { int ret = nfc_t4t_setup(_nfc_t4t_ndef_cb, &_ctx); if (ret!=0) { log_warn("nfcmgr : could not setup nfc_t4t library for basic NDEF card, error %d", ret); return false; } } ctx->setupdone = true; nfc_t4t_ndef_rwpayload_set(ctx->ndef_buff, MAXLEN_NDEF); //ctx->ndef_sz); nfc_t4t_emulation_start(); ctx->enabled = true; break; } default: { log_warn("nfcmgr : could not setup unknown mode %d", ctx->ctype); return false; } } return true; } void nfcmgr_disable(nfc_ref_t inst) { if (inst==NULL) { return; } struct _nfc_ctx* ctx = (struct _nfc_ctx*)inst; ctx->cb_fn = NULL; ctx->cb_ctx = NULL; log_warn("nfcmgr : nfc disable disabled as crashes..."); #ifdef CRASH if (ctx->enabled) { switch (ctx->ctype) { case NFC_TYPE4_NDEF: { nfc_t4t_emulation_stop(); nfc_t4t_done(); // release NFC periph break; } case NFC_TYPE4_APDU: { nfc_t4t_emulation_stop(); nfc_t4t_done(); // release NFC periph break; } case NFC_TYPE2_NDEF: { #ifdef CONFIG_NFC_T2T_NRFXLIB nfc_t2t_emulation_stop(); nfc_t2t_done(); // release NFC periph #endif /* CONFIG_NFC_T2T_NRFXLIB*/ break; } default: { log_warn("nfcmgr : could not disable unknown mode %d", ctx->ctype); break; } } } #endif ctx->enabled = false; }
It works to enable the NFC operation the first time eg for type 4 using the ndef library to do the HL exchanges.
I am experiencing a problem to disable the nfc emulation, as when I call nfc_t4t_emulation_stop() it fails the assert
NRFX_ASSERT(m_nfct_cb.state == NRFX_DRV_STATE_INITIALIZED);
in nrfc_nfct_disable(void) in modules/hal/nordic/nrfx/drivers/src/nrfx_nfct.c
This is called from nfc_t4t_emulation_stop() via the RPC mechanism (not sure why the code uses this by the way?)
Given the emulation was working, I don't see why the state is now not initialized?
Ay ideas on how to use the nfc driver/libraries in this way? For the moment as you can see I have just ifdef'd out the code, but it means I cannot change the NFC mode on the fly or disable it once its enabled....
thanks