This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TRF7970A + SLOC297 + NXP NT3H2211

Other Parts Discussed in Thread: MSP430G2553, TRF7970A, TRF7960A, TRF7960, DLP-7970ABP

Have been successfully using the MSP430G2553 launchpad in conjunction with the TRF7970A DLP Booster Pack and the sample reading code at http://www.ti.com/lit/zip/sloc297.

The NTAG i2c Plus is an ISO 14443A type 2 tag and uses 4-bit ACK/NAKs as well as no RX CRC on commands such as WRITE / FAST_WRITE.

1) Regarding the RX CRC, setting the ISO Control Register to 0x88 has resolved that issue as expected.

2) Regarding the 4-bit ACK/NAK, when setting the TRF 7970A Special Function Register BIT2 to 4-bit receive, one does not have the expected results. During a

read comment (0x30), trhe IRQ Status Register BIT4 and BIT6 set are set, but that causes the current Trf797xISR() routine to fall out with a protocol error. The

buffer does not contain valid read data. This occurs whether it is a valid read or a read that would normally cause a NAK.

3) With the special function register BIT2 turned off, reads are writes are successful, but unsure if the NAK and ACK are being appropriately captured. Is there a

way to see the value of the 4-bit NAK? I've tried relaying back the dummy byte that's read from the interrupt handler, but the NAK value shown indicates a state

that would not be possible at POR for the tag when not acting in an arbiter mode. Similarly I don't think I see the ACK being captured.

On the plus side, I have this module working the happy path using energy harvesting and pass through modes, arbitrating a functionality between the msp430

and the nxp lpc11u24 over NFC. It's the boundary cases and errors that I'm concerned with.

Thanks,

