cancel
Showing results for 
Search instead for 
Did you mean: 

ST25R100 NFC Tag Read Problems

William_RnD
Associate III

Hi everyone,

I’m trying to interface an ST25R100 NFC reader with my MCU, and I’m having trouble reading ISO15693 tags. My initialization seems to work, but I never get any response from the tag. I’m hoping someone can spot what I might be missing.

This is what my uart debugging spits out:
INIT - NFC
NFC: Init start (POR -> RESET -> POWER-DOWN -> Ready Mode)
ROP_REG_OPERATION = 0x00 (after PD write)
ROP_REG_GENERAL = 0x01 (after write)
ROP_REG_REGULATOR = 0x08 (after write)
NFC IRQ triggered!
IRQ: I_osc Oscillator ready
ROP_REG_OPERATION = 0x0A (after enable)
ROP_REG_OPERATION = 0x0A (check mode)
Chip is in READY mode (en = 1)
STATUS register = 0x00
NFC Reader Operation
ROP_REG_PROTOCOL = 0x85 (after write)
ROP_REG_OPERATION = 0x3A (after write)
NFC IRQ triggered!
IRQ: I_txe End of transmission
NFC IRQ triggered!
IRQ: I_nre No-response timer expired

This is consistent with what the datasheet says on page 22.

But now I don't quiet see how I can get it to read data from my NFC-Tag

void NFC_Init(void)
{
	uint8_t status, val;
	printf("\tNFC: Init start (POR -> RESET -> POWER-DOWN -> Ready Mode)\r\n");

	/* 1. Hardware reset: enter reset mode (optional if POR occurred) */
	HAL_GPIO_WritePin(NFC_RST_GPIO_Port, NFC_RST_Pin, GPIO_PIN_SET);
	HAL_Delay(10); // hold RESET low 10 ms
	/* 2. Release RESET pin */
	HAL_GPIO_WritePin(NFC_RST_GPIO_Port, NFC_RST_Pin, GPIO_PIN_RESET);
	HAL_Delay(2); // small delay for POR completion

	/* 3. Ensure device is in Power-Down mode (en = 0), (wk = 0) */
	NFC_WriteReg(ROP_REG_OPERATION, 0x00);
	val = NFC_ReadReg(ROP_REG_OPERATION);
	printf("\tROP_REG_OPERATION = 0x%02X (after PD write)\r\n", val);
	HAL_Delay(2);

	/* 4. Configure general register (safe in PD) */
	NFC_WriteReg(ROP_REG_GENERAL, 0x01);
	val = NFC_ReadReg(ROP_REG_GENERAL);
	printf("\tROP_REG_GENERAL = 0x%02X (after write)\r\n", val);

	/* 5. Configure regulators (recommended) */
	NFC_WriteReg(ROP_REG_REGULATOR, 0b00001000); // 3.26V
	val = NFC_ReadReg(ROP_REG_REGULATOR);
	printf("\tROP_REG_REGULATOR = 0x%02X (after write)\r\n", val);

	/* 6. Enable device: set en = 1 to transition to READY */
	NFC_WriteReg(ROP_REG_OPERATION, 0b00001010);
	val = NFC_ReadReg(ROP_REG_OPERATION);
	HAL_Delay(5);
	printf("\tROP_REG_OPERATION = 0x%02X (after enable)\r\n", val);

	/* 7. Verify device is in the correct mode */
	val = NFC_ReadReg(ROP_REG_OPERATION);
	printf("\tROP_REG_OPERATION = 0x%02X (check mode)\r\n", val);

	if ((val & 0x01) != 0)
	{
		printf("\tChip is in Wake up mode (wu_en = 1)\r\n");
	}
	else
	{
		printf("\tChip is in READY mode (en = 1)\r\n");
	}

	/* Optional: read STATUS register for additional info */
	status = NFC_ReadReg(ROP_REG_STATUS);
	printf("\tSTATUS register = 0x%02X\r\n", status);

	//init in reader mode
	configureReaderOperation();
	//NFC_WakeUpConfigure();
}


void configureReaderOperation(void)
{
	uint8_t val;

	printf_yellow("\tNFC Reader Operation\r\n");

	//1. Set protocol register: OM bits, TX rate, RX rate
	NFC_WriteReg(ROP_REG_PROTOCOL, 0b10000101);
	val = NFC_ReadReg(ROP_REG_PROTOCOL);
	printf("\tROP_REG_PROTOCOL = 0x%02X (after write)\r\n", val);

	// 2. Enable TX and RX in Operation register
	NFC_WriteReg(ROP_REG_OPERATION, 0b00111010);
	val = NFC_ReadReg(ROP_REG_OPERATION);
	printf("\tROP_REG_OPERATION = 0x%02X (after write)\r\n", val);

	HAL_Delay(10);

	//Recommended preparation and execution of a transceiver operation:
	// 1. Stop all activities
	NFC_DirectCmd(0x62); // stop all
	HAL_Delay(1);

	// 2. Reset Rx gain
	NFC_DirectCmd(0x66); // reset RX gain
	HAL_Delay(1);

	// 3. Configure timers
	NFC_WriteReg(ROP_REG_MRT, 0x10);
	NFC_WriteReg(ROP_REG_NRT1, 0x50); 

	// Define the length of data to be transmitted (ntx<12:0> and nbtx<2:0>)
	// 6. Prepare FIFO for transmission
	NFC_WriteReg(ROP_REG_TX_FRAME1, 0x26); // REQA command example
	NFC_WriteReg(ROP_REG_TX_FRAME2, 0x00); // unused here
	// set ntx = 7 bits, nbtx = 7 in relevant registers (datasheet Sec 5.10.1)

	//NFC_WriteReg(0x1C, 0x01);

	// 7. Send transmit command
	NFC_DirectCmd(0x6A); // Transmit Data
	//NFC_DirectCmd(0xE6); // MRT timer start

	// Now wait for I_txe IRQ to know TX finished

	// sq_en is enabled by default.
	// agc_en is enabled by default.
}

NFC-Tag:

- ISO 15693
- NfcV, Ndef technology
- 196 Bytes of data
Any help is greatly appreciated!

 

 

 

 

 

This discussion is locked. Please start a new topic to ask your question.
1 ACCEPTED SOLUTION

Accepted Solutions

Hi William,

you have probably downloaded the X-CUBE-NFC9 package and have used STM32CubeMx to generate the code (standalone version or embedded in STM32CubeIDE).

Make sure to follow the step by step Getting Started (in <homeDir>\STM32Cube\Repository\Packs\STMicroelectronics\X-CUBE-NFC9\1.0.0\Documentation)

In particular, Sofware Packs / Select Components:

BrianTIDAL_0-1769779397319.png

 

and in Middleware:

BrianTIDAL_1-1769779443985.png

then the nfc_conf.h file should be properly generated.

Note: as of today the X-CUBE-NFC9 does not include the NDEF middleware. You can retrieve this middleware from the ST25 Embedded Library as well as the ndef demo application from the ndef_rw demo project.

Feel free to send me your ioc file and I will check it.

Rgds

BT

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

View solution in original post

7 REPLIES 7
Brian TIDAL
ST Employee

Hi,

ST provides a middleware for the ST25R100 NFC readers: the RF Abstraction Layer (RFAL). This RFAL is available in the ST25 Embedded Library. It is portable and scalable C code. This library also includes NDEF API to read, write, encode et decode messages and various ready to use demos (such as NDEF read and write). I recommend using this library. 

Regarding the code:

// 6. Prepare FIFO for transmission
	NFC_WriteReg(ROP_REG_TX_FRAME1, 0x26); // REQA command example
	NFC_WriteReg(ROP_REG_TX_FRAME2, 0x00); // unused here
  1. REQA is dedicated to ISO14443-A technology, not for ISO15693. You may rather want to use an ISO15693 INVENTORY command.
  2. TX frame register 1 and TX frame register 2 define the length of data to be transmitted (ntx<12:0> and nbtx<2:0>). This is not designed to store the data to be sent. 0x26 0x00 is likely not the correct data size for a ISO15693 INVENTORY command
  3. The FIFO seems to be empty. An INVENTORY command such as 0x26 0x01 0x00 should be written to the FIFO and ntx (resp. nbtx) should be set to 3 (resp. 0) in the TX frame register 1 and TX frame register 2.

Rgds

BT

 

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Hi, 

Great, I didn't know these libraries excited for this chip.

A Problem I do encounter is when generating code, I get this error in nfc_conf.h

/**
  ******************************************************************************
  * @file           : nfc_conf.h
  * @brief          : This file contains definitions for the NFC9 components bus interfaces
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2026 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */


/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __NFC09A1_CONF_H__
#define __NFC09A1_CONF_H__

#ifdef __cplusplus
extern "C" {
#endif

FreeMarker template error (DEBUG mode; use RETHROW in production!):
The following has evaluated to null or missing:
==> SWIPdatas [in template "nfc_conf_h.ftl" at line 260, column 8]
----
Tip: If the failing expression is known to legally refer to something that's sometimes null or missing, either specify a default value like myOptionalVar!myDefault, or use [#if myOptionalVar??]when-present[#else]when-missing[/#if]. (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)??
----
----
FTL stack trace ("~" means nesting-related):
- Failed at: #list SWIPdatas as SWIP [in template "nfc_conf_h.ftl" at line 260, column 1]
----
Java stack trace (for programmers):
----
freemarker.core.InvalidReferenceException: [... Exception message was already printed; see it above ...]
at freemarker.core.InvalidReferenceException.getInstance(InvalidReferenceException.java:134)
at freemarker.core.Expression.assertNonNull(Expression.java:249)
at freemarker.core.IteratorBlock.acceptWithResult(IteratorBlock.java:104)
at freemarker.core.IteratorBlock.accept(IteratorBlock.java:94)
at freemarker.core.Environment.visit(Environment.java:370)
at freemarker.core.Environment.visitAndTransform(Environment.java:501)
at freemarker.core.CompressedBlock.accept(CompressedBlock.java:42)
at freemarker.core.Environment.visit(Environment.java:334)
at freemarker.core.Environment.visit(Environment.java:340)
at freemarker.core.Environment.process(Environment.java:313)
at freemarker.template.Template.process(Template.java:383)
at com.st.microxplorer.codegenerator.CodeEngine.freemarkerDo(CodeEngine.java:420)
at com.st.microxplorer.codegenerator.CodeEngine.genCode(CodeEngine.java:273)
at com.st.microxplorer.codegenerator.CodeGenerator.generateOutputCode(CodeGenerator.java:6459)
at com.st.microxplorer.codegenerator.CodeGenerator.generateSpecificCode(CodeGenerator.java:5281)
at com.st.microxplorer.codegenerator.CodeGenerator.generateSpecificCodeFile(CodeGenerator.java:1862)
at com.st.microxplorer.codegenerator.CodeGenerator.generateCodeFiles(CodeGenerator.java:2188)
at com.st.microxplorer.codegenerator.CodeGenerator.generateDefaultConfig(CodeGenerator.java:10991)
at com.st.microxplorer.codegenerator.CodeGenerator.generateCode(CodeGenerator.java:1593)
at com.st.microxplorer.plugins.projectmanager.engine.ProjectBuilder.generateCode(ProjectBuilder.java:3343)
at com.st.microxplorer.plugins.projectmanager.engine.ProjectBuilder.createCode(ProjectBuilder.java:2235)
at com.st.microxplorer.plugins.projectmanager.engine.ProjectBuilder.createProject(ProjectBuilder.java:819)
at com.st.microxplorer.plugins.projectmanager.engine.ProjectBuilder.createProject(ProjectBuilder.java:608)
at com.st.microxplorer.plugins.projectmanager.engine.MainProjectManager.startGenerateCode(MainProjectManager.java:1497)
at com.st.microxplorer.plugins.projectmanager.engine.MainProjectManager$3.onCommandEntered(MainProjectManager.java:283)
at com.st.components.util.CommandLineManager$3.run(CommandLineManager.java:175)
at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:308)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:773)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:720)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:714)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:742)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

 

The checkbox is also yellow, but it doesn't give a warning message something is wrong.

William_RnD_2-1769762001485.png

 

I have:  STM32CubeIDE Version: 1.19.0

Do you know a solution for this problem?
Kind Regards,
William

 

Hi William,

you have probably downloaded the X-CUBE-NFC9 package and have used STM32CubeMx to generate the code (standalone version or embedded in STM32CubeIDE).

Make sure to follow the step by step Getting Started (in <homeDir>\STM32Cube\Repository\Packs\STMicroelectronics\X-CUBE-NFC9\1.0.0\Documentation)

In particular, Sofware Packs / Select Components:

BrianTIDAL_0-1769779397319.png

 

and in Middleware:

BrianTIDAL_1-1769779443985.png

then the nfc_conf.h file should be properly generated.

Note: as of today the X-CUBE-NFC9 does not include the NDEF middleware. You can retrieve this middleware from the ST25 Embedded Library as well as the ndef demo application from the ndef_rw demo project.

Feel free to send me your ioc file and I will check it.

Rgds

BT

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Hi, 

Thank you very much!

 

Just a few final things.

 

Should I need the Ndef, because it also has NfcV (screenshot)?

 

I fighting with my IT department to get the ST25 library on my PC.

 

I presume I need to implement BSP_NCF0X... and globalCommProtectCnt ?

So then it would be just as easy as following this application note If I have t correct.

https://www.st.com/resource/en/application_note/an5514-st25-tags-embedded-library-stmicroelectronics.pdf

 

Kind Regards, 

William

 

William_RnD
Associate III

Screenshots, oeps

William_RnD_0-1769772500373.png

 

Hi William,

The ST25 Embedded Library is a collection of source code provided in a self-extracting archive with a click-through license. The archive does not install any drivers, DLLs, or EXEs; it only copies source and project files into a specified folder.

NDEF (NFC Data Exchange Format) is a lightweight, standardized message format used to store and exchange data over NFC. NDEF relies on various NFC technologies, such as NFC-A, NFC-B, NFC-F, and NFC-V.

The use of NDEF depends on the application. For example, access control applications, such as ski passes, do not use NDEF, while Bluetooth® pairing applications use NDEF.

Regarding BSP_NCF0X... and globalCommProtectCnt linker issue, the previous post has been updated. In Software Packs > Select Components, an application must be selected. Currently, NFC09A1_PollingTagDetect is the only available application.

In the Middleware tab, select Device NFC Applications, complete the assignment of the various peripherals, and regenerate the code. There should not be any link errors.

Rgds

BT

 

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Hi, 

Thanks a lot!

I got it reading the UID from my tag now just the data, but I'm sure I'll figure it out!

Thank you, 

Kind regards, William