The steps required to adapt the NFC Reader Library to a sample target MCU
This post entry provides a detailed description of how to port the NFC Reader Library to Kinetis K64F MCU. It is used a real porting example exercise to show the steps required to adapt the NFC Reader Library to a sample target MCU. The goal of this post is to serve as a guide for software developers requiring to port the NFC Reader Library to their MCU of choice for their designs.
NFC Reader Library overview
The NFC Reader Library is a software stack for creating and developing contactless applications for NXP’s NFC frontends and NFC controllers with customizable firmware. This library provides an API facilitates the most common operations required in NFC applications such as: reading or writing data into contactless cards, exchanging data with other NFC-enabled devices or emulating cards. The NFC Reader Library:
- It is based on a modular approach
- It has been designed with a flexible and multilayered architecture
- It is written in ANSI-C programming language
- It is supported in multiple design environments and platforms and it has been developed with a strong focus on portability.
- It is available for free download.
The NFC Reader Library v5.02.00 currently supports:
- All our NFC frontends (CLRC663 plus PN5180) and PN7462 NFC controller.
- Their corresponding development boards, used as NXP reference HW (CLEV6630B, PNEV5180B, PNEV7662B)
- And built-in MCU support for LPC1769, LPC11U68, FRDM-K82F and Raspberry Pi.
In addition, the release includes several examples to get familiar with the library and which can be used as reference for your developments and, it is also included an HTLM-based API documentation for all the components, which is generated from source-code annotations.
NFC Reader Library architecture
The NFC Reader Library is encapsulated into layers, differentiated by colors, and components, differentiated in boxes. From top to bottom, we have:
- The Application Layer (AL), which implements the command sets to interact with MIFARE cards and NFC tags.
- The NFC activity, which implements a configurable Discovery loop for the detection of contactless cards, NFC tags or other NFC devices.
- Next to it, the HCE and P2P components, for the emulation of Type 4 tags and P2P data exchange respectively.
- The protocol abstraction layer (PAL), which contains the RF protocol implementation of the ISO14443, Felica, vicinity and NFC standards.
- One level down, the hardware abstraction layer (HAL), which implements the drivers for controlling the NFC frontends RF interface and capabilities.
- Below, the Driver Abstraction Layer (DAL), newly introduced in the latest release, which implements the GPIO pinning, the timer configuration and the physical interface (BAL) between the host MCU and the reader IC.
- Finally, the OSAL module, in charge of abstracting the OS or RTOS specifics (handles tasks such as timers, events, semaphores and threads)
This layered architecture is helpful for several reasons:
- The eleven software examples, the Application Layer (AL) and the Protocol Abstraction Layer (PAL) are HW-independent, so that can be used on top of any NFC frontend.
- The the Application Layer (AL), the Protocol Abstraction Layer (PAL) and the Hardware Abstraction Layer (HAL) are platform-independent, so that can run in any MCU without any additional change.
In case the reader MCU is part of the built-in support, the examples can be directly imported and executed straight forward. On the other hand, in case the reader MCU is not supported by default, the major advantage is that only adaptations in the DAL and OSAL layers are required, while the rest of the layers can be used without any modification.
The NFC Reader Library structure can be seen more clearly when imported in the MCUXpresso development environment. After completing the import wizard, all projects are listed in the “Project Explorer” window. As can be seen in the screenshot, it contains different folders:
- API documentation folder
- Driver Abstraction Layer
- FreeRTOS support
- The platform support (in the screenshot, corresponding to the LPC support)
- The software examples (11)
- The Reader Library implementation
- And the OS abstraction layer
NFC Reader Library porting to FRDM-K64F steps
In the existing NFC Reader Library v5.02.00 release there is no native support for Kinetis K64F. However, it is included a pre-compiled package for Kinetis K82F MCU. We use the K82F NFC Reader Library package as a reference project to start the porting to K64F MCU. This package can be downloaded from www.nxp.com/pages/:NFC-READER-LIBRARY. The steps required to port the library to Kinetis K64F are:
- Prearing the HW (i.e the pining between the Kinetis and the NFC reader board).
- Setting up the development environment (i.e workspace).
- Perfoming some changes in project configuration settings
- Performing some code modifications in the DAL and application code for adding Kinetis K64F support.
NFC Reader Library porting to FRDM-K64F – Preparing the hardware
The hardware used for this porting exercise is:
- A CLEV6630B board (CLRC663 plus) as an NFC transceiver
- A FRDM-K64F board (Kinetis K64F) as host MCU, used to load and run the application logic.
The CLRC663 plus evaluation board is connected by default to an LPC1769 µC via SPI. However, the board is made in such a way that the LPC1769 MCU can be bypassed to connect an external MCU easily. For doing so:
- Six resistors from the board need to be removed. These are highlighted in red.
- Use the SPI pin connectors available on the left hand side, on the board edge.
Next, to connect the two boards together, the pining routing was done as follows:
- We use the Kinetis K64F jumper 2 pin line for the MOSI, MISO, chip select and clock lines of the SPI communication.
- The IRQ, interface selection and reset pins of CLRC663 plus are connected in jumper 1 pin line.
- And, one ground pin used for reference.
Therefore no complex HW manipulation was required since all interfaces are easily accessible via dedicated headers or test points.
Once the HW connection is prepared, we can move to setting up the development environment and workspace.
Get the latest NFC Reader Library release
From the software perspective, first we need to download the latest NFC Reader Library package. To do so:
- Go to NXP dot com slash pages slash NFC Reader Library (www.nxp.com/pages/:NFC-READER-LIBRARY)
- Go to the Downloads tab and click on the download button
- Click download on the NFC Reader Library for Kinetis K82Fpackage.
Generate a downloadable SDK package for FRDM-K64F board
As part of the NXP support, an SDK with drivers, middleware, RTOS demos and more is available for any of its Kinetis and LPC micros.We need to build the corresponding one to K64F SDK. For that:
- Navigate to www.mcuxpresso.nxp.com and select SDK builder option.
- Then, use the drop-down menus to customize your SDK configuration, middleware and optional software components be included in the package.
- Select Request build.
- In a few minutes, you will receive an email with a link to download the SDK package, very similar to the one showed in the figure below.
Import the NFC Reader Library into MCUXpresso workspace
Next step to configure the development environment is to import the library package in the workspace. The easiest way is to use the Quick Start Panel on the left hand side.
- Click on Import project from file system
- Then, browse the library package in your file system.
- Click Finish to import it all to your workspace.
The last step is to import the K64F customized SDK we configured from the MCUXpresso tools. To do so:
- Just drag and drop the SDK into the installed SDKs tab of the MCUXpresso IDE. (It will appear in the bottom part, in the center)
- Import the SDK into the workspace and link it with the software examples. It will appear as another folder in the project explorer window.
If the K64F SDK has been properly imported in the workspace, we should see a new drop-down menu for K64F. From there, we should select K64F and click Apply so that the memory details for K64F are set to the project example
NFC Reader Library porting to FRDM-K64F – Project configuration changes
At this point we have the hardware and the workspace for software development ready. In this step, we will start porting the NfcrdlibEx1_BasicDiscoveryLoop software example provided as part of the NFC Reader Library release.
Select FRDM-K64F SDK in the project MCU settings
One of the first configurations to be changed is the project MCU settings. These settings indicate which target host device is running the application code. These settings can be found if:
- You right click on the project example > Properties
- In the left-hand list of the Properties window, open “C++ build” and select “MCU settings”
- In the right-hand panel, we can observe the corresponding settings for K82F micro.
The left figure indicates the project configuration settings used by the default SW example prepared for K82F while the right figure indicates the final project configuration settings used by the SW example ported to K64F.
After that, we need to change the compiler preprocessor settings, which can be found in C++Build > Settings. In the project examples of the NFC Reader Library, the conditional directives like #ifdef and #ifndef are used to include or exclude portions of the code from the actual compilation. The conditional codes are included in the program compilation only if the MACROs are defined in the project compiler preprocessor settings.
In the left side we can see the defined macros for the original project. Among them, includes one which defines that the HW used is PN518 and K82F board. Therefore, in the ported project, we need to replace the macros corresponding to K82F with the new ones corresponding to K64F.
For instance, the PHDRIVER_K64_CLRC663 macro includes in the compilation the files related to the new HW used in the ported project (for the board pin and GPIO config, SPI settings or timers). Precisely, these files are included inside BoardSelection.h file in the Driver Abstraction Layer (DAL).
Add include paths for FRDM-K64F SDK files
When including header files into our project, the compiler must be told which directories must be searched to find those files. To do this:
- Open the project properties.
- In the left-hand list, open “C++ Build” and Select “Settings”.
- In the right-hand pane, choose the “Includes” section.
- Click the “Add icon”.
In the left figure, we see the compiler include paths for the K82F SDK of the original example. In the ported example, the K64F SDK sources will not yet compile since we did not tell the compiler about all the new include paths. Therefore, we need to add the new include paths pointing to the K64F SDK and put them into the MCUXpresso IDE project. In the right figure, you can see the paths we included for this purpose. Mainly, these paths reference to the board system init, board drivers, CMSIS files and debug utils.
Add include path for FRDM-K64F MCU assembler
The last MCUXpresso settings to be changed is in the MCU Assembler. This can be found in the right-hand panel, choose the “MCU Assembler” and select “General”.
In the original source code, a path is used to the K82F SDK. In the ported example, we just need to remove the previous include path and replace it with the corresponding one pointing to the K64F SDK in our workspace.
NFC Reader Library porting to FRDM-K64F – Code changes
So far, we have the HW, the development environment prepared and the project configuration settings changed. At this point, there are only a few code changes to be done before the porting is completed and the software example can be run in K64F.
DAL driver adaptation for FRDM-K64F
The layered architecture of the NFC Reader Library makes porting easier since only the lower drivers need to be adapted. This driver includes functions for:
- The physical link connection establishment between the CLRC663 plus and K64F
- The init functions for timers and interrupts so they are correctly used by the application layer.
Going to the NfcrdlibEx1-BasicDiscovery loop project structure, it contains several folders. If we open the DAL > board folder, we can observe one source file per each supported platform (LPC with PN5180 and CLRC663, and the same for Raspberry Pi and Kinetis K82F). Our task for the porting would be to create an equivalent source file for the new supported board, the K64F together with the CLRC663 (e.g. Board_FRDM_K64FRc663.h). This file includes
- The related board pin and GPIO configurations
- The SPI configuration
- The timer configuration
In addition, we need to include the board, pin_mux and clock config files.
Use SDK examples to get FRDM-K64F board specific configuration
Implementing these board specific files, in some cases, could be time consuming and may require experience. However, you do not need to do so but rather use the existing source files. For that, you can use any of the existing SDK software examples. You can easily import one SDK example by:
- Clicking the “Import SDK” example in the quick start menu > select the FRDM-K64F board.
- Selecting the demo example.
Each example application has its own unique copy of the board, pin mux, and clock config files that you can reuse for the porting (Note: this process could be different depending on the MCU used).
Add FRDM-K64F macro definitions in the source code
Next, along the project tree, we need to add the #ifdef directives, indicating that K64F board files that need to be compiled. This is the case for:
- The BoardSelection.h file
- The ph_NxpBuild_App.h, which links the board with the reader IC by enabling the CLRC663 plus module in the HAL layer.
- The ph_AppInit.h so that the board is initialized when the reader device boots.
Add FRDM-K64F CPU initialization code
The ph_AppInit.h file takes care of the code initialization and code specific to the HW used to run the example. As part of this ph_AppInit.h file, there is a function in charge of initialization the host MCU. Here, we need to implement the corresponding function for the K64F init, based on the SDK example source code selected earlier. If we look within this routine, we actually find functions for:
- Configuring the MCU clocks.
- Configuring the MCU pins.
- Configuring the interrupts (PIT).
NFC Reader Library porting to FRDM-K64F: NfcrdlibEx1_BasicDiscoveryLoop execution
After following the previous steps, the source code is succesfully ported to K64F. The following video demonstrates the correct execution of the NfcrdlibEx1_BasicDiscoveryLoop example in FRDM-K64F host MCU connected to CLRC663 plus NFC frontend (CLEV6630B).
The video includes a webcam, which records the HW, including all the witing wiring between the K64F and the CLRC663 plus antenna. After the code is built and compiled, the video shows how some tags are tapped to validate that the example is working as expected (tag’s UIDs are displayed in the MCUXpresso console). .
General considerations to port the NFC Reader Library to your target MCU
Overall, the general steps required to port the NFC Reader Library to your target MCU are:
- Adapt the MCU drivers to the DAL layer in the NFC Reader Library. This typically includes: timers, interrupts, pining and host interface configuration between the NFC reader and host MCU sides.
- Adapt the OS layer (i.e. you might need to port the FreeRTOS or to your target OS platform).
- Adapt the source code examples: project settings (macros, include paths, MCU configuration) and perform the required code modifications (Code for HW initialization, board files, etc).