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

nRF52 write NFC Tag

Hi,

I am not yet familiar with NFC and have a question about using NFC with the nRF52.

If I understood it correctly the nRF52 is a "listening device" i.e. it cannot generate a NFC field and write data to another device. But is it possible to send/write data from another device (for example a smartphone) to the NFC tag of the nRF52. Or is it only possible to read data from the tag? If it is not possible at the moment will it be possible in the future?

I am using a nRF52 development kit with nRF5 SDK 11.0.0-2.alpha.

Thanks, Alex

  • Use case: I would like be able to write to the nRF52 via NFC to program the UUID, advertising interval, and transmit power level used by the Bluetooth beacon. Is there any new information whether writing to the nRF52 via NFC will be supported?

  • @CR: It is possible to write to the tag, what is missing is software support in the SDK. You have the possibility of writing the software yourself; see the nRF52 series product specification for hardware features, and the specifications for Tag Type 2 for the software. You can also implement Tag Type 4, but that will be more complex.

  • Is there any news about tag writing? I would like to store some information on the nRF52 for binding porpuses.

  • Hello,

    The write NFC Tag is now enabled :)

    I've removed the libnfc library because it didn't support the write feature, and no documentation is provided by Nordic to manage it. Furthermore the library gives information to the host (the NFC reader), that the card is NOT writable. So the host will never send the write request (0xA2).

    What exactly does this library? It simulates a Type2 NFC buffer card, and provided data to the HAL driver. I've replaced it, by a function who sends the buffer content with the right datas.

    static uint8_t Test_Memory_Type2[NFC_MAX_PAYLOAD_SIZE_RAW] = {
    	// page 0
    	0x5F, 0xF6, 0x4C, 0x6D,	// Internal 0-3
    	0x2F, 0xF4, 0xDA, 0x59,	// Internal 4-7
    	0x58, 0x03, 0x00, 0x00, // Internal 8-9 | Lock0-1       // <-- makes the card writable !
    	0xE1, 0x11, 0x7C, 0x00, // CC0-3						// <-- makes the card writable !
    	// page 4
    	0x03, 0x16, 0xC1, 0x01,	// TLV Tag field, Length field, Value field
    	0x00, 0x00, 0x00, 0x0F, // NDEF Payload length 15
    	0x54, 0x02, 0x65, 0x6E, // NDEF Message Type : Text UTF8, "Hello World!"
    	0x48, 0x65, 0x6C, 0x6C, //
    	// page 8
    	0x6F, 0x20, 0x57, 0x6F,
    	0x72, 0x6C, 0x64, 0x21, //
    	0x00, 0x00, 0x00, 0x00,
    	0x00, 0x00, 0x00, 0x00,
    };
    

    I've linked directly the application calls to the HAL functions to check if it's working

    ret_val = nfcSetup(nfc_callback, NULL);
    

    replaced by ret_val = hal_nfc_setup(nfc_callback, NULL);

    welcome_msg_encode(ndef_msg_buf, &len);
    ret_val = nfcSetPayload( (char*)ndef_msg_buf, len);	
    

    no need because the buffer is already set with the right datas

    ret_val = nfcStartEmulation();
    

    replaced by ret_val = hal_nfc_start();

    So the main function looks like this below :

    int main(void) {
    	NfcRetval ret_val;
    
    	printf("nfc_1 start\n");
    
    	uint32_t err_code = NRF_LOG_INIT();
    	APP_ERROR_CHECK(err_code);
    
    	/* Configure LED-pins as outputs */
    	LEDS_CONFIGURE(BSP_LED_0_MASK);
    	LEDS_OFF(BSP_LED_0_MASK);
    
    	ret_val = hal_nfc_setup(nfc_callback, NULL); // <-- callback to to application 
    	APP_ERROR_CHECK(ret_val);
    
    	// Start sensing NFC field
    	ret_val = hal_nfc_start();
    	APP_ERROR_CHECK(ret_val);
    	while(1)
    	{
    		if (!NFC_NEED_MCU_RUN_STATE())
    		{
    			__WFE();
    		}
    	}
    return 0;
    }
    

    And I've added the read & write command inside the NFCT_IRQHandler !

    ...
    if (NRF_NFCT->EVENTS_RXFRAMEEND && (NRF_NFCT->INTEN & NFCT_INTEN_RXFRAMEEND_Msk))
    {
        /* Take into account only number of whole bytes */
        uint32_t rx_data_size = ((NRF_NFCT->RXD.AMOUNT & NFCT_RXD_AMOUNT_RXDATABYTES_Msk) >> NFCT_RXD_AMOUNT_RXDATABYTES_Pos);
    
        nrf_nfct_event_clear(&NRF_NFCT->EVENTS_RXFRAMEEND);
    
    	if (rx_data_size>NFC_CRC_SIZE) {
    		rx_data_size -= NFC_CRC_SIZE;
    
    		LOG_HAL_NFC("[NFC_HAL]: rx %02X [%02X]\r\n", m_nfc_rx_buffer[0], m_nfc_rx_buffer[1]);
    
            switch (m_nfc_rx_buffer[0]) {
    
            case T2T_READ_CMD :		// 30h
            	{
    				uint8_t BNo = m_nfc_rx_buffer[1];
    				if (BNo<252) /* Max Block number */
    					hal_nfc_send(&Test_Memory_Type2[BNo*4], 16);
    				else 
    					/* hal_nfc_send(&Dymamic_Memory_Aera[0], 16); */
    					hal_send_ack_nack(0x0);	// NAck
            	}
            	break;
    
    
    
            case T2T_WRITE_CMD :	// A2h
            	{
    				uint8_t BNo = m_nfc_rx_buffer[1];
    				if (rx_data_size==6) {
    					LOG_HAL_NFC("[NFC_HAL]: receive");
    					uint8_t i, c;
    					for (i=0;i<4;i++) {
    						c = m_nfc_rx_buffer[2+i];
    						Test_Memory_Type2[BNo*4 + i] = c;
    						NRF_LOG_PRINTF(" %02X", c);
    					}
    					NRF_LOG_PRINTF("\n");
    
    					hal_send_ack_nack(0xA);	// Ack for write command
    				} else {
    					hal_send_ack_nack(0x0);	// NAck for write command : should be 0, 1, 4 or 5
    				}
            	}
            	break;
    
            case NFC_SLP_REQ_CMD :
            	LOG_HAL_NFC("[NFC_HAL]: SLP_REQ\r\n");
            	m_slp_req_received = true;
    
            default:
            	/* Not a READ Command, so wait for next frame reception */
            	NRF_NFCT->TASKS_ENABLERXDATA = 1;
            	break;
    
            }
    	}
    ...
    

    the HAL send functions are listed below:

    /**
     * send data to the host (the reader) with CRC16 
     */
    hal_nfc_retval hal_nfc_send(const uint8_t *data, size_t dataLength)
    {
    	if (dataLength == 0)
    	{
    		return HAL_NFC_RETVAL_INVALID_SIZE;
    	}
    
    	
    	/* Ignore previous TX END events, SW takes care only for data frames which tranmission is triggered in this function */
    	nrf_nfct_event_clear(&NRF_NFCT->EVENTS_TXFRAMEEND);
    
    	NRF_NFCT->PACKETPTR     = (uint32_t)(data);
    	NRF_NFCT->TXD.AMOUNT    = (dataLength << NFCT_TXD_AMOUNT_TXDATABYTES_Pos) & NFCT_TXD_AMOUNT_TXDATABYTES_Msk;
    
    	uint32_t reg = 0;
    	reg |= (NFCT_TXD_FRAMECONFIG_PARITY_Parity << NFCT_TXD_FRAMECONFIG_PARITY_Pos);
    	reg |= (NFCT_TXD_FRAMECONFIG_DISCARDMODE_DiscardStart << NFCT_TXD_FRAMECONFIG_DISCARDMODE_Pos);
    	reg |= (NFCT_TXD_FRAMECONFIG_SOF_SoF << NFCT_TXD_FRAMECONFIG_SOF_Pos);
    	reg |= (NFCT_TXD_FRAMECONFIG_CRCMODETX_CRC16TX << NFCT_TXD_FRAMECONFIG_CRCMODETX_Pos);
    	NRF_NFCT->TXD.FRAMECONFIG  = reg;
    
    	NRF_NFCT->INTENSET      = (NFCT_INTENSET_TXFRAMEEND_Enabled << NFCT_INTENSET_TXFRAMEEND_Pos);
    	NRF_NFCT->TASKS_STARTTX = 1;
    
    	LOG_HAL_NFC("[NFC_HAL]: send");
    	uint8_t i;
    	for (i=0;i<dataLength;i++) {
    		NRF_LOG_PRINTF(" %02X", *(data+i));
    	}
    
    	NRF_LOG_PRINTF("\n");
    
    
    	return HAL_NFC_RETVAL_OK;
    }
    
    /**
     * send a ack or nack to the host (the reader) without CRC16
     */
    static hal_nfc_retval hal_send_ack_nack(uint8_t ack_nack_code) {
    	static uint8_t Ack;
    	Ack = ack_nack_code;
    
    	nrf_nfct_event_clear(&NRF_NFCT->EVENTS_TXFRAMEEND);
    
    	NRF_NFCT->PACKETPTR     = (uint32_t)(&Ack);
    	NRF_NFCT->TXD.AMOUNT    =  4;
    
    	uint32_t reg = 0;
    	/* reg |= (NFCT_TXD_FRAMECONFIG_PARITY_Parity << NFCT_TXD_FRAMECONFIG_PARITY_Pos); */
    	reg |= (NFCT_TXD_FRAMECONFIG_SOF_SoF << NFCT_TXD_FRAMECONFIG_SOF_Pos);
    	NRF_NFCT->TXD.FRAMECONFIG  = reg;
    	NRF_NFCT->INTENSET      = (NFCT_INTENSET_TXFRAMEEND_Enabled << NFCT_INTENSET_TXFRAMEEND_Pos);
    	NRF_NFCT->TASKS_STARTTX = 1;
    
    	return HAL_NFC_RETVAL_OK;
    }
    

    Et voila !

  • Hi I have recently started developing with nordifc nrf52, andi have some doubts. Could you post the full program?. I have found several mistakes. With this code you are able to write via NFC in your nrf52? Thanks

Related