I've ported the NXPNCI library examples over to a MCXN236 MCUXpresso board and keep getting errors within the NxpNci_CheckDevPres() function. It seems to fail on sending the NCICoreReset data. I've confirmed correct HW connections, but continue to get data failures in 3 different scenarios:
Scenario #1: Using FLEXIO_I2C_MasterTransferBlocking() with no retries, the program hangs in an infinite loop after receiving a shifter error flag from the FLEXIO module (which is interpreted as a NACK).
Scenario #2: Using FLEXIO_I2C_MasterTransferBlocking() with retries (3), the program aborts the write process after receiving a shifter error flag from the FLEXIO module (which is interpreted as a NACK).
Scenario #3: Using FLEXIO_I2C_MasterTransferNonBlocking() with retries (3), the program writes with no error, but fails when attempting to receive an answer back from the PN7160 NFC chip. This results in continuous writes with no returned data.
Per https://www.nxp.com/docs/en/user-manual/UM11496.pdf, I am setting up the pins accordingly and using the default device address 0x28.
I'm currently using the FLEXIO_I2C functions in place of the I2C functions called out in the original TML files for the examples. Since I'm using the pin, clock and peripheral configuration tools, I had to reroute some of the code in the TML files to point to the pin_mux.h/.c and peripheral.h/.c files.
I've attached the project here if anyone has the HW and wants to try. NOTE: because of file size limits, I had to separately compress the debug folder outside of the project folder. To bring up this project, you will either have to decompress the debug folder and place it back into the root folder for the project - OR - create a new debug as MCUXpresso IDE LinkServer.
Pinout from MCXN236 to OM27160 are as follows...
SCL: FLEXIO D21 (J4, Pin 12) ---> J2, Pin 1
SDA: FLEXIO D20 (J4, Pin 10) ---> J2, Pin 2
GND: J4, Pin 3 ---> J1, Pin 6
VDD: 3.3V (J3, Pin
VBAT: 5V (J3, Pin 10) ---> J1, Pin 5
IRQ: J7, Pin 4 ---> J1, Pin 10
VEN: J7, Pin 5 ---> J4, Pin 1
DWL_REQ: J6, Pin 6 ---> J4, Pin 2
Solved! Go to Solution.
I was finally able to get this pairing to work. A clue that helped me was getting the LPC824 example working, which didn't work unless I had the board directly mounted on top (no extra cable length attached between boards), which seems like a drive strength issue for the MCUXpresso boards.
Understanding that, I reconfigure my MCXN Xpresso board to have the same pinout that aligns with the arduino headers that connect to the OM27160A1EVK. Once I did that, I placed the OM27160A1EVK board directly on top of the Xpresso board using J1 through J4. I then, just soldered pins on top of the OM27160A1EVK I2C and IRQ signals to probe with a logic analyzer.
Another caveat that I noticed is that the program only seems to work when debug output (NCI_DEBUG) is enabled. For some reason, a time delay is needed between a buffer read and when it is being accessed for comparison. Otherwise, I get failures when the NCI library is comparing the received data to the expected response bytes. My assumption is that the debug adds extra time between read/write and buffer access, allowing the buffer to make the correct data available in memory.
The specific design that I'm working on should be tolerant of a small delay in reads, but this seems like a flaw for the MCXN236.
I was finally able to get this pairing to work. A clue that helped me was getting the LPC824 example working, which didn't work unless I had the board directly mounted on top (no extra cable length attached between boards), which seems like a drive strength issue for the MCUXpresso boards.
Understanding that, I reconfigure my MCXN Xpresso board to have the same pinout that aligns with the arduino headers that connect to the OM27160A1EVK. Once I did that, I placed the OM27160A1EVK board directly on top of the Xpresso board using J1 through J4. I then, just soldered pins on top of the OM27160A1EVK I2C and IRQ signals to probe with a logic analyzer.
Another caveat that I noticed is that the program only seems to work when debug output (NCI_DEBUG) is enabled. For some reason, a time delay is needed between a buffer read and when it is being accessed for comparison. Otherwise, I get failures when the NCI library is comparing the received data to the expected response bytes. My assumption is that the debug adds extra time between read/write and buffer access, allowing the buffer to make the correct data available in memory.
The specific design that I'm working on should be tolerant of a small delay in reads, but this seems like a flaw for the MCXN236.
Hello @KaiLi,
I momentarily switched over to one of the recommended platforms (LPC824) to see how it's expected to work and I've run into a couple of issues...
Please see attached debug log.
@KaiLi ,
In the case when it starts discovery and then enters an infinity loop, I see that the SCL and SDA lines get out of sync and there is a repeated pattern of read 0x7F with NACK
This screenshot above shows the bursts of data that occurs in the infinite loop in ~500ms intervals.
This screenshot above shows the repeated ~15ms burst of data that occurs every ~500ms.
Screenshot above shows the data within that burst in a zoomed in view. It also shows SDA and SCL getting out of sync and the IRQ signal toggling.
@KaiLi ,
Is there a list of commands that I can view to help debug? Sometimes I get an unexpected response. The NCIStartDiscovery command in NxpNci_StartDiscovery() is expecting [0x41, 0x03] for the first two byte, but gets back [0x41, 0x00]. Currently, I have no way of telling what this is supposed to mean.
Running the NXP-NCI2.0 example.
NCI >> 20 00 01 01
NCI << 40 00 01 00
NCI << 60 00 09 02 01 20 04 04 71 12 50 05
NCI >> 20 01 02 00 00
NCI << 40 01 1e 00 1a 7e 06 03 01 d0 02 ff ff 01 ff 00 08 00 00 01 00 02 00 03 00 80 00 82 00 83 ...
NCI >> 2f 00 01 00
NCI << 4f 00 01 00
NCI >> 20 02 05 01 00 02 fe 01
NCI << 40 02 02 00 00
NCI >> 20 03 03 01 a0 14
NCI << 40 03 25 00 01 a0 14 20 57 65 64 20 4d 61 72 20 31 32 20 31 34 3a 33 30 3a 30 35 20 32 30 ...
NCI >> 20 00 01 00
NCI << 40 00 01 00
NCI << 60 00 09 02 00 20 04 04 71 12 50 05
NCI >> 20 01 02 00 00
NCI << 40 01 1e 00 1a 7e 06 03 01 d0 02 ff ff 01 ff 00 08 00 00 01 00 02 00 03 00 80 00 82 00 83 ...
NCI >> 2f 02 00
NCI << 4f 02 05 00 00 01 aa dd
NCI >> 21 00 10 05 01 01 01 02 01 01 03 01 01 04 01 02 80 01 80
NCI << 41 00 01 00
NCI >> 21 03 07 03 00 01 01 01 06 01
NCI << 41 00 01 00 00 01 aa dd 01 d0
Error: cannot start discovery
Hello @shalom_greene
The problem should be in the porting of I2C driver , so you need to check whether the I2C communication is correct between MCU and PN7160.
Also, you can refer to the section 12.1 of AN13892 (https://www.nxp.com.cn/docs/en/application-note/AN13892.pdf) and trigger the NCI log to see what happened on your side.
Thanks for sharing the expected data from the example. I was able to modify the TML file enough to confirm the results of the NxpNci_CheckDevPres() function. I seem to get that data back fine, but then fail on the next command of NxpNci_HostTransceive(). It returns with no data. Initially, I thought that I needed a longer wait period for the data to be ready and IRQ to generate, but the IRQ signal remains low indefinitely after sending the NCICoreInit_2_0 (0x20, 0x01, 0x02, 0x00, 0x00) command.
Also, sometimes I notice that the data seems buffered or delayed from the PN7160. This seems to occur when the system comes up with the IRQ already high. I expect that the reset toggle on the VEN pin should set the IRQ back low, but it doesn't always do so.
Here is the data transaction that I'm getting.
I have to note here that I had to modify the tml_Receive() function to get this to work this far. And the system still only seems to work when using non-blocking I2C transfer functions.
Here's the code snippet for the receive function that I modified:
void tml_Receive(uint8_t *pBuffer, uint16_t BufferLen, uint16_t *pBytes, uint16_t timeout) {
PRINTF("\n\r*** New Read Triggered! ***\n\r");
//clear out buffer
memset(pBuffer,0x00,BufferLen*sizeof(uint8_t));
//Sleep(300);
tml_WaitForRx(timeout*10); //currently discarding error
Status ret = tml_Rx(pBuffer, BufferLen, pBytes);
PRINTF("\n\rtml_Rx status: %i, buffer length: %i\n\r", ret, *pBytes);
PRINT_BUF("\n\r***Current Buffer Content: ", pBuffer, *pBytes);
if ((GPIO_PinRead(BOARD_NXPNCI_IRQ_GPIO, BOARD_NXPNCI_IRQ_PIN) == 1)) {
PRINTF("\n\r*** IRQ still asserted! More data to read... ***\n\r");
PRINT_BUF("\n\r**BEFORE RETRY*** NCI << ", pBuffer, *pBytes);
if (ret == SUCCESS) {
PRINTF("\n\r*** Attempting to read remaining data. ***\n\r");
if(INTF_READ(&pBuffer[*pBytes], pBuffer[2]) == kStatus_Success)
{
*pBytes = *pBytes + ((pBuffer[2] + 3) - *pBytes);
}
else
{
PRINTF("\n\r*** Failed to read additional bytes ***\n\r");
}
}
else {
PRINTF("\n\r*** tml_Rx Failed initial read. Attempting to retry read with INTF_READ. ***\n\r");
if(INTF_READ(&pBuffer[*pBytes], pBuffer[2]) == kStatus_Success)
{
*pBytes = pBuffer[2] + 3;
}
else
{
PRINTF("\n\r*** Failed to read additional bytes ***\n\r");
}
}
PRINT_BUF("**AFTER RETRY*** NCI << ", pBuffer, *pBytes);
}
PRINTF("\n\rtml_Rx status: %i, buffer length: %i\n\r", ret, *pBytes);
PRINT_BUF("\n\r***Current Buffer Content: ", pBuffer, *pBytes);
}
Please also see log attached with some debug output.
Hello @KaiLi,
Thanks for the quick reply. I understand that there is an issue with the I2C communication. I just can't figure out what exactly is wrong. I've switch from using FLEXIO_I2C to use LPI2C via LP_Flexcomm, but I get the same results. When using the blocking transfer function, transmission aborts due to shifter error status flags. When using nonblocking transfer functions, I can see the data being transmitted out, but I get no reply form the PN7160.
I see that the data being transmitted is being acknowledged by the PN7160 device, but I'm not getting a response when trying to receive. The User Manual documentation for PN7160 says to wait for the IRQ pin to go high before requesting data. I see it go high, but it's in the middle of the data transfer. There is a function tml_Rx() in the NXPNCI Library that waits for this pin to go high but fails due to timeout. The pin only remains high for about 160ns, and seems to coincide with a glitch in the clock signal. So, the function aborts before attempting to read due to missing the interrupt. This occurs while sending the NCICoreReset command. Is this command expected to return any data?
Also, I assume that the fact that I'm getting ACKs back from the PN7160 means that it's alive, but how do I confirm that it's not in standby mode? I read that if the device is in standby mode, it will not respond
Here is the data that I've captured on a logic analyzer using the non-blocking transfer functions:
I realized that I didn't have the logic analyzer grounded. So, once I sync'd the grounds, I no longer see the glitch. So, I'm back to seeing data transmitted with ACK on each byte, but no IRQ or data generated by the PN7160.
So, my question still stands on how to ensure that the PN7160 is not in standby mode.
Feedback on the OM27160 devkit: It would be nice to have some LEDs to know status of the HW (i.e. RX/TX data being received/sent and an indicator for standby vs active mode). Right now, there is no way to tell what mode it's in and the WUP_REQ pin that is suggested for forcing the PN7160 out of standby is a NC according to the schematics.
Hello @shalom_greene
If you want to make sure the PN7160 is not in standby mode, you can configure it as follows:
/* NXP-NCI standby enable setting
* Refer to NFC controller User Manual for more details
*/
uint8_t NxpNci_CORE_STANDBY[]={0x2F, 0x00, 0x01, 0x00}; /* last byte indicates enable/disable */
Hello @shalom_greene
uint8_t NxpNci_CORE_STANDBY[]={0x2F, 0x00, 0x01, 0x00}; /* last byte indicates enable/disable */
0x00: disable Standby
0x01: enable standby