Karl

  • Hi Karl,

    I don't have that particular tag in hand so I can't test with it directly right now. But I'll look into using some other NTAG's and sending erroneous commands in order to trigger the ACK/NAK and see how those are being reported back to the TRF7970A and how the driver handles it. It is possible that an extra case has to be added to the TRF driver to handle the case where the special function register is set for the 4 bit receives. Thanks for bringing this up, I will look into that behavior over the next week and see what needs to be done to allow for ACK's/NAK's to be properly handled in both the ISO14443a layer and the TRF driver. I'll keep you posted as I find out more.

    Also good catch on the 0x88, you are right that it needs to be used in order to get ACK's and NAK's back. Looks like that needs to be modified with the Type 2 Read Block function to set that instead of 0x08.

  • Just wanted to check if you'd had any luck with the 4 bit ACK/NAKs. 

    Thanks, Karl

  • yes we have - its in multiple code projects - how else would we have handled the responses- i thought Ralph was looking for the best example - you can also look in the -G2253 code and the NFCLink code bases, along with training i have posted on E2E many times

  • I appreciate that. My question is around accessing those actual ACK/NAK values. From NFCLink, it's clear that the capability is there: 

    Transmitted PDU size: 6 bytes, data:

    A2 10 AB CD EF BB

    Received PDU size: 1 bytes, data:

    A0 

    My question is actually from the G2553 code. That code does not inherently have write support. After adding support modeled after the exiting methods, and disabling the CRC checking for a WRITE/ FAST_WRITE operation with the tag, I am able to pass the requests back and forth as well as receive an RX_COMPLETE from the trf797x.c::Trf797xISR

    The origin of my question is what needs to be set to receive the ACK/NAK values in the receive buffer. When I examine the g_ui8TrfBuffer for the ACK/NAK value, it is not present. There are just residual data bytes from prior operations. 

    I have also attempted to set the special function register (0x10) BIT2 with the impression that this was needed to have the ACK/NAK values in the buffer. Instead it causes the Trf797xISR to treat the response as an error. The reason I'm seeking them is because I need to key off of specific NAK values that may be returned. 

    If this is explained elsewhere, then I have missed it. I had reviewed the powerpoint presentation at http://e2e.ti.com/cfs-file.ashx/__key/communityserver-discussions-components-files/667/3365.NFC-Forum-Type-2-Tag-Platform-Operations-with-TRF7970A_5F00_02_5F00_18_5F00_2014.pdf and followed the slide titled "Writing Data / Formatting NFC Forum Type 2 Tag Platform". The saleae logic traces show exactly what I was hoping to see appear in the return buffer. 

    At this point I've had little success in making this work with the NT3H2211 or even an NTAG203 using the G2553 sample code. Any assistance would be greatly appreciated. 

    Karl

  • Karl -
    please have a look at the TRF7960A reference firmware - in there you will find Read (0x30) and Write (0xA2) for my-d move and the other vendors type 2 cards, you will also find the read two (0x31) and write two (0xA1) commands as well, but they only apply to the Infineon tag.

    www.ti.com/.../sloc251

    see type2.c file, hope that helps you out. this is also described in section 6.4, page 20 here  

  • Thanks, I've taken a look at both and have confirmed that WRITE operations with the special function register set to 4-bit ACK/NAK are working properly. The ACK or NAK byte is returned, which is great.

    The problem that I'm having (and continue to have) even after replicating the code behavior seen in type2.c is that neither NFCLink+NFCPlayer nor the G2553 code are working as expected on READ operations.

    An example as seen with NFCLink firmware + NFCPlayer when reading outside the memory boundaries of the ntag203. The response should be a NAK, but instead I see the following when issuing the command (0x30 0xFF):

    21:17:14:468 Tag detected
    21:17:14:468 Tag's properties:
    21:17:14:469 Identifier: MIFARE Ultralight
    21:17:14:469 Manufacturer: NXP
    21:17:14:469 UID length: 7
    21:17:14:469 UID: 04:06:AE:02:84:2A:81
    21:17:14:469 ATQA: 0x0044
    21:17:14:469 SAK: 0x00
    21:17:14:469 CNfcInstance::connectTag: Enter
    21:17:14:469 CNfcInstance::connectTag: Exit (status: 0)
    21:17:14:471 CNfcPlayer::handleNfcTechnologyDiscovered: Exit
    21:17:14:471 CNfcInstance::handleTagDetected: Exit
    21:17:46:584 CNfcPlayer::legacyExchangePdu: Enter
    21:17:46:594 CNfcInstance::legacyExchangePdu: Enter
    21:17:47:992 CNfcInstance::exchangePdu: ! Transceiving PDU failed (status: 1)
    21:17:47:993 CNfcInstance::legacyExchangePdu: ! Exchanging PDU failed (code: 1)
    21:17:47:994 CNfcInstance::legacyExchangePdu: Exit (status: 1)
    21:17:47:995 CNfcPlayer::legacyExchangePdu: ! Exchanging data failed (code: 1)
    21:17:47:997 CNfcPlayer::legacyExchangePdu: Exit (status: 1)
    21:17:50:395 CNfcInstance::dispatchEvent: nfcEventTagRemoved
    21:17:50:397 CNfcInstance::handleTagRemoved: Enter
    21:17:50:400 CNfcPlayer::handleNfcTechnologyRemoved: Enter
    21:17:50:406 CNfcPlayer::handleNfcTechnologyRemoved: Exit
    21:17:50:408 CNfcInstance::handleTagRemoved: Exit

    On a READ of a valid address, no issue is encountered in NFCPlayer. (There is no ACK to process either).

    Similarly, in direct code, such as the G2553 sample, the behavior is the same (seemingly protocol error). If the SFR BIT 2 is set in the G2553 sample code, both READ operations on valid memory addresses and invalid memory addresses result in a protocol error. Specifically the IRQ Status Register BIT4 and BIT6 are set.

    Based on the type2.c example, I also tried setting the SFR BIT2 only after a TX was complete and prior to RX of the tag read command. I experienced the same behavior which was to see both BIT4 and BIT6 of the IRQ Status Register set.

    Perhaps I'm lacking some additional detail in documentation regarding how the 4-bit ACK/NAK setup is meant to work on READ operations. I would not have expected to encounter the CRC error to have been set.

    Thanks,
    Karl
  • i don't think the NFCLink log could be interpreted in that manner - is this tag formatted? if not, then NFCLink (NCI) NFCPlayer would give you that kind of response.

    if you are trying to read above block 0x29 then it should give you NAK
    I see the problem clearly here now - you expect to be able to read normal data and also deal with the possibility of an ACK or NAK - think if you are reading - set it up for normal RX and deal with error on your own - if writing, then ACK or NAK would show up correctly, which is more important -

    the capability container tells you how big the tag is.
  • Yep, it's a formatted tag. Although I use this as an example, the main target is the NT3H2211. This includes NAK codes that indicate the arbiter state as well as some more common passive tag conditions. In some cases it would be possible to alter the code to read this from a register instead. If I understand correctly, are you saying that the NAK code is something we won't be able to extract during the READ operation? We had been able to obtain this with the NXP pn7120, which was originally used to interface with the NT3H2211. Thanks, Karl
  • yes. this tag type operates that way - back when the original TRF7960 was designed, this tag was limited to niche RFID applications - the general consensus at that time was that common sense would rule out and all tag types for the NFC Forum specified would be ISO standard devices. this did not happen. We noticed this and requested the addition of the handling of the non standard 4 bit RX to the SFR in this case - which resulted in the TRF7960A version and the others that followed it. 

    the fact that you get correct response for this case with NXP reader is not suprising - its their product, of course they would support it...here in this case i think we do support, just in the negative cases, the response will need to be interpreted and handled that way. 

  • Makes sense. Thanks for the background and working through the issue. Certainly gives a clear direction on how our implementation will need to operate w/ the TRF7970A. 

    Thanks, Karl

  • Hi Karl,

    Sorry I hadn't gotten back to you yet, but I haven't yet had a chance to work on this on my end either. I plan to do so this week.

    I believe, as Josh alluded to in his last post, the primary change needed is the TRF7970A IRQ Handler in order to handle the negative cases not as an error but as an accepted response and then to ensure that the 4 bit value is properly stored inside of the buffer and not discarded.

    My suspicion is that in the G2553, either the code to handle broken bits for anticollision does not translate to handling the 4 bit ACK/NAK replies, or some procedural in the RX_COMPLETE case needs to be tweaked. Once I get a chance to get an LSA capture to see what sort of IRQ is reported back to the TRF7970A, then it should be clearer what needs to be done - but I think those are the two most likely cases.

    Did you ever get a chance to sniff the TRF7970A SPI lines and see what IRQ value is given in 4 bit mode?

  • The WRITE conditions are working fine with SFR BIT2 set, which is great.

    The READ conditions with the SFR (0x10) BIT2 set seem to be where the issue arises with the G2553 code. I had a trace at one point, but I apologize I have discarded it. The IRQ Status (0x0C) does have BIT4 and BIT6 set under the conditions of performing a READ operation on a Type2 tag with SFR (0x10) BIT2 set. (Whether it is an error or not). 

    Currently that is treated as a protocol error. In the type2.c from the TRF7970A firmware Josh provided, this similar clause in the interrupt handler was dealt with by not discarding the byte and placing it in reserved location at buf[200]. 

    I believe there may be some other changes needed, however, as this was not enough to resolve the issue alone in the G2553 code, and new data was not being populated into the receive buffer. 

    I thought I had understood from Josh that during the READ conditions, one would actually not set SFR (0x10) BIT 2, and instead supplement the application with code to prevent the issue (if possible) and/or deal with negative cases as an error instead. If I misunderstood, I apologize. 

    Thanks, Karl

     

  • Hi Karl,

    Ah I see, yes if it reports back a BIT4 set on the IRQ Status that would be an issue with the current handling.

    I will check the differences between the older type2.c and the current firmware and also the settings (register and otherwise)

    Thanks for sharing all those details, it gives me a clearer picture of what to look for. I'm going to try and work on this in the next couple days.

    Without having done any debugging, I think SFR (0x10) BIT 2 being set is going to be needed... and I think Josh was eluding to that when discussing the changes we made from the TRF7960 to the TRF7960A.
  • Hi Karl,

    So I don't have your particular NXP tag in hand right now, but I worked with the NTAG213 and put together some ACK/NAK handling based on that. It should translate just fine for your own tag.

    Seems like no TRF driver changes are required at all though. The key was to enable the 4 bit RX and RX without CRC on. With these two settings, the TRF7970A reports back a 0x40 for all tag WRITE replies. I got no errors and since the TRF7970A registered the bits coming in from the RX_COMPLETE case, the buffer already had the data setup. That made things pretty easy in the end actually :)

    Here are the updated Type 2 Read and Write functions based on the G2553 code base: 

    uint8_t Iso14443a_Type2Read4Blocks(uint8_t ui8StartBlock)
    {
    	uint8_t ui8Offset = 0;
    	uint8_t ui8Status = STATUS_FAIL;
    #ifdef ENABLE_HOST
    	uint8_t	ui8LoopCount1 = 1;
    	uint8_t	ui8LoopCount2 = 0;
    #endif
    
    	if (Trf797xGetIsoControlValue() != 0x88)
    	{
    		// Trf797x has not been properly configured for ISO14443A
    		Trf797xWriteIsoControl(0x88);			// Configure the TRF797x for ISO14443A @ 106kbps and Receive without CRC
    	}
    	if (Trf797xCheckRfField() == false)
    	{
    		// RF field is not enabled, VICC will not receive the command
    		Trf797xTurnRfOn();						// Ensure TRF797x is outputting an RF Field
    
    		// When a PICC is exposed to an unmodulated operating field
    		// it shall be able to accept a quest within 5 ms.
    		// PCDs should periodically present an unmodulated field of at least
    		// 5.1 ms duration. (ISO14443-3)
    		McuDelayMillisecond(6);
    	}
    
    	g_ui8TrfBuffer[ui8Offset++] = 0x8F;		// Reset FIFO
    	g_ui8TrfBuffer[ui8Offset++] = 0x91;		// Send with CRC
    	g_ui8TrfBuffer[ui8Offset++] = 0x3D;		// Write Continuous
    	g_ui8TrfBuffer[ui8Offset++] = 0x00;		// Length of packet in bytes - upper and middle nibbles of transmit byte length
    	g_ui8TrfBuffer[ui8Offset++] = 0x20;		// Length of packet in bytes - lower and broken nibbles of transmit byte length
    	g_ui8TrfBuffer[ui8Offset++] = 0x30;				// Read Command
    	g_ui8TrfBuffer[ui8Offset++] = ui8StartBlock;	// Starting from Block # (called Bno)
    
    	Trf797xRawWrite(&g_ui8TrfBuffer[0], ui8Offset);		// Issue the Type 2 Read Command
    
    	Trf797xIrqWaitTimeout(5,30);		// 5 millisecond TX timeout, 30 millisecond RX timeout
    
    	g_sTrfStatus = Trf797xGetTrfStatus();
    
    	if(g_sTrfStatus == RX_COMPLETE)		// If block data has been received
    	{
    		if (Trf797xGetRxBytesReceived() > 0)
    		{
    			ui8Status = STATUS_SUCCESS;		// Mark tag has been successfully read
    
    #ifdef ENABLE_HOST
    			for(ui8LoopCount2 = 0; ui8LoopCount2 < 4; ui8LoopCount2++)
    			{
    				UartSendCString("Block ");
    				UartPutByte(ui8StartBlock++);
    				UartSendCString(":  [");
    				for(ui8LoopCount1 = (ui8LoopCount2*4); ui8LoopCount1 < 4+(ui8LoopCount2*4); ui8LoopCount1++)
    				{
    					UartPutByte(g_ui8TrfBuffer[ui8LoopCount1]);		// Print out the received data
    				}
    				UartPutChar(']');
    				UartPutNewLine();
    			}
    #endif
    		}
    		else
    		{
    #ifdef ENABLE_HOST
    			UartSendCString("Read Fail");
    			UartPutNewLine();
    #endif
    		}
    	}
    	else
    	{
    		// Otherwise return a fail
    		ui8Status = STATUS_FAIL;
    	}
    
    	return ui8Status;
    }
    
    uint8_t Iso14443a_Type2WriteSingleBlock(uint8_t ui8StartBlock, uint8_t * pui8TagData)
    {
    	uint8_t ui8Offset = 0;
    	uint8_t ui8Status = STATUS_FAIL;
    	uint8_t pui8TrfConfig[2];
    	uint8_t ui8TagResp;
    
    	if (ui8StartBlock < 4)
    	{
    		// Attempt to write OTP blocks, do not allow
    		// * This can be removed by experienced users who understand
    		//   that they can permanently break a tag by using this incorrectly
    		return ui8Status;
    	}
    
    	// Read Register 0x10 - Special Functions Register
    	pui8TrfConfig[1] = TRF797x_SPECIAL_FUNCTION_1;
    	Trf797xReadSingle(&pui8TrfConfig[1]);
    
    	// Set Bit 2 in Special Functions Register to 1
    	pui8TrfConfig[0] = TRF797x_SPECIAL_FUNCTION_1;
    	pui8TrfConfig[1] |= 0x04; 	// Turn on 4-bit receive for ACK/NAK replies
    	Trf797xWriteSingle(pui8TrfConfig);
    
    	if (Trf797xGetIsoControlValue() != 0x88)
    	{
    		// Trf797x has not been properly configured for ISO14443A
    		Trf797xWriteIsoControl(0x88);			// Configure the TRF797x for ISO14443A @ 106kbps and Receive without CRC
    	}
    	if (Trf797xCheckRfField() == false)
    	{
    		// RF field is not enabled, VICC will not receive the command
    		Trf797xTurnRfOn();						// Ensure TRF797x is outputting an RF Field
    
    		// When a PICC is exposed to an unmodulated operating field
    		// it shall be able to accept a quest within 5 ms.
    		// PCDs should periodically present an unmodulated field of at least
    		// 5.1 ms duration. (ISO14443-3)
    		McuDelayMillisecond(6);
    	}
    
    	g_ui8TrfBuffer[ui8Offset++] = 0x8F;				// Reset FIFO
    	g_ui8TrfBuffer[ui8Offset++] = 0x91;				// Send with CRC
    	g_ui8TrfBuffer[ui8Offset++] = 0x3D;				// Write Continuous
    	g_ui8TrfBuffer[ui8Offset++] = 0x00;				// Length of packet in bytes - upper and middle nibbles of transmit byte length
    	g_ui8TrfBuffer[ui8Offset++] = 0x60;				// Length of packet in bytes - lower and broken nibbles of transmit byte length
    	g_ui8TrfBuffer[ui8Offset++] = 0xA2;				// Write Command
    	g_ui8TrfBuffer[ui8Offset++] = ui8StartBlock;	// Starting from Block # (called Bno)
    	g_ui8TrfBuffer[ui8Offset++] = pui8TagData[0];	// Four tag data bytes
    	g_ui8TrfBuffer[ui8Offset++] = pui8TagData[1];
    	g_ui8TrfBuffer[ui8Offset++] = pui8TagData[2];
    	g_ui8TrfBuffer[ui8Offset++] = pui8TagData[3];
    
    	Trf797xRawWrite(&g_ui8TrfBuffer[0], ui8Offset);		// Issue the Type 2 Read Command
    
    	Trf797xIrqWaitTimeout(10,40);		// 10 millisecond TX timeout, 40 millisecond RX timeout
    
    	g_sTrfStatus = Trf797xGetTrfStatus();
    
    	if(g_sTrfStatus == RX_COMPLETE)		// If an acknowledgment is received
    	{
    		ui8TagResp = g_ui8TrfBuffer[0] >> 4;	// Only use upper four bits received for ACK/NAK check
    
    		if (ui8TagResp == 0xA)
    		{
    			ui8Status = STATUS_SUCCESS;		// Mark tag has been successfully read
    	#ifdef ENABLE_HOST
    			UartSendCString("Write Success");
    			UartPutNewLine();
    	#endif
    		}
    		else
    		{
    #ifdef ENABLE_HOST
    		UartSendCString("Write Fail: ");
    		if (ui8TagResp == 0x0)
    		{
    			UartSendCString("Invalid Page Address");
    		}
    		else
    		{
    			UartSendCString("NAK = ");
    			UartPutChar(ui8TagResp);
    		}
    		UartPutNewLine();
    #endif
    		}
    
    	}
    	else
    	{
    #ifdef ENABLE_HOST
    		UartSendCString("Write Fail");
    		UartPutNewLine();
    #endif
    		// Otherwise return a fail
    		ui8Status = STATUS_FAIL;
    	}
    
    	// Read Register 0x10 - Special Functions Register
    	pui8TrfConfig[1] = TRF797x_SPECIAL_FUNCTION_1;
    	Trf797xReadSingle(&pui8TrfConfig[1]);
    
    	// Set Bit 2 in Special Functions Register to 1
    	pui8TrfConfig[0] = TRF797x_SPECIAL_FUNCTION_1;
    	pui8TrfConfig[1] &= ~0x04; 	// Clear 4-bit receive for ACK/NAK replies
    	Trf797xWriteSingle(pui8TrfConfig);
    
    	return ui8Status;
    }

    My changes are:

    For Write:

    • Activate 4 bit RX at the start of the function
    • On RX complete, check the byte received for ACK (0xA) or NAK and print out either success or fail+NAK reason
    • Then at the end, turn off the 4 bit RX again.

    For Read

    • Turn off RX with CRC
    • On RX complete, check length received.
      • If greater than 0 byte, print out data
      • Otherwise print Read Fail as an RX Complete + 0 Bytes of data in the FIFO occurs when receiving a NAK from the Type 2 Tag.
        • There is no way to receive this NAK data unless 4 bit mode is enabled, but then tag data cannot be received correctly instead. Hence this implementation has been chosen.

    Let me know how this works for you.

    EDIT: This post has been edited following the subsequent discussions in the thread in order to remove misleading and erroneous information as well as a non-functional firmware example. The contents of this post now correctly reflect how the TRF7970A should be operated for Type 2 Read and Write commands.

  • Great! I will give this a shot shortly. Quick question comes to mind though on the READ case. If setup for no RX CRC, does this mean that the return CRC is not validated? Similar to my tag and the 203, the NTAG213 (Section 10.2) a READ command does include a CRC in response. That was the reason I hadn't tried enabling both 4 bit and no RX CRC as I do with the WRITE. 

    Thoughts? 

    Thanks, Karl

  • Correct, it wouldn't be validated automatically by the TRF7970A. However, you will find the two extra bytes in the FIFO so you can run a software CRC-16 check yourself to validate the data instead of letting the TRF7970A handle it automatically if that CRC check is crucial for you.
  • Enabling no RX CRC as suggested on my existing method resolved it. Since the CRC-16 is available to manually validate, then I can implement that if there are any concerns. Thanks again for the assistance. This worked on the NTAG203, 213, and the NT3H2211.

    Karl
  • Oops, sorry spoke too soon. I was seeing the right RX behavior, but the data actually coming back in the buffer aren't the correct bytes. It only becomes correct once the SFR setting for 4-bit is disabled again... I even verified the entire contents of g_ui8TrfBuffer. Saw this with both your function and mine...
  • Hummm...

    What isn't correct about it? How much data are you getting back? Can you make a local variable to check returned value from the Trf797xGetRxBytesReceived() function? Curious how much it reports back... or if you are getting a reply at all.

    One thing I noticed was if an erroneous command was sent out, the NTAG213 didn't seem to want to reply to subsequent correct commands. I didn't really investigate why yet, but I'd imagine either there is a timeout which must be obeyed (easy to implement) or the tag needs to be re-activated to reset it...

    When I first ran the updated read data function, I got the right data, but I have to admit I didn't validate the read data by the time I packaged the firmware up with all of the cases for data handling... I can do so first thing tomorrow (I apparently don't have any Type 2 Tags at home...). I assume you tried with an NTAG213 as well?
  • Yep, just tried with a 213 and 203.

    As an example, on a completely uninitialized 213, using an android reader, it confirms bytes from block 0x11 that I'm reading are all 0x00. The read method with the 4-bit receive enable sees:

    Anticollison Completed
    ISO14443A UID: [04ED613A983780]
    Tag is not ISO14443-4 Compliant

    Block 11: [00080808]
    Block 12: [08080808]
    Block 13: [08080808]
    Block 14: [08080808]

    (19 bytes received)

    When the SFR is not set, I see:

    Anticollison Completed
    ISO14443A UID: [04ED613A983780]
    Tag is not ISO14443-4 Compliant

    Block 11: [00000000]
    Block 12: [00000000]
    Block 13: [00000000]
    Block 14: [00000000]

    (18 bytes received)

    Also to make sure we're working with apples to apples, I did this on a fresh tree from sloc297b with only your new read method added.

    Karl
  • Alright. I will look at it in the morning in further detail and see what is going on... that is pretty odd behavior, but I actually now do recall having seen some 0x08's being read out from my testing when I was checking the error case messages and such, which were at the back of the tag and it's pretty likely those were actually 0x00's instead.

    Out of curiosity... if it's not too hard, can you write something like FF or AA and then read that out with the SFR set to see what happens? I wonder if it's a single bit thats being corrupted, a whole nibble (because it's 4 byte mode?) or something entirely different. I doubt I'd be able to tell anything conclusive, but it could give me more food for thought about what could be occurring.
  • Also regarding the invalid command, I know the 203 at least will reset on a NAK.

  • Sure, one of my tags as AB CD EF AA AA BB CC DD 00 00 00 00 00 00 00 00 as a test set starting at 0x10, this is the output with SFR set starting at 0x10 I see:

    Block 10: [B0D5F6A7]
    Block 11: [ADBDCDDE]
    Block 12: [0E080808]
    Block 13: [08080808]

    Starting at 0x11 I see:

    Block 11: [A0BDCDDE]
    Block 12: [0E080808]
    Block 13: [08080808]
    Block 14: [08080808]

    It's consistent across reflashing as well.

    Karl
  • Quite an interesting result. All I can discern from the pattern is that the lower nibble of each data byte appears as the upper byte of each received value, and the lower nibble of the received value seems to be garbage, which helps explain the 0x08 spam on 0x00's I suppose.

    I think the first thing I will try and do is see what kind of responses I get from leaving the SFR off for the read and if there is a workable way to handle a unique case in the ISR to pull out the NAK data with the SFR off, then perhaps that may be the best solution. Otherwise I'll have to see what can be done about toggling between the modes. In any event, it doesn't seem likely that receiving block data correctly will work with the SFR on... I was kind of hoping we'd see something like A8 B8 C8 D8 etc, which would have meant it received all the data but then the data got broken across 2 bytes per 1 byte of valid data and that would be easy to then extract. Seems that is not the case though.
  • Hi Karl,

    Alright did a whole battery of tests on trying to receive the NAK with the Read if incorrect commands are sent but also get the data correctly when a valid command is sent.

    The conclusion for this firmware example is that it is not possible to do.

    The issue at hand is that the TRF7970A has to be in one of two modes beforehand... 4 bit or 8 bit mode.

    In 4 bit mode, the TRF7970A will receive the NAK correctly, but the data received will only be received as 4 bits and not 8 bits mean you will never get the correct block data from the tag.

    In 8 bit mode, the TRF7970A will receive all 8 bit tag data correctly, but it cannot process the 4 bit value received (which is why the 4 bit receive had been added to begin with from the TRF7960 to the TRF7960A, for write cases) and while it gives an RX complete, the 4 bit value is lost and not retrievable for the user to view/process.

    I exhausted all settings I could think of and found no workaround for this. I was sure I had read data with the 4 bit on before, but was mistaken an erroneously thought that was the case. That's my mistake, as is not verifying it a final time before pushing that half of it out. I will be editing the prior post later to match the correct features of the chip.

    As far as what you can do... well, I tried coming up with a software workaround but the NTAG213 I had did not like that solution it seems.

    The idea was:

    1. Send Read command out
    2. If RX Complete, check # of bytes received
      1. If 1 or more bytes, assume Tag Data was provided and print out
      2. If 0 bytes were received, this means an RX Complete with no data occurred and this was almost guaranteed to be a NAK so
        1. Turn on 4 bit RX mode
        2. Proceed to send out the identical Read command again to get the NAK properly
    3. If no RX occurred, treat it as an error and exit

    The problem is... the NTAG213 went silent for the 2nd read command. Completely. I sniffed the connection over the air and clearly saw all packets including the NAK's and ACK's for writes, but that 2nd read command resulted in nothing. The tag simply won't reply to it.

    I tried to put it to sleep with a HLTA and then wake it up with a WUPA but even that didn't get it to behave. It's odd too, in that if I sent 2 correct read commands using that sequence, it would reply both times, but the second I sent two of the same erroneous commands, it would give a NAK to the first command and utterly ignore the second one. Very strange, and it killed my hopeful software workaround.

    If you absolutely must have the NAK data for the Read command, the only option at play is to use Direct Mode 0 or Direct Mode 1. I am pretty sure Direct Mode 1 is sufficient to receive NAK/ACK and also tag data, but I'd need to verify that with a colleague. This adaptation is not planned for the example firmware, but we do have app note which discusses receiving in Direct Mode 1 you can read: http://www.ti.com.cn/cn/lit/an/sloa214/sloa214.pdf 

    The latest revision of the DLP-7970ABP BoosterPack (V4.5) supports the needed connections on a hardware level, so it would then become a software implementation for you to be able to get that feature to work.

    Sorry I didn't have better news after all this time and testing.

  • Thanks for all the effort. I think that there should be a workaround for us through the use of some registers on the NT3H2211. The only NAK that won't be distinguishable will be 4h for exceeding authentication attempts. As this isn't a current requirement I believe pre-checking registers and in some cases relying on the protocol error should work. 

    I am interested in the direct mode regardless to see if I can make this work. I do have the DLP-7970ABP so that should make this straightforward at least from a hardware perspective. I'll only need the direct mode after connecting to the tag as well. 

    Either way, the help and guidance is much appreciated. 

    Karl