T4T tag callback blocks

Hello,

I am trying to develop an application where I can turn on/off the NFC T4T tag emulation using interrupt-driven buttons.

However, after the first read of the NFC tag, only NFC callback events can be run, while blocking any other code to run(Including button interrupts, and logging).

I couldn't solve the issue by myself, and I would appreciate it if you can help.

I attached my code below.

/*
 * Copyright (c) 2018 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
 */

#include <zephyr/kernel.h>
#include <zephyr/sys/reboot.h>

#include <nfc_t4t_lib.h>
#include <nfc/t4t/ndef_file.h>
#include <nfc/ndef/msg.h>
#include <nfc/ndef/text_rec.h>

#include <dk_buttons_and_leds.h>

#define MAX_REC_COUNT		1
#define NDEF_MSG_BUF_SIZE	128

#define NFC_FIELD_LED		DK_LED1
#define NFC_SW_BUTTON 		DK_BTN1_MSK

int nfc_state;

/* Text message in English with its language code. */
static const uint8_t en_payload[] = {
	'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!'
};
static const uint8_t en_code[] = {'e', 'n'};

/* Buffer used to hold an NFC NDEF message. */
static uint8_t ndef_msg_buf[NDEF_MSG_BUF_SIZE];


static void nfc_callback(void *context,
			 nfc_t4t_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_T4T_EVENT_FIELD_ON:
		dk_set_led_on(NFC_FIELD_LED);
		break;
	case NFC_T4T_EVENT_FIELD_OFF:
		dk_set_led_off(NFC_FIELD_LED);
		break;
	default:
		break;
	}
}


/**
 * @brief Function for encoding the NDEF text message.
 */
static int welcome_msg_encode(uint8_t *buffer, uint32_t *len)
{
	int 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),
				      en_payload,
				      sizeof(en_payload));

	/* Create NFC NDEF message description, capacity - MAX_REC_COUNT
	 * records
	 */
	NFC_NDEF_MSG_DEF(nfc_text_msg, MAX_REC_COUNT);

	/* 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 first record!\n");
		return err;
	}
	
	err = nfc_ndef_msg_encode(&NFC_NDEF_MSG(nfc_text_msg),
				      buffer,
				      len);
	if (err < 0) {
		printk("Cannot encode message!\n");
	}

	return err;
}

static void button_changed(uint32_t button_state, uint32_t has_changed)
{
	int err;
	if (has_changed & NFC_SW_BUTTON) {
		uint32_t user_button_state = button_state & NFC_SW_BUTTON;

		if (user_button_state == 1) {
			if (nfc_state == 1) {
				err = nfc_t4t_emulation_stop();
				if (err) {
					printk("Cannot stop emulation\n");
				} else {
					printk("Emulation stopped\n");
					nfc_state = 0;
				}
			} else {
				err = nfc_t4t_emulation_start();
				if (err) {
					printk("Cannot start emulation\n");
				} else {
					printk("Emulation started\n");
					nfc_state = 1;
				}
			}
		}
	}
}

int main(void)
{
	uint32_t len = nfc_t4t_ndef_file_msg_size_get(sizeof(ndef_msg_buf));

	printk("Starting NFC Text Record example\n");

	/* Configure LED-pins as outputs */
	if (dk_leds_init() < 0) {
		printk("Cannot init LEDs!\n");
		goto fail;
	}

	if (dk_buttons_init(button_changed) < 0) {
		printk("Cannot init buttons!\n");
		goto fail;
	}


	/* Set up NFC */
	if (nfc_t4t_setup(nfc_callback, NULL) < 0) {
		printk("Cannot setup NFC T2T library!\n");
		goto fail;
	}


	/* Encode welcome message */
	if (welcome_msg_encode(nfc_t4t_ndef_file_msg_get(ndef_msg_buf), &len) < 0) {
		printk("Cannot encode message!\n");
		goto fail;
	}

	nfc_t4t_ndef_file_encode(ndef_msg_buf, &len);

	/* Set created message as the NFC payload */
	if (nfc_t4t_ndef_rwpayload_set(ndef_msg_buf, sizeof(ndef_msg_buf)) < 0) {
		printk("Cannot set payload!\n");
		goto fail;
	}


	/* Start sensing NFC field */
	if (nfc_t4t_emulation_start() < 0) {
		printk("Cannot start emulation!\n");
		goto fail;
	}
	nfc_state = 1;

	printk("NFC configuration done\n");

	return 0;

fail:
#if CONFIG_REBOOT
	sys_reboot(SYS_REBOOT_COLD);
#endif /* CONFIG_REBOOT */

	return -EIO;
}

  • Hello,

    What version of NCS are you using? Is it possible to zip your entire application folder, including all the .conf files and upload them here, so that I will have the same setup that you are testing on?

    Best regards,

    Edvin

  • Hi Edvin, 

    Thanks for reaching out. I use NCS latest version 2.3.0. I attached the zip file below.

    Also, while trying to debug, I noticed that after tag is read and right before blocking, callback receives "Field detected" event although the polling device (phone) is taken away.

    writable_ndef_msg.zip 

  • Hello,

    generated_hex_file.hex

    This is the .hex file that was produced when I built your sample (I renamed it. It was called zephyr.hex inside build\zephyr\)

    Are you experimenting on a DK? If so, can you please try to program this file to your DK? You can use either nRF Connect for Desktop -> Programmer, or if you have nrfjprog (nRF Command Line Tools) installed, you can use the command:

    nrfjprog --program generated_hex_file.hex --verify --reset

    When I am running this on a DK, this is my behavior:

    So as you can see, I can still receive button interrupts after using the NFC. Do you see the same if you program with the same .hex file? I just want to check whether there are any external factors that could be the cause, or if it may be part of the SDK that is changed, or perhaps a HW issue.

    Do you see the error all the time? By this, I mean every time you read the NFC tag, the application freeses? Do you see the NFC data on the phone? 

    Best regards,

    Edvin

  • Hello!

    I flashed the .hex file to my DK, but the issue remains.

    Here in the picture below, after the last "Field Detected" event, the phone shows the tag is read and I can see the data, but the application freezes for some time. After this, if I move around the phone near the tag, it unfreezes, starts receiving NFC events until the tag is read and it freezes again.

    But if I take away the phone from the tag when it is read and the freeze happened, nothing can unfreeze the application.

Related