This document provides a guide on how to use the NFC frontend PN5190 with the FRDM-MCXN947 and using the latest existing version of the NFC Reader Library.
Location of the changes mentioned above can be seen in the following image:
Habib_MS_0-1781132345846.png
Routing NFC module communication pins to JP1
To enable the pins on JP1 for communication, we must enable bus switch U10 and disable bus switch U12 in the NFC Host Interface. These switches enable or disable the connections from K82 to PN5190 SPI pins, and expose the SPI interface to an external host.
Remove short on R5 to disable communication routing to K82F.
Place short on R7 to enable communication routing to JP1 pins.
Habib_MS_2-1781132571269.png
For FRDM-MCXN947 side, no modifications are necessary. The pins used are available in Header J1 and J2. Which are shown in the following table.
Name
MCXN947
PN5190
SCK
J2.12
JP1.1
MOSI
J2.8
JP1.2
MISO
J2.10
JP1.3
SSEL
J2.6
JP1.4
IRQ
J1.16
JP1.5
RESET
J2.2
JP6.1
GND
J2.14
JP1.10
SUCCESS
J2.17*
FAIL
J2.15*
DWL
J2.13*
* Pins that need to be configured for library compatibility but are not used and do not need to be connected.
Software Changes
This section describes the software changes required to run the “NfcrdlibEx1_DiscoveryLoop” example from the NFC Reader Library which consists in a detection loop that displays in a terminal information (like UID, SAK, and Product Type for MIFARE product-based cards) about any tag detected by the PN5190. Please download the NFC Reader Library for PN5190 from NFC Reader Library | NXP Semiconductors.
To begin with the migration, we first need to create a project with the FRDM-MCXN947 SDK (v26.06.00), for this purpose download and install the FRDM-MCXN947 SDK from the SDK Builder.
Importing NFC Reader Library
Click on “File” from upper tab menu and “Import…”.
In the Import wizard, select “Existing Projects into Workspace”.
In the “Select root directory” search the directory where the downloaded library is located and click on Finish (do not check the “Copy projects into workspace” option).
Habib_MS_0-1781133143312.png
Note: If the K82 SDK is not installed an error message will appear, please click on cancel.
Habib_MS_0-1782234443148.png
Creating base project
1. In the Quick Start panel click on “import SDK example(s)…” in the MCUXpresso IDE.
2. Select “frdmmcxn947” and click on next.
Habib_MS_1-1781133200020.png
3. Select the SDK example “hello_world_cm33_core0” and click on finish.
Habib_MS_2-1781133254045.png
4.Now we will add the required drivers for migration, which are SPI and CTIMER drivers. . Click on properties-> SDK Management-> Manage SDK Components.
Habib_MS_3-1781133444305.png
5. Search in the filter bar “ctimer” and “lpspi” and check their boxes to add them and click on OK.
Habib_MS_5-1781133510047.png
Habib_MS_6-1781133576098.png
Add the source code Discovery Loop Example
From the imported example NfcrdlibEx1_DiscoveryLoop_mcux of the NFC Reader Library, find and copy the following files (included in src folder): NfcrdlibEx1_EmvcoProfile.c, phApp_Helper.c, phApp_Init.c, phApp_PN5190_Init.c; and paste them into the source folder inside the created base project. Additionally, delete the file hello_world .c created by the project.
Additionally, we need to add the file “NfcrdlibEx1_DiscoveryLoop.c” which is the main source file of the project, to do this right-click on the “source” folder of our project and then put the cursor on “New” and select “File”.
Habib_MS_2-1781134090137.png
In the tab that will open, write the name of the file (NfcrdlibEx1_DiscoveryLoop.c) and then, click on “Finish”.
Habib_MS_3-1781134114470.png
Finally, in the created file copy and paste all the code inside the original source file located in the library example.
Habib_MS_4-1781134170782.png
Habib_MS_5-1781134196935.png
Link the NFC Reader Library elements
To make the required software changes, we need to link the DAL, NxpNfcRdLib, phOsal and intfs folders into the base project, to do this:
1. In the Project Explorer, right click on the project and place your cursor on New and click on Folder.
2. In the New Folder tab, click on “Advanced >>” and select “Link to alternate location (Linked Folder)” and on “Browse…”.
Habib_MS_6-1781134337471.png
3. Browse into the path where the library was extracted, choose the NxpNfcRdLib folder and click on Finish.
Habib_MS_7-1781134383646.png
4. Do the same procedure for “Platform/DAL”, “Examples/NfcrdlibEx1_DiscoveryLoop/intfs” and “RTOS/phOsal” folders.
If you have the folder in the same project explorer, the included folder will not appear, but you can see it when you open the window to add another folder, as shown in the following figure.
Habib_MS_8-1781134451238.png
But if the included folders are not in the Project Explorer, the Project should look like this:
Habib_MS_9-1781134500816.png
Once this is done, we will need to delete the “KinetisSDK” folder located in “DAL > src” to avoid multiple definition issues.
Habib_MS_10-1781134521814.png
Define FRDM-MCXN947 SDK preprocessor symbol
We need to do some changes to the compiler preprocessor configuration.
1. Right click on the project in the Project Explorer and click on “Properties…
Habib_MS_0-1781134734232.png
2. In the properties tab, go to “C/C++ Build > Settings > MCU C Compiler > Preprocessor”. The symbols are related with the FRDM board, but we need to add the following symbols related with the NFC Reader Library:
PH_OSAL_NULLOS
PHDRIVER_FRDMMCXN947_PN5190_BOARD
NXPBUILD_CUSTOMER_HEADER_INCLUDED
PHDRIVER_MCXN947_SPI_POLLING
Habib_MS_1-1781134774044.png
Click on the “Add...” button at the top right corner of the “Defined symbols (-D)” menu and enter each symbol mentioned before.
Habib_MS_0-1782235762579.png
These symbols are added so the preprocessor knows which header files to include at build time.
PHDRIVER_FRDMMCXN947_PN5190_BOARD will help include the BoardSelection.h header, the file that is going to define addresses for registers and peripherals of MCXN947.
PH_OSAL_NULLOS will include headers related to non-OS operation, meaning that the project will work without any operative system (at the end of this guide you will find the steps to add FreeRTOS support).
NXPBUILD_CUSTOMER_HEADER_INCLUDED will add headers to add and select the NFC reader and host that will be used in the project.
PHDRIVER_MCXN947_SPI_POLLING if is defined the example will perform SPI communication by polling method, and if not, will be perform through non-blocking transfers.
3. Once added, click on “Apply and Close”, "Rebuild Index" and then to “Yes” to save the changes.
Modifying the Driver Abstraction Layer (DAL)
The added linked folder DAL will contain the important changes to be able to use the MCXN947 as host device since it will contain all the changes regarding SPI, timer and GPIO configurations required by the library to work properly.
Board_FRDM_MCXN947_PN5190.h
We need to create a header file that will contain important macros used by the library that are related to the host specific SPI, timer and GPIO peripherals, as well as interrupt vectors and priorities, clock sources and addresses. This file is required to be inside the “boards” folder which is inside DAL. Please add the header file as the file created NfcrdlibEx1_DiscoveryLoop.c but replacing .c to .h:
Habib_MS_1-1782236163267.png
Habib_MS_0-1781196980059.png
The file should be named as shown in the picture above.
Inside this file, some important macros related to the SPI peripheral and the important pins to be handled (IRQ, Chip Select, Reset) are defined.
Now, inside DAL > src folder we will create a folder named “MCXN947” that will contain 2 source files:
phbalReg_Mcxn947Spi.c
phDriver_Mcxn947SDK.c
Habib_MS_3-1781198965225.png
Inside these source files we will modify the functions from the source files of other board hosts with the specific configurations of MCXN947 peripheral drivers, such as SPI, timers, GPIOs and interrupt handlers. This is done based on SDK examples such as “ctimer_match_interrupt_example_cm33_core0” and “lpspi_polling_b2b_transfer_master_cm33_core0”.
phbalReg_Mcxn947Spi.c:
In this file we first need to include the necessary files and include the headers and callbacks to ensure the correct functionality:
After, we will define the phbalReg_Init function, which will be used by the library to initialize the SPI peripheral in this case, and it is defined as follows:
static void phbalReg_Mcxn947SpiConfig(void)
{
const port_pin_config_t port0_24_pinB6_config = {
kPORT_PullUp,
kPORT_LowPullResistor,
kPORT_SlowSlewRate,
kPORT_PassiveFilterDisable,
kPORT_OpenDrainDisable,
kPORT_LowDriveStrength,
/* Pin is configured as FC1_P0 */
kPORT_MuxAlt2,
kPORT_InputBufferEnable,
kPORT_InputNormal,
kPORT_UnlockRegister};
/* PORT0_24 (pin B6) is configured as SPI_MOSI */
PORT_SetPinConfig(PORT0, 24U, &port0_24_pinB6_config);
const port_pin_config_t port0_25_pinA6_config = {kPORT_PullUp,
kPORT_LowPullResistor,
kPORT_SlowSlewRate,
kPORT_PassiveFilterDisable,
kPORT_OpenDrainDisable,
kPORT_LowDriveStrength,
/* Pin is configured as FC1_P1 */
kPORT_MuxAlt2,
kPORT_InputBufferEnable,
kPORT_InputNormal,
kPORT_UnlockRegister};
/* PORT0_25 (pin A6) is configured as SPI_SCK */
PORT_SetPinConfig(PORT0, 25U, &port0_25_pinA6_config);
const port_pin_config_t port0_26_pinF10_config = {kPORT_PullUp,
kPORT_LowPullResistor,
kPORT_SlowSlewRate,
kPORT_PassiveFilterDisable,
kPORT_OpenDrainDisable,
kPORT_LowDriveStrength,
/* Pin is configured as FC1_P2 */
kPORT_MuxAlt2,
kPORT_InputBufferEnable,
kPORT_InputNormal,
kPORT_UnlockRegister};
/* PORT0_26 (pin F10) is configured as SPI_MISO */
PORT_SetPinConfig(PORT0, 26U, &port0_26_pinF10_config);
const port_pin_config_t port0_27_pinE10_config = {kPORT_PullUp,
kPORT_LowPullResistor,
kPORT_SlowSlewRate,
kPORT_PassiveFilterDisable,
kPORT_OpenDrainDisable,
kPORT_LowDriveStrength,
/* Pin is configured as FC1_P3 */
kPORT_MuxAlt2,
kPORT_InputBufferEnable,
kPORT_InputNormal,
kPORT_UnlockRegister};
/* PORT0_27 (pin E10) is configured as SPI_CS */
PORT_SetPinConfig(PORT0, 27U, &port0_27_pinE10_config);
}
phDriver_Mcxn947SDK.c:
In this file we will have the following definitions and includes that describe relevant characteristics of the ctimer (configuration structures, interrupt handlers and maximum count value), and of the GPIO port:
With these additions, we have all the functions needed (based on the FRDM-MCXN947 SDK) by the library to communicate with the PN5190.
BoardSelection.h
In this header file, which is found at “DAL > cfg” we will add the definition set in the preprocessor settings to use the FRDM-MCXN947 board as host by adding the following lines to the file:
In this header located at “intfs” folder we will add the required include files for the initialization of our board and enable the correct debug interface.
Finally, in this source file we will add the initialization code for the MCXN947 to complement the initialization macros defined in the previous phApp_Init.h file modification. Here we will call functions to initialize clocks and UART pins.
These functions are used to initialize the correspondent clocks of each peripheral such as CTIMER, the input pins multiplexor for selecting GPIO functionality and FLEXCOMM for SPI. In here we also set the GPIO functionality for pins P0_31 and P0_28 (IRQ and RESET), as well as UART3 for printing the tag information on the serial port connected to the computer.
Additionally, we need to set the NVIC priority to ensure that interrupts can occur. Add the NVIC_SetPriority() function to phApp_Configure_IRQ().
void BOARD_InitBootPins(void)
{
/* Use FRO HF clock for some of the Ctimers */
CLOCK_SetClkDiv(kCLOCK_DivCtimer0Clk, 1u);
CLOCK_AttachClk(kFRO_HF_to_CTIMER0);
CLOCK_EnableClock(kCLOCK_Gpio0);
CLOCK_EnableClock(kCLOCK_Gpio1);
BOARD_InitPins();
}
Additionally, within the “BOARD_InitPins()” function available in the same file, we will replace the initializations of the GPIO and UART pins.
Since we are including header files into the project, we must specify which directories to search in order to find the required files. To do this:
1. Open project properties (right-click on project > Properties).
2.Click on the drop menu “C/C++ Build”, then “Settings”.
3.Click on “Includes” option.
Habib_MS_1-1781208012765.png
4.Click on the “Add..” button at the top right corner of the “Include paths (-l)” menu.
5. Click on “Workspace…”
Habib_MS_2-1781208068003.png
6. Add the following highlighted directories from FRDM-MCXN project:
Habib_MS_3-1781208097487.png
7. Accept the changes and click on “Apply and Close”.
Add “root folder” to source location
1.Open project properties.
2. Click on the drop menu “C/C++ General”, then “Paths and Symbols”.
3. Click on the “Source Location” tab.
4.Click on “Add Folder…” and add the “<root folder>”.
Habib_MS_4-1781208199983.png
Delete phOsal files
We must delete from the path “phOsal > src > NullOs > portable” the files: “phOsal_Port_CM3.c”,“phOsal_Port_PN76xx.c” and “phOsal_Port_PN74xxxx.c”. This has the purpose of avoiding any multiple definition errors when compiling the final project.
Add _DSB and _ISB support
As final modification step, please include in NxpNfcRdLib->comps->phhalHw->src->PN5190-> phhalHw_Pn5190_Int.c the “cmsis_gcc.h” to support of _DSB and _ISB functions.
Habib_MS_5-1781208264265.png
Testing Final Project Without OS
After making all the previous changes and modifications, the migration is now complete, and we can proceed to compile and flash the example to MCXN947.
Please “clean” the project before building by right clicking on the project as follows:
Habib_MS_6-1781208329457.png
To run the project, we will need a serial terminal like Tera Term with the following settings:
- 115200 baud rate.
- 8 data bits.
- No parity.
- One stop bit,
- No flow control.
Once the program is flashed and the serial terminal configured, we can reset the board and power the PNEV5190BP. You should see an output similar to the following:
Habib_MS_7-1781208358485.png
Now if any NFC tag is close to the PNEV5190BP’s antenna, you should see the information displayed as shown in the image below:
Habib_MS_8-1781208378570.png
Adding FreeRTOS support
This section presents the steps to follow to add FreeRTOS support to the current project with the possibility of easily choosing either to have OS support or not.
1. Open the “Manage SDK Components” in properties->SDK Management.
Habib_MS_9-1781208421419.png
2. Search the FreeRTOS kernel component (NXP integration layer), heap 4 and add it to your project.
Habib_MS_0-1785533111303.png
Note: If this option does not appear, you will have to download the SDK with the FreeRTOS stack included.
Adding porting-specific files to FreeRTOS folder
We need to set the core-specific files which define core register addresses and the assembly instructions that integrate the FreeRTOS kernel functions. The core integrating the MCXN947 IC is the Cortex M33 with Trust Zone, therefore, the folder that we will use to add the port files will be from the folder “ARM_CM33_NTZ” as explained below:
1. Import the SDK example called “freertos_hello_cm33_core0”:
Habib_MS_11-1781208505026.png
2. Inside this example, you will see the folder “GCC” from the path freertos>freertoskernel>portable>GCC, please copy and paste this folder into the same path of the project.
Adding port-specific created folder to include path.
Now we need to tell the compiler where to find the port-specific files we just added to the project, to accomplish this:
1. Open the project properties (right-click on project > Properties) and click on “C/C++ General” and on “Paths and symbols”.
Habib_MS_14-1781208609258.png
2. Here we will click on “Add…” and then “Workspace”. In the new tab we will search the last folder of the path we created (freertos/freertoskernel/portable/GCC/ARM_CM33_NTZ/non-secure), select it and click on “OK”
Habib_MS_1-1785533523574.png
3. Repeat this step in project > Properties > “C/C++ Build” >Settings >“Includes”.
Habib_MS_16-1781208764822.png
Changing OS preprocessor macro
Finally, we just need to tell the compiler that we want to run the example with FreeRTOS, to do this:
1. Open the project properties (right-click on project > Properties) and click on “C/C++ Build”, then on “Settings” and on “Preprocessor”.
Habib_MS_17-1781208849806.png
2. Now find the previous macro named “PH_OSAL_NULLOS”, double click on it and change it to “PH_OSAL_FREERTOS”
Habib_MS_18-1781209097027.png
3. Click on “Apply and Close” and click on “Rebuild Index”.
4. To avoid multiple definition issues when we change between NULLOS and FREERTOS, we will discard the SysTickHandler for FREERTOS side located in port.c when the NULLOS macro is defined, as shown the following image:
5. Finally, copy and paste the FreeRTOSConfig_Gen.h, FreeRTOSConfig.h and freertos_tasks_c_additions.h files from the freertos_hello example as shown the following image: