cancel
Showing results for 
Search instead for 
Did you mean: 

[solved] having trouble reading simple NDEF records from NFCA Passive T4T cards

anotherandrew
Senior

ST25R3911B, using the ST25RFAL001 and the NDEF library v1.0.4. I'm using the read example found in the ndef.chm file. It's detecting the card fine, but ndefPollerNdefDetect() is returning 0x5 (invalid request or requested function can't be executed at this time). Every very rare once in a while I'll get the same return code from ndefPollerReadRawMessage() so I know I'm close.

The software loop is very small. It is being called in an endless loop with HAL_Delay(1), so it runs every 1msec.

int nfc_loop(void)
{
	uint32_t now;
	static uint32_t next_tick;
	rfalNfcState nfc_state;
	static uint8_t buf[256];
	int err, nread;
 
	rfalNfcWorker();
	now = HAL_GetTick();
	nfc_state = rfalNfcGetState();
 
	if (rfalNfcIsDevActivated(nfc_state)) {
		rfalNfcDevice *nfcDevice;
 
		rfalNfcGetActiveDevice(&nfcDevice);
		if ((err = ndefPollerContextInitialization(&ndefCtx, nfcDevice)) != ERR_NONE) {
			platformLog("ndefPollerContextInitialization returned (%d)\n", err);
			return;
		}
 
		if ((err = ndefPollerNdefDetect(&ndefCtx, NULL)) != ERR_NONE) {
			platformLog("ndefPollerNdefDetect returned (%d)\n", err);
			return;
		}
 
		memset(buf, 0, sizeof(buf));
		if ((err = ndefPollerReadRawMessage(&ndefCtx, buf, sizeof(buf), &nread)) != ERR_NONE) {
			platformLog("ndefPollerReadRawMessage returned (%d)\n", err);
			return;
		}
 
		platformLog("success, read %d bytes\n", nread);
	}
}

Digging a little deeper, it looks like ndefT4TReadAndParseCCFile() is able to successfully select the file to read, but ndefT4TPollerReadBinary() does not get a isoDepAPDU status that it likes. It receives 17 bytes from the card (00 00 00 00 0F 0F 0F 20 00 FF 00 36 04 04 06 00 01) but the status word encoded in those 17 bytes is 0x0000, not 0x9000 so the call fails.

I'm lost as to how to go about debugging this; the card is returning data, and other calls seem to work (the expected return value of 0x9000 is seen). If I use this exact same card with an iPhone reader, it correctly shows the NDEF TXT record (NFC well known type 0x01, record type T (0x54) , 19 bytes total with raw values 0x02 0x65 0x6e 0x63 0x65 0x61 0x30 0x30 0x30 0x30 0x30 0x30 0x31 0x65 0x38).

How do I go about debugging this? I should add the relevant bits of the platform header file which configures the RFAL and NDEF libraries:

#define RFAL_FEATURE_LISTEN_MODE		true			/*!< Enable/Disable RFAL support for Listen Mode                               */
#define RFAL_FEATURE_WAKEUP_MODE		false			/*!< Enable/Disable RFAL support for the Wake-Up mode                          */
#define RFAL_FEATURE_NFCA			true			/*!< Enable/Disable RFAL support for NFC-A (ISO14443A)                         */
#define RFAL_FEATURE_NFCB			false			/*!< Enable/Disable RFAL support for NFC-B (ISO14443B)                         */
#define RFAL_FEATURE_NFCF			false			/*!< Enable/Disable RFAL support for NFC-F (FeliCa)                            */
#define RFAL_FEATURE_NFCV			false			/*!< Enable/Disable RFAL support for NFC-V (ISO15693)                          */
#define RFAL_FEATURE_***			false			/*!< Enable/Disable RFAL support for *** (Topaz)                               */
#define RFAL_FEATURE_T2T			false			/*!< Enable/Disable RFAL support for T2Tn                                      */
#define RFAL_FEATURE_T3T			false			/*!< Enable/Disable RFAL support for T3Tn                                      */
#define RFAL_FEATURE_T4T			true			/*!< Enable/Disable RFAL support for T4Tn                                      */
#define RFAL_FEATURE_T5T			false			/*!< Enable/Disable RFAL support for T5Tn                                      */
#define RFAL_FEATURE_ST25TB			false			/*!< Enable/Disable RFAL support for ST25TB                                    */
#define RFAL_FEATURE_DYNAMIC_ANALOG_CONFIG	false			/*!< Enable/Disable Analog Configs to be dynamically updated (RAM)             */
#define RFAL_FEATURE_DYNAMIC_POWER		false			/*!< Enable/Disable RFAL dynamic power support                                 */
#define RFAL_FEATURE_ISO_DEP			true			/*!< Enable/Disable RFAL support for ISO-DEP (ISO14443-4)                      */
#define RFAL_FEATURE_ISO_DEP_POLL		true			/*!< Enable/Disable RFAL support for Poller mode (PCD) ISO-DEP (ISO14443-4)    */
#define RFAL_FEATURE_ISO_DEP_LISTEN		false			/*!< Enable/Disable RFAL support for Listen mode (PICC) ISO-DEP (ISO14443-4)   */
#define RFAL_FEATURE_NFC_DEP			false			/*!< Enable/Disable RFAL support for NFC-DEP (NFCIP1/P2P)                      */
 
#define RFAL_FEATURE_ISO_DEP_IBLOCK_MAX_LEN	512			/*!< ISO-DEP I-Block max length. Please use values as defined by rfalIsoDepFSx */
#define RFAL_FEATURE_ISO_DEP_APDU_MAX_LEN	512			/*!< ISO-DEP APDU max length. Please use multiples of I-Block max length       */
 
#define RFAL_FEATURE_NFC_DEP_BLOCK_MAX_LEN	128
#define RFAL_FEATURE_NFC_DEP_PDU_MAX_LEN	128
#define RFAL_FEATURE_NFC_RF_BUF_LEN		512

Eventually I need to shrink this down to the absolute bare minimum, but for now I just need to be able to read these simple text records.

1 ACCEPTED SOLUTION

Accepted Solutions
anotherandrew
Senior

Interesting -- I have 8 identical boards (ST25R3911B + STM32L031, internal HSI RC, 32MHz SYSCLK, 32MHz APB1/2) -- two of them will periodically read the 19-byte NDEF file on the card, where the others all do not (same error 0x5, mostly in ndefPollerNdefDetect() but occasionally that function returns without error but then ndefPollerReadRawMessage() returns 0x5.

I thought it might be power related, so I powered things from a bench supply - no change. I then thought it might be some edge case with SPI timing so I tried adding some delay after asserting CS# and before negating CS# - no change. Then I slowed the SPI clock WAAAAAAY down and things started working reliably. After some tweaking I went from SPI_BAUDRATEPRESCALER_2 to SPI_BAUDRATEPRESCALER_4 and now I'm reliably reading NDEF data on all boards and with all cards.

It's very odd that I can reliably talk to the ST25R3911B with the faster (16MHz) SPI clock, reliably detect cards and even retrieve their ID (struct rfalNfcDevice.dev.nfca.nfcId1) without any trouble whatsoever, but trying to select an NDEF record and retrieve it was intermittent to the point of failing 100% on some boards with the same fast SPI clock. Dropping to 8MHz SPI Clock solves the issue, but looking more closely at the ST25R3911B datasheet seems to indicate that this is still too fast (SCLK period is minimum 167ns which is 6MHz).

View solution in original post

2 REPLIES 2
Ulysses HERNIOSUS
ST Employee

Hi andrew-st,

Out of the box I cannot pin-point what could be the issue here. The received APDU does not really look like an APDU. May require to look into real exchanged frames on the lower layer of RFAL or maybe even the SPI itself using a logic analyzer.

But maybe at first I would go and verify using an existing working example: Use STSW-ST25R-LIB / STSW-ST25R015 which contains a known-to-work example application of reading NDEF content from tags.

Regards, Ulysses

anotherandrew
Senior

Interesting -- I have 8 identical boards (ST25R3911B + STM32L031, internal HSI RC, 32MHz SYSCLK, 32MHz APB1/2) -- two of them will periodically read the 19-byte NDEF file on the card, where the others all do not (same error 0x5, mostly in ndefPollerNdefDetect() but occasionally that function returns without error but then ndefPollerReadRawMessage() returns 0x5.

I thought it might be power related, so I powered things from a bench supply - no change. I then thought it might be some edge case with SPI timing so I tried adding some delay after asserting CS# and before negating CS# - no change. Then I slowed the SPI clock WAAAAAAY down and things started working reliably. After some tweaking I went from SPI_BAUDRATEPRESCALER_2 to SPI_BAUDRATEPRESCALER_4 and now I'm reliably reading NDEF data on all boards and with all cards.

It's very odd that I can reliably talk to the ST25R3911B with the faster (16MHz) SPI clock, reliably detect cards and even retrieve their ID (struct rfalNfcDevice.dev.nfca.nfcId1) without any trouble whatsoever, but trying to select an NDEF record and retrieve it was intermittent to the point of failing 100% on some boards with the same fast SPI clock. Dropping to 8MHz SPI Clock solves the issue, but looking more closely at the ST25R3911B datasheet seems to indicate that this is still too fast (SCLK period is minimum 167ns which is 6MHz).