2387149_en-US

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

2387149_en-US

2387149_en-US

NFC Reader Library Migration to FRDM-MCXN947 on VS code

Introduction.

This document provides a guide on how to use the NFC frontend PN5190 with the FRDM-MCXN947 and using the NFC Reader Library.

The hardware required to follow this guide is:

Software Setup.

  • MCXN947 SDK version: 26.03.00
  • NFCReaderLibrary version: 07.14.00
  • PN5190 FW version: 0x20D

Hardware connections.

The PNEV5190 comes with a Kinetis K82F as a host MCU to drive the PN5190

Since the goal is to drive PN5190 from the MCXN947 via SPI, we need to prepare the PNEV5190 for it:

  • Power up board correctly
  • Enable external SPI pins
  • Disable K82F interface with PN5190

Power up and jumper configuration

  • To power up the board correctly:

– Powering it up over USB does not provide enough current. It will be powered with an external power supply of 7.5V over connector J17.

  • Put jumper on following pins:

– J9 2-3: External power supply

– J8: VBATPWR supplied with VBAT=3.3 V

– J12: VBAT supplied with 3.3 V

  • Remove jumpers on following pins:

– J22, J23: open SDA signals for K82F

– J19: RTS push-button bypass for K82F

– J3, J4, J5, J6: pull down jumpers for NFC module signals

 

  • Set GPIO and SPI voltage to 3.3 V: supplying 3.3 V to VDDIO and the μC supply:

– Remove short circuit on R19

– Place short circuit on R20

Location of the changes mentioned above can be seen in the following image:


Habib_MS_0-1782499687907.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_1-1782499777420.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 integration, we first need to import a “hello_world” project from the FRDM MCXN 947 SDK (v26.03.00) into the MCUXpresso IDE for VS code, for this purpose download and install the FRDM-MCXA156 repository (version 26.03) from the extension in quickstart panel-> import repository. For more information about this process, you can consult this guide.

Importing NFC Reader library.


Download the “NFC Reader Library” zip from the product page and extract in a known folder. This will be useful for later use. 

Importing base project


1. In the Quick Start panel click on “Import Example from Repository” in VS code.

Habib_MS_0-1782500337538.png

2. Select “FRDM-MCXN947” in board setting.

Habib_MS_1-1782500355284.png

3. In the template will search for the “freertos_hello_cm33_core0” example, select Freestanding Application, chose the location and click on “import”.

Habib_MS_2-1782500369308.png

Importing SDK drivers


Once the project is added to the workspace we will need to add the required drivers, which are SPI, CTIMER and CMSIS drivers. For this we need to add the following code in the prj.cfg file.


Habib_MS_3-1782500385724.png
Spoiler
CONFIG_MCUX_COMPONENT_driver.lpflexcomm_lpspi=y
CONFIG_MCUX_COMPONENT_driver.ctimer=y
CONFIG_MCUX_COMPONENT_driver.CMSIS=y

Add the source code Discovery Loop Example


Firstly, delete the file freertos_hello.c created by the project.

From the “NxpNfcRdLib_PN5190_v07.14.00_PUB” extracted, find and drag and drop the following files on in the project files folder: NfcrdlibEx1_EmvcoProfile.c, phApp_Helper.c, phApp_Init.c, phApp_PN5190_Init.c. You can find these files in the following path:

{NxpNfcRdLibRoot} \Examples\NfcrdlibEx1_DiscoveryLoop\src

Habib_MS_2-1782504550792.png

When you drag and drop a file into VS code a window will appear asking whether you want to link the file or copy it. Please select “Copy files.”

Habib_MS_3-1782504569947.png

After dragging and dropping any file, the CMakeLists.txt file is automatically updated to include all the copied .c files. If you selected all these files, the generated code will appear as follows:

Habib_MS_4-1782504588274.png

Additionally, we need to add the file “NfcrdlibEx1_DiscoveryLoop.c” which is the main source file of the project, to achieve this also please drag and drop in the project files folder.

Habib_MS_5-1782504604217.png

At this point, the project should look like this:       

Habib_MS_6-1782504632756.png

Add the example source code to the newly created MCXN947 project


From the “NxpNfcRdLib_PN5190_v07.14.00_PUB” extracted just drag and drop in the project files folder the following folders.

Habib_MS_0-1782504704260.png
Habib_MS_1-1782504734285.png
Habib_MS_2-1782504750818.png

Habib_MS_3-1782504795659.png

Once these folders are added the project should look like this:


Habib_MS_0-1782506609973.png

Define FRDM-MCXN947 SDK preprocessor symbol


We need to make some changes to the compiler preprocessor configuration related to the NFC reader library, to do this we need to modify the Cmakelist.txt

  • PH_OSAL_FREERTOS
  • PHDRIVER_FRDMMCXN947_PN5190_BOARD
  • NXPBUILD_CUSTOMER_HEADER_INCLUDED
  • PHDRIVER_MCXN947_SPI_POLLING
Habib_MS_0-1782505699286.png
Spoiler
mcux_add_macro(
    CC   "NXPBUILD_CUSTOMER_HEADER_INCLUDED\
    PHDRIVER_FRDMMCXN947_PN5190_BOARD\
    PH_OSAL_FREERTOS\
    PHDRIVER_MCXN947_SPI_POLLING"
)

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_FREERTOS will include headers related to OS operation, meaning that the project will work with operative system (at the end of this guide you will find the steps to add NULLOS 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.

Modifying the Driver Abstraction Layer (DAL)


The added 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.

1. Go to explorer window and select “add file” on the boards folder:

Habib_MS_1-1782505314578.png

2. Write the file’s name as follows (Board_FRDM_MCXN947_PN5190.h) and click enter:

Habib_MS_2-1782505345384.png

A window like the one shown in the following figure will appear. However, it can be discarded. This window is intended to add the newly created file to the CMakeLists.txt file, but we will instead include the entire folder later.

Habib_MS_3-1782505364793.png

Inside this file, some important macros related to the SPI peripheral and the important pins to be handled (IRQ, Chip Select, Reset) are defined.

Habib_MS_4-1782505388079.png
Spoiler
#ifndef DAL_BOARDS_BOARD_FRDM_MCXN947_PN5190_H_
#define DAL_BOARDS_BOARD_FRDM_MCXN947_PN5190_H_
#define GPIO_PORT 0
#define GPIO_PORT1 1
/******************************************************************
* LPSPI clock configuration
******************************************************************/
/*Clock Frequency for SPI Flexcomm 1*/
#define SPI_CLOCK_FREQ (CLOCK_GetLPFlexCommClkFreq(1u))
#define SPI_MASTER_CLOCK_FREQ SPI_CLOCK_FREQ
/******************************************************************
* Board Pin/Gpio configurations
******************************************************************/
#define PHDRIVER_PIN_RESET ((GPIO_PORT << 8) | 28) /**< Reset pin, Pin28, PIO0_28 */
#define PHDRIVER_PIN_IRQ ((GPIO_PORT << 8) | 31)  /**< IRQ pin, Pin10, PIO0_10 */
/* For 5190 busy is same as IRQ */
#define PHDRIVER_PIN_BUSY ((GPIO_PORT << 8) | 31)  /**< IRQ pin, Pin31, PIO0_31 */
#define PHDRIVER_PIN_DWL    ((GPIO_PORT << 8) | 19)  /**< Download pin, Pin19, PIO0_19*/
/* These pins are used for EMVCo Interoperability test status indication,
 * not for the generic Reader Library implementation.
 */
#define PHDRIVER_PIN_SUCCESS   ((GPIO_PORT1 << 8) | 0)   /**< GPIO, Port 1, Pin0 */
#define PHDRIVER_PIN_FAIL      ((GPIO_PORT1 << 8) | 1)   /**< GPIO, Port 1, Pin1 */
/******************************************************************
* PIN Pull-Up/Pull-Down configurations.
******************************************************************/
#define PHDRIVER_PIN_RESET_PULL_CFG    PH_DRIVER_PULL_UP
#define PHDRIVER_PIN_IRQ_PULL_CFG      PH_DRIVER_PULL_DOWN
#define PHDRIVER_PIN_WKUP_PULL_CFG     PH_DRIVER_PULL_UP
#define PHDRIVER_PIN_CLK_PULL_CFG      PH_DRIVER_PULL_UP
#define PHDRIVER_PIN_DWL_PULL_CFG      PH_DRIVER_PULL_UP
#define PHDRIVER_PIN_NSS_PULL_CFG      PH_DRIVER_PULL_UP
#define PHDRIVER_PIN_BUSY_PULL_CFG     PH_DRIVER_PULL_UP

We define the macros as well for the interrupt vector of MCXN947, its priority, handler and trigger type.

Habib_MS_5-1782505436112.png
Spoiler
/******************************************************************
* IRQ PIN NVIC settings
******************************************************************/
#define EINT_IRQn GPIO00_IRQn /*Adding interrupt vector A of GPIO*/
#define EINT_PRIORITY 7 /*Default interrupt priority for GPIO*/
#define CLIF_IRQHandler GPIO00_IRQHandler /*Interrupt handler for vector A*/
#define PIN_IRQ_TRIGGER_TYPE PH_DRIVER_INTERRUPT_RISINGEDGE /*Rising edge Trigger*/

As well as some macros for pin logic levels.

Habib_MS_6-1782505468893.png
Spoiler
/*****************************************************************
* Front End Reset logic level settings
****************************************************************/
#define PH_DRIVER_SET_HIGH 1 /**< Logic High. */
#define PH_DRIVER_SET_LOW 0 /**< Logic Low. */
#define RESET_POWERDOWN_LEVEL PH_DRIVER_SET_LOW
#define RESET_POWERUP_LEVEL PH_DRIVER_SET_HIGH

Finally, we define macros for the base address of CTIMER and SPI peripherals, clock frequencies, interrupt vectors and related pins.

Habib_MS_7-1782505509612.png
Spoiler
/*****************************************************************
* SPI Configuration
****************************************************************/
#define PHDRIVER_MCXN947_SPI_MASTER LPSPI1
#define PHDRIVER_MCXN947_SPI_DATA_RATE 5000000U
#define PHDRIVER_MCXN947_SPI_CLK_SRC SPI_MASTER_CLOCK_FREQ
#define PHDRIVER_MCXN947_SPI_IRQ LP_FLEXCOMM1_IRQn
#define SPI_IRQ_PRIORITY 6 /*SPI interrupt priority*/
#define PHDRIVER_PIN_SSEL  27U/* Chip Select, Pin6, SPI */
#define PHDRIVER_PIN_SCK   25U/* SPI clock, Pin7, SPI */
#define PHDRIVER_PIN_MISO  26U/* MISO, Pin8, SPI */
#define PHDRIVER_PIN_MOSI  24U/* MOSI, Pin9, SPI */
#define PHDRIVER_FC1_SPI_DIV kCLOCK_DivFlexcom1Clk
#define PHDRIVER_FC1_SPI_CLK kFRO12M_to_FLEXCOMM1 /*Clock to attach to Flexcomm1*/
/*****************************************************************
* Timer Configuration
****************************************************************/
#define PH_DRIVER_SDK_CTIMER CTIMER0 /*CTIMER0 base*/
#define PH_DRIVER_SDK_CTIMER_CLK  kCLOCK_DivCtimer0Clk/*CTIMER0 clock*/
#define PH_DRIVER_SDK_CTIMER_NVIC CTIMER0_IRQn /*Interrupt vector*/
#define PH_DRIVER_SDK_CTIMER_PRIORITY 4
#define PH_DRIVER_SDK_CTIMER_CLK_FREQ CLOCK_GetCTimerClkFreq(0U) /*CTIMER0 Clock frequency*/

#endif /* DAL_BOARDS_BOARD_FRDM_MCXN947_PN5190_H_ */

MCXN947 SPI and SDK files

 Now, inside DAL > src folder we will create a folder named “MCXN947” that will contain 2 source files:

  • phbalReg_Mcxn947Spi.c
  • phDriver_Mcxn947SDK.c

1. Firstly, we will need to delete the “KinetisSDK” folder located in the src folder to avoid multiple definition issues. Please right-click on src/KinetisSDK and click on “Delete”:

Habib_MS_1-1782505869521.png
 
2. A window as the following figure will appear, please click on “Move to Recycle Bin”:
Habib_MS_2-1782505893781.png

3. In the same folder please right-click and click on “New folder…”:

Habib_MS_3-1782505917835.png

4. Write the folder’s name as follows (MCXN947) and click enter:

Habib_MS_4-1782505943176.png

5. Add both files following the same steps mentioned in the section Board_FRDM_MCXN947_PN5190.h but with those files (phbalReg_Mcxn947Spi.c and phDriver_Mcxn947SDK.c). We will add these source files in the CMake_List.txt on the next step.

Once these files are added the src folder should look like this:

Habib_MS_5-1782505974388.png

6. Finally, we will add both files to the CMakeLists.txt file so they are included in the compilation process. Please add the following code in the CMake_list.txt file:

Habib_MS_6-1782505996170.png
Spoiler
mcux_add_source(BASE_PATH ${CMAKE_CURRENT_LIST_DIR}
    SOURCES "DAL/src/MCXN947/phbalReg_Mcxn947Spi.c"
    "DAL/src/MCXN947/phDriver_Mcxn947SDK.c")

Although the Kinetis SDK folder has been deleted, it is still referenced in the CMakeLists.txt file. Please remove those includes from this file.

Now we will return to the MCUxpresso extension. 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:

Habib_MS_1-1782506156720.png
Spoiler
#include "phDriver.h"
#include 
#include "BoardSelection.h"
#include 
#include 
#include 

#define PHBAL_REG_MCXN947_SPI_ID 0x0FU /**< ID for MCXN947 SPI BAL component */
#define RX_BUFFER_SIZE_MAX                     272U /* Receive Buffer size while exchange */

#ifndef PHDRIVER_MCXN947_SPI_POLLING
lpspi_master_handle_t g_masterHandle;
/* LPSPI user callback */
void LPSPI_MasterUserCallback(LPSPI_Type *base, lpspi_master_handle_t *handle, status_t status, void *userData);
#endif
static void phbalReg_Mcxn947SpiConfig(void);
#ifndef PHDRIVER_MCXN947_SPI_POLLING
volatile bool isTransferCompleted  = false;
void LPSPI_MasterUserCallback(LPSPI_Type *base, lpspi_master_handle_t *handle, status_t status, void *userData)
{
    if (status == kStatus_Success)
    {
        __NOP();
    }
    isTransferCompleted = true;
}
#endif

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:

Habib_MS_2-1782506214363.png
Spoiler
/**
* \brief Initialize the Rw612 SPI BAL layer.
*
* \return Status code
* \retval #PH_DRIVER_SUCCESS Operation successful.
* \retval #PH_ERR_INVALID_DATA_PARAMS Parameter structure size is invalid.
*/

phStatus_t phbalReg_Init( void * pDataParams, uint16_t wSizeOfDataParams)
{
	lpspi_master_config_t userConfig;
	uint32_t srcFreq = 0;
	if((pDataParams == NULL) || (sizeof(phbalReg_Type_t) != wSizeOfDataParams))
	{
	return (PH_DRIVER_ERROR | PH_COMP_DRIVER);
	}
	((phbalReg_Type_t *)pDataParams)->wId = PH_COMP_DRIVER | PHBAL_REG_MCXN947_SPI_ID;
	((phbalReg_Type_t *)pDataParams)->bBalType = PHBAL_REG_TYPE_SPI;
	/*Initialize Flexcomm1 clock*/
	/* attach FRO 12M to FLEXCOMM1 */
	CLOCK_SetClkDiv(PHDRIVER_FC1_SPI_DIV, 1u);
	CLOCK_AttachClk(PHDRIVER_FC1_SPI_CLK);
	/*Configure SPI pins*/
	phbalReg_Mcxn947SpiConfig();
	/*SPI configuration*/
	LPSPI_MasterGetDefaultConfig(&userConfig);
	userConfig.baudRate = PHDRIVER_MCXN947_SPI_DATA_RATE;
	srcFreq = SPI_MASTER_CLOCK_FREQ;
	userConfig.whichPcs = (lpspi_which_pcs_t)kLPSPI_Pcs0;
	userConfig.pcsActiveHighOrLow = (lpspi_pcs_polarity_config_t)kLPSPI_PcsActiveLow;
	userConfig.pcsToSckDelayInNanoSec        = 1000000000U / (userConfig.baudRate * 1U);
	userConfig.lastSckToPcsDelayInNanoSec    = 1000000000U / (userConfig.baudRate * 1U);
	userConfig.betweenTransferDelayInNanoSec = 1000000000U / (userConfig.baudRate * 1U);

	/*Initialize SPI*/
#ifdef PHDRIVER_MCXN947_SPI_POLLING
	LPSPI_MasterInit(PHDRIVER_MCXN947_SPI_MASTER, &userConfig, srcFreq);
#else
	LPSPI_MasterInit(PHDRIVER_MCXN947_SPI_MASTER, &userConfig, srcFreq);
    LPSPI_MasterTransferCreateHandle(PHDRIVER_MCXN947_SPI_MASTER, &g_masterHandle, LPSPI_MasterUserCallback, NULL);
#endif
	return PH_DRIVER_SUCCESS;
}

We have to define the phbalReg_Exchange function as well, which is used for communicating via SPI with the PN5190.

Habib_MS_3-1782506250553.png

 Habib_MS_4-1782506278106.png

Spoiler
phStatus_t phbalReg_Exchange(
				void * pDataParams,
				uint16_t wOption,
				uint8_t * pTxBuffer,
				uint16_t wTxLength,
				uint16_t wRxBufSize,
				uint8_t * pRxBuffer,
				uint16_t * pRxLength
				)
{
    phStatus_t status = PH_DRIVER_SUCCESS;
    uint8_t * pRxBuf;
    status_t lpspiStatus;
    lpspi_transfer_t g_masterXfer;
    uint8_t g_dummyBuffer[RX_BUFFER_SIZE_MAX];
    if(pRxBuffer == NULL)
    {
        pRxBuf = g_dummyBuffer;
    }
    else
    {
        pRxBuf = pRxBuffer;
    }
    if(pTxBuffer == NULL)
    {
        wTxLength = wRxBufSize;
        g_dummyBuffer[0] = 0xFF;
        pTxBuffer = g_dummyBuffer;
    }
    memset(&g_masterXfer, 0, sizeof(lpspi_transfer_t));
    /* Set up the transfer */
    g_masterXfer.txData = pTxBuffer;
    g_masterXfer.rxData = pRxBuf;
    g_masterXfer.dataSize = wTxLength;
    g_masterXfer.configFlags = kLPSPI_MasterPcs0 | kLPSPI_MasterPcsContinuous | kLPSPI_MasterByteSwap;
    /* Start transfer */
#ifdef PHDRIVER_MCXN947_SPI_POLLING
    lpspiStatus = LPSPI_MasterTransferBlocking(PHDRIVER_MCXN947_SPI_MASTER, &g_masterXfer);
#else
    lpspiStatus = LPSPI_MasterTransferNonBlocking(PHDRIVER_MCXN947_SPI_MASTER, &g_masterHandle, &g_masterXfer);
    /* Wait transfer complete */
    while (!isTransferCompleted)
    {
    }
#endif
    if (lpspiStatus != kStatus_Success)
    {
        return (PH_DRIVER_FAILURE | PH_COMP_DRIVER);
    }
    if (pRxLength != NULL)
    {
        *pRxLength = wTxLength;
    }
#ifndef PHDRIVER_MCXN947_SPI_POLLING
    SDK_DelayAtLeastUs(300U, BOARD_BOOTCLOCKPLL150M_CORE_CLOCK);
#endif
    return status;
}

Finally, we will define the phbalReg_Mcxn947SpiConfig function, which is called by phbalReg_Init to configure the SPI pins on the MCXN947:

Habib_MS_5-1782506335570.png
Spoiler
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:

Habib_MS_1-1782506665356.png
Spoiler
#include "phDriver.h"
#include "BoardSelection.h"
#include "fsl_device_registers.h"
#include 
#include 
/* ***********************************************************************************************************
* Internal Definitions
* ********************************************************************************************************** */
#define MCXN947_TIMER_MAX_32BIT 0xFFFFFFFFU
#define CTIMER_HANDLER CTIMER0_IRQHandler
/* ***********************************************************************************************************
 * * Type Definitions
*********************************************************************************************************** */
volatile bool ctimerIsrFlag = false;
/* ***********************************************************************************************************
* Global and Static Variables
*
* Match Configuration for CTIMER Channel 0*/
static ctimer_match_config_t matchConfig0;
/* Total Size: NNNbytes
* ********************************************************************************************************** */
/* Array initializer of GPIO peripheral base pointers */
static const GPIO_Type *pGpiosBaseAddr[] = GPIO_BASE_PTRS;

static pphDriver_TimerCallBck_t pCTimerCallBack;
static volatile uint8_t dwTimerExp;

static const gpio_interrupt_config_t aInterruptTypes[] = {kGPIO_InterruptLogicZero, /* Unused. */
        kGPIO_InterruptLogicZero,
        kGPIO_InterruptLogicOne,
        kGPIO_InterruptRisingEdge,
        kGPIO_InterruptFallingEdge,
        kGPIO_InterruptEitherEdge,
};
/* ***********************************************************************************************************
* Private Functions Prototypes
* ********************************************************************************************************** */
static void phDriver_CTimerIsrCallBack(void);

We will define the following functions to initialize and stop the timer, and to enable timer interruptions and its callback:

Habib_MS_2-1782506722983.png
Habib_MS_3-1782506736273.png
Spoiler
phStatus_t phDriver_TimerStart(phDriver_Timer_Unit_t eTimerUnit, uint32_t dwTimePeriod,
pphDriver_TimerCallBck_t pTimerCallBack)
{
	uint64_t qwTimerCnt;
	uint32_t dwTimerFreq;

	dwTimerFreq = PH_DRIVER_SDK_CTIMER_CLK_FREQ;

	qwTimerCnt = dwTimerFreq;
	qwTimerCnt = (qwTimerCnt / eTimerUnit);
	qwTimerCnt = (dwTimePeriod * qwTimerCnt);
	/* 32-bit timers. */
	if(qwTimerCnt > (uint64_t)MCXN947_TIMER_MAX_32BIT)
	{
		return PH_DRIVER_ERROR | PH_COMP_DRIVER;
	}
	if(pTimerCallBack == NULL) /* Timer Start is blocking call. */
	{
		dwTimerExp = 0;
		pCTimerCallBack = phDriver_CTimerIsrCallBack;
	}
	else /* Call the Timer callback. */
	{
		pCTimerCallBack = pTimerCallBack;
	}
	/*Configure & start CTIMER*/
	/*Ctimer config structure*/
	ctimer_config_t config;

	/*Timer mode, init*/
	CTIMER_GetDefaultConfig(&config);
	CTIMER_Init(PH_DRIVER_SDK_CTIMER, &config);
	CTIMER_EnableInterrupts(PH_DRIVER_SDK_CTIMER, kCTIMER_Match0InterruptEnable|kCTIMER_Capture0InterruptEnable);
	/* Configuration match 0 */
	matchConfig0.enableCounterReset = true;
	matchConfig0.enableCounterStop 	= false;
	matchConfig0.matchValue 	 	= (uint32_t)qwTimerCnt;
	matchConfig0.outControl 		= kCTIMER_Output_NoAction;
	matchConfig0.outPinInitState 	= false;
	matchConfig0.enableInterrupt 	= true;

	EnableIRQ(PH_DRIVER_SDK_CTIMER_NVIC);
	NVIC_SetPriority(PH_DRIVER_SDK_CTIMER_NVIC, PH_DRIVER_SDK_CTIMER_PRIORITY);
	/*Setup Match*/
	CTIMER_SetupMatch(PH_DRIVER_SDK_CTIMER, kCTIMER_Match_0, &matchConfig0);
	/*Start*/
	CTIMER_StartTimer(PH_DRIVER_SDK_CTIMER);
while (true)
	{
		/* Check whether an interrupt occurred */
		if (true == ctimerIsrFlag && dwTimerExp)
		{
			/* Clear interrupt flag*/
			ctimerIsrFlag = false;
			break;
		}
	}

	return PH_DRIVER_SUCCESS;
}
Habib_MS_4-1782506821715.png
Spoiler
phStatus_t phDriver_TimerStop(void)
{
	/*Stop timer & disable interrupts*/
	CTIMER_StopTimer(PH_DRIVER_SDK_CTIMER);
	CTIMER_DisableInterrupts(PH_DRIVER_SDK_CTIMER, kCTIMER_Match0InterruptEnable|kCTIMER_Capture0InterruptEnable);

	/* Disable at the NVIC */
	DisableIRQ(PH_DRIVER_SDK_CTIMER_NVIC);

	return PH_DRIVER_SUCCESS;
}

We will also have definitions for the functions that configure and handle GPIOs of the MCXN947 and enable interruptions.

Habib_MS_5-1782506864713.png
Spoiler
phStatus_t phDriver_PinConfig(uint32_t dwPinNumber, phDriver_Pin_Func_t ePinFunc, phDriver_Pin_Config_t *pPinConfig)
{
	gpio_pin_config_t sGpioConfig;
	uint8_t bPinNum;

	if((ePinFunc == PH_DRIVER_PINFUNC_BIDIR) || (pPinConfig == NULL))
	{
		return PH_DRIVER_ERROR | PH_COMP_DRIVER;
	}
	/* Extract the Pin, Gpio, Port details from dwPinNumber */
	bPinNum = (uint8_t)(dwPinNumber & 0xFF);

	sGpioConfig.pinDirection = (ePinFunc == PH_DRIVER_PINFUNC_OUTPUT) ? kGPIO_DigitalOutput:kGPIO_DigitalInput;
	sGpioConfig.outputLogic = pPinConfig->bOutputLogic;

	if(ePinFunc == PH_DRIVER_PINFUNC_INTERRUPT)
	{
		gpio_interrupt_config_t intConfig = aInterruptTypes[(uint8_t)pPinConfig->eInterruptConfig];

		GPIO_GpioClearInterruptFlags((GPIO_Type *)pGpiosBaseAddr[GPIO_PORT], bPinNum);
		GPIO_SetPinInterruptConfig((GPIO_Type *)pGpiosBaseAddr[GPIO_PORT], bPinNum, intConfig);
		EnableIRQ(EINT_IRQn);

		GPIO_PinInit((GPIO_Type *)pGpiosBaseAddr[GPIO_PORT],bPinNum,&sGpioConfig);
	}
	else
	{
		GPIO_PinInit((GPIO_Type *)pGpiosBaseAddr[GPIO_PORT],bPinNum,&sGpioConfig);
	}

	return PH_DRIVER_SUCCESS;
}
Habib_MS_6-1782506901116.png
Spoiler
uint8_t phDriver_PinRead(uint32_t dwPinNumber, phDriver_Pin_Func_t ePinFunc)
{
	uint8_t bValue;
	uint32_t intStatus;
	uint8_t bPinNum;

	/* Extract the Pin, Gpio details from dwPinNumber */
	bPinNum = (uint8_t)(dwPinNumber & 0xFF);

	if(ePinFunc == PH_DRIVER_PINFUNC_INTERRUPT)
	{
		/*Get value of pin interrupt status*/
		intStatus = GPIO_PinGetInterruptFlag((GPIO_Type *)pGpiosBaseAddr[GPIO_PORT], bPinNum);
		bValue = intStatus ? 1:0;
	}
	else
	{
		/*Read pin value*/
		bValue = (uint8_t)GPIO_PinRead((GPIO_Type *)pGpiosBaseAddr[GPIO_PORT], bPinNum);
	}
	return bValue;
}
Habib_MS_7-1782506942143.png
Spoiler
void phDriver_PinWrite(uint32_t dwPinNumber, uint8_t bValue)
{
	uint8_t bPinNum;

	/* Extract the Pin, Gpio details from dwPinNumber */
	bPinNum = (uint8_t)(dwPinNumber & 0xFF);

	GPIO_PinWrite((GPIO_Type *)pGpiosBaseAddr[GPIO_PORT], bPinNum, bValue);
}

void phDriver_PinClearIntStatus(uint32_t dwPinNumber)
{
	uint8_t bPinNum;

	/* Extract the Pin, Gpio details from dwPinNumber */
	bPinNum = (uint8_t)(dwPinNumber & 0xFF);
	/*Clear interrupt flag*/
	GPIO_GpioClearInterruptFlags((GPIO_Type *)pGpiosBaseAddr[GPIO_PORT], (1U << bPinNum));
}

It is also necessary to add functions required for the library to function correctly.

Habib_MS_8-1782506978124.png
Spoiler
void phDriver_EnterCriticalSection(void)
{
    NVIC_DisableIRQ(EINT_IRQn);
}

void phDriver_ExitCriticalSection(void)
{
	NVIC_EnableIRQ(EINT_IRQn);
}

phStatus_t phDriver_IRQPinRead(uint32_t dwPinNumber)
{
	phStatus_t bGpioVal = false;

	bGpioVal = phDriver_PinRead(dwPinNumber, PH_DRIVER_PINFUNC_INPUT);

	return bGpioVal;
}
phStatus_t phDriver_IRQPinPoll(uint32_t dwPinNumber, phDriver_Pin_Func_t ePinFunc, phDriver_Interrupt_Config_t eInterruptType)
{
    uint8_t    bGpioState = 0;

    if ((eInterruptType != PH_DRIVER_INTERRUPT_RISINGEDGE) && (eInterruptType != PH_DRIVER_INTERRUPT_FALLINGEDGE))
    {
        return PH_DRIVER_ERROR | PH_COMP_DRIVER;
    }

    if (eInterruptType == PH_DRIVER_INTERRUPT_FALLINGEDGE)
    {
        bGpioState = 1;
    }

	while(phDriver_PinRead(dwPinNumber, ePinFunc) == bGpioState);

    return PH_DRIVER_SUCCESS;
}

Finally, here, we will have the definition of the timer interrupt handler and ISR callback.

Habib_MS_9-1782507031648.png
Spoiler
void CTIMER0_IRQHandler(void)
{
	/* Clear interrupt flag.*/
	CTIMER_ClearStatusFlags(PH_DRIVER_SDK_CTIMER, kCTIMER_Match0Flag|kCTIMER_Capture0Flag);
	/* Single shot timer. Stop it. */
	CTIMER_StopTimer(PH_DRIVER_SDK_CTIMER);
	CTIMER_DisableInterrupts(PH_DRIVER_SDK_CTIMER, kCTIMER_Match0InterruptEnable|kCTIMER_Capture0InterruptEnable);
	pCTimerCallBack();

	ctimerIsrFlag = true;
}

static void phDriver_CTimerIsrCallBack(void)
{
	dwTimerExp = 1;
}

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:

Habib_MS_10-1782507079841.png
 
Spoiler
#ifdef PHDRIVER_FRDMMCXN947_PN5190_BOARD
#    include 
#endif

ph_NxpBuild_App.h


In this header found at “intfs” folder, we will add our board support to use it with the PN5190 by adding the following change:

Habib_MS_1-1782507715135.png
Spoiler
#if defined(PHDRIVER_LPC1769PN5190_BOARD) \
    || defined(PHDRIVER_K82F_PNEV5190B_BOARD)\
	|| defined(PHDRIVER_FRDMMCXN947_PN5190_BOARD)
#   define NXPBUILD__PHHAL_HW_PN5190
#endif

phApp_Init.h


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.

Habib_MS_2-1782507771262.png
Spoiler
/*Check for MCXN controller based boards*/
#if defined (PHDRIVER_FRDMMCXN947_PN5190_BOARD)
#define PHDRIVER_FRDM_MCXN947
#endif

#ifdef PHDRIVER_FRDM_MCXN947
#include 
#include 
#include 
#include 
#include 
#include 
#endif
Spoiler
#if defined(PHDRIVER_KINETIS_K82)|| defined(PHDRIVER_FRDM_MCXN947)

phApp_Init.c


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.

Habib_MS_3-1782507864930.png
Spoiler
#ifdef PHDRIVER_FRDM_MCXN947
#include "fsl_common.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "board.h"
static void phApp_MCXN947_Init(void){
	BOARD_InitBootPins();
	BOARD_InitBootClocks();
	BOARD_InitDebugConsole();
}
#endif
Spoiler
#elif defined(PHDRIVER_FRDM_MCXN947)
    phApp_MCXN947_Init();

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().

Habib_MS_5-1782507924509.png
Spoiler
#ifdef PH_PLATFORM_HAS_ICFRONTEND
#if !(defined(PH_OSAL_LINUX) && defined(NXPBUILD__PHHAL_HW_PN5190))
    phDriver_Pin_Config_t pinCfg;
    NVIC_SetPriority(EINT_IRQn, EINT_PRIORITY);
    pinCfg.bOutputLogic = PH_DRIVER_SET_LOW;
    pinCfg.bPullSelect = PHDRIVER_PIN_IRQ_PULL_CFG;

    pinCfg.eInterruptConfig = PIN_IRQ_TRIGGER_TYPE;
    phDriver_PinConfig(PHDRIVER_PIN_IRQ, PH_DRIVER_PINFUNC_INTERRUPT, &pinCfg);

#endif

pin_mux.c


Inside the function “BOARD_InitBootPins()” which is defined in pin_mux.c file, the following initializations need to be added, you can find this file in the following path:

{PrjRootDirPath}\frdmmcxn947_Discovery_Loop\frdmmcxn947_cm33_core0\cm33_core0

 
Habib_MS_6-1782507961225.png
Spoiler
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 function to add initializations of the GPIO and UART pins.

Habib_MS_7-1782507998410.png
Habib_MS_8-1782508012260.png
Habib_MS_9-1782508024569.png
Spoiler
void BOARD_InitPins(void)
{
    /* Enables the clock for PORT0 controller: Enables clock */
    CLOCK_EnableClock(kCLOCK_Port0);
    /* Enables the clock for PORT1: Enables clock */
    CLOCK_EnableClock(kCLOCK_Port1);

    const port_pin_config_t port0_19_config = {/* Internal pull-up/down resistor is disabled */
                                                      kPORT_PullDisable,
                                                      /* Low internal pull resistor value is selected. */
                                                      kPORT_LowPullResistor,
                                                      /* Fast slew rate is configured */
                                                      kPORT_FastSlewRate,
                                                      /* Passive input filter is disabled */
                                                      kPORT_PassiveFilterDisable,
                                                      /* Open drain output is disabled */
                                                      kPORT_OpenDrainDisable,
                                                      /* Low drive strength is configured */
                                                      kPORT_LowDriveStrength,
                                                      /* Pin is configured as PIO0_10 */
                                                      kPORT_MuxAlt0,
                                                      /* Digital input enabled */
                                                      kPORT_InputBufferEnable,
                                                      /* Digital input is not inverted */
                                                      kPORT_InputNormal,
                                                      /* Pin Control Register fields [15:0] are not locked */
                                                      kPORT_UnlockRegister};
    /* PORT0_10 (pin B12) is configured as PIO0_10 */
    PORT_SetPinConfig(PORT0, 19U, &port0_19_config);

    const port_pin_config_t port1_0_config = {
                                                      kPORT_PullDisable,
                                                      kPORT_LowPullResistor,
                                                      kPORT_FastSlewRate,
                                                      kPORT_PassiveFilterDisable,
                                                      kPORT_OpenDrainDisable,
                                                      kPORT_LowDriveStrength,
                                                      /* Pin is configured as PIO0_10 */
                                                      kPORT_MuxAlt0,
                                                      kPORT_InputBufferEnable,
                                                      kPORT_InputNormal,
                                                      kPORT_UnlockRegister};
    /* PORT0_10 (pin B12) is configured as PIO0_10 */
    PORT_SetPinConfig(PORT1, 0U, &port1_0_config);
    const port_pin_config_t port1_1_config = {
                                                      kPORT_PullDisable,
                                                      kPORT_LowPullResistor,
                                                      kPORT_FastSlewRate,
                                                      kPORT_PassiveFilterDisable,
                                                      kPORT_OpenDrainDisable,
                                                      kPORT_LowDriveStrength,
                                                      /* Pin is configured as PIO0_10 */
                                                      kPORT_MuxAlt0,
                                                      kPORT_InputBufferEnable,
                                                      kPORT_InputNormal,
                                                      kPORT_UnlockRegister};
    /* PORT0_10 (pin B12) is configured as PIO0_10 */
    PORT_SetPinConfig(PORT1, 1U, &port1_1_config);
    const port_pin_config_t port0_31_pinB12_config = {
                                                      kPORT_PullDown,
                                                      kPORT_LowPullResistor,
                                                      kPORT_FastSlewRate,
                                                      kPORT_PassiveFilterDisable,
                                                      kPORT_OpenDrainDisable,
                                                      kPORT_LowDriveStrength,
                                                      /* Pin is configured as PIO0_10 */
                                                      kPORT_MuxAlt0,
                                                      kPORT_InputBufferEnable,
                                                      kPORT_InputNormal,
                                                      kPORT_UnlockRegister};
    /* PORT0_10 (pin B12) is configured as PIO0_10 */
    PORT_SetPinConfig(PORT0, 31U, &port0_31_pinB12_config);

    const port_pin_config_t port0_28_config = {
                                                     kPORT_PullDisable,
                                                     kPORT_LowPullResistor,
                                                     kPORT_FastSlewRate,
                                                     kPORT_PassiveFilterDisable,
                                                     kPORT_OpenDrainDisable,
                                                     kPORT_LowDriveStrength,
                                                     /* Pin is configured as PIO0_6 */
                                                     kPORT_MuxAlt0,
                                                     kPORT_InputBufferEnable,
                                                     kPORT_InputNormal,
                                                     kPORT_UnlockRegister};
    /* PORT0_6 (pin C14) is configured as PIO0_6 */
    PORT_SetPinConfig(PORT0, 28U, &port0_28_config);

    const port_pin_config_t port0_2_pinB16_config = {
                                                     .pullSelect = kPORT_PullDisable,
                                                     .pullValueSelect = kPORT_LowPullResistor,
                                                     .slewRate = kPORT_FastSlewRate,
                                                     .passiveFilterEnable = kPORT_PassiveFilterDisable,
                                                     .openDrainEnable = kPORT_OpenDrainDisable,
                                                     .driveStrength = kPORT_HighDriveStrength,
                                                     /* Pin is configured as SWO */
                                                     .mux = kPORT_MuxAlt1,
                                                     .inputBuffer = kPORT_InputBufferEnable,
                                                     .invertInput = kPORT_InputNormal,
                                                     .lockRegister = kPORT_UnlockRegister};
    /* PORT0_2 (pin B16) is configured as SWO */
    PORT_SetPinConfig(PORT0, 2U, &port0_2_pinB16_config);

    const port_pin_config_t port1_8_pinA1_config = {
                                                    .pullSelect = kPORT_PullUp,
                                                    .pullValueSelect = kPORT_LowPullResistor,
                                                    .slewRate = kPORT_FastSlewRate,
                                                    .passiveFilterEnable = kPORT_PassiveFilterDisable,
                                                    .openDrainEnable = kPORT_OpenDrainDisable,
                                                    .driveStrength = kPORT_LowDriveStrength,
                                                    /* Pin is configured as FC4_P0 */
                                                    .mux = kPORT_MuxAlt2,
                                                    .inputBuffer = kPORT_InputBufferEnable,
                                                    .invertInput = kPORT_InputNormal,
                                                    .lockRegister = kPORT_UnlockRegister};
    /* PORT1_8 (pin A1) is configured as FC4_P0 */
    PORT_SetPinConfig(PORT1, 8U, &port1_8_pinA1_config);
   const port_pin_config_t port1_9_pinB1_config = {
                                                   .pullSelect = kPORT_PullDisable,
                                                    .pullValueSelect = kPORT_LowPullResistor,
                                                    .slewRate = kPORT_FastSlewRate,
                                                    .passiveFilterEnable = kPORT_PassiveFilterDisable,
                                                    .openDrainEnable = kPORT_OpenDrainDisable,
                                                    .driveStrength = kPORT_LowDriveStrength,
                                                    /* Pin is configured as FC4_P1 */
                                                    .mux = kPORT_MuxAlt2,
                                                    .inputBuffer = kPORT_InputBufferEnable,
                                                    .invertInput = kPORT_InputNormal,
                                                    .lockRegister = kPORT_UnlockRegister};
    /* PORT1_9 (pin B1) is configured as FC4_P1 */
    PORT_SetPinConfig(PORT1, 9U, &port1_9_pinB1_config);
}

At the same time, add the following includes to the file:

Habib_MS_0-1782508183634.png
Spoiler
#include "fsl_common.h"
#include "fsl_port.h"
#include "board.h"
#include "clock_config.h"
#include "pin_mux.h"

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.

Although these files have been deleted, they are still referenced in the CMakeLists.txt file. Please remove those includes from this file.

Add all header files in CMake_List.txt


As mentioned previously, the CMake_List.txt is automatically updated when you copy a .c file. However, .h files are not automatically linked, so they must be added manually. Please copy and paste the following includes into the CMakeLists.txt file:

Habib_MS_0-1782508446885.png
Spoiler
mcux_add_include(
    BASE_PATH ${CMAKE_CURRENT_LIST_DIR}
    INCLUDES 
            NxpNfcRdLib/intfs
            NxpNfcRdLib/types
			NxpNfcRdLib/comps/phacDiscLoop/src/Sw
			intfs
			DAL/boards
			DAL/cfg
			DAL/inc
			phOsal/inc
			. 
    )

Add _DSB and _ISB support


As final modification step, please include in {PrjRootDirPath}\NxpNfcRdLib\comps\phhalHw\src\Pn5190\phhalHw_Pn5190_Int.c the “cmsis_gcc.h” to support of _DSB and _ISB functions.

Habib_MS_2-1782508515584.png

Testing Final Project with FreeRTOS


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_3-1782508554465.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_4-1782508585568.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_5-1782508604979.png

Changing OS preprocessor macro


This section presents the steps to follow to add the possibility of easily choosing whether to have OS support or not.  This guide is based as default with FREERTOS, but the NFC reader library offers the possibility to run without OS, firstly, we need to change the preprocessor macro PH_OSAL_FREERTOS to PH_OSAL_NULLOS in the CMakeList.txt, as shown the following image:

Habib_MS_6-1782508642319.png

Finally, 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, to achieve this we need to add a replacement of the file port.c since the included FreeRTOS is shared with all projects of the repository, and if we modify this file, it will be modified in all projects.

1. Go to the explorer window, right-click on the project and click on “New File…”.

Habib_MS_7-1782508678537.png

2. Write the file’s name as follows (port.c) and click enter:

Habib_MS_8-1782508703600.png
3. Add this file into the CMakeList.txt file to include port.c into the compilation process:
Habib_MS_9-1782508775980.png
Spoiler
mcux_add_source(BASE_PATH ${CMAKE_CURRENT_LIST_DIR}
    SOURCES "port.c")

4. Please copy and paste all the content form of the port.c located on the following path to the port.c we created:

{PrjRootDirPath}\mcuxsdk\mcuxsdk\rtos\freertos\freertos-kernel\portable\GCC\ARM_CM33_NTZ\non_secure

Habib_MS_10-1782508828714.png

5. Replace the SysTick_Handler() of the port.c we created to the following function:

Habib_MS_11-1782508854714.png
Spoiler
#ifndef PH_OSAL_NULLOS
void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */
{
    uint32_t ulPreviousMask;

    ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
    traceISR_ENTER();
    {
        /* Increment the RTOS tick. */
        if( xTaskIncrementTick() != pdFALSE )
        {
            traceISR_EXIT_TO_SCHEDULER();
            /* Pend a context switch. */
            portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
        }
        else
        {
            traceISR_EXIT();
        }
    }
    portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask );
}
#endif

6. Finally, we will ignore the port.c of the FreeRTOS folder, please add the following code to the CMakeList.txt:

Habib_MS_12-1782508890989.png
Spoiler
mcux_project_remove_source(
    BASE_PATH ${SdkRootDirPath}/rtos/freertos/freertos-kernel/portable/GCC/ARM_CM33_NTZ/non_secure
    SOURCES port.c
)
Please rebuild and test as the steps mentioned in the section Testing Final Project with FreeRTOS.
NFC Reader Library
タグ(1)
評価なし
バージョン履歴
最終更新日:
7 時間前
更新者: