NFC知识库

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

NFC Knowledge Base

讨论

排序依据:
Introduction Many customers are using PN7220 + Android 16 recently. In this document, I will show you how to porting the PN7220 to Android 16. I use the i.MX95 FRDM board as a reference target board.   NOTE :  All the modifications are just for reference. They are NOT a NXP official patches for the newer release of AOSP porting. So the modifications may not be the best solution. Customer please base on their needs to modify the AOSP source code. This is not for production. Customer still need to perform full testing after the porting.    Hardware boards: i.MX95 FRDM Board (FRDM i.MX 95 Development Board | NXP Semiconductors) FRDM-IMX95-TOP.jpg   PN7220 EVK -- PNEV7220BP1 (PNEV7220BP1 Development Board for PN7220 NFC Controller | NXP Semiconductors) PNEV7220BP1-TOP-IMG.jpg   There is a 40pins connector on both PN7220 EVK and i.MX95 FRDM board. So PN7220 + i.MX95 FRDM connecting together is like this: pn7220_imx95FRDM.jpg   Build the Android BSP for i.MX95 FRDM board: The i.MX Android BSP that I used is Android 16.0.0_1.4.0 (L6.12.49_2.2.0 BSP). It could be downloaded from here: Android OS for i.MX Applications Processors | NXP Semiconductors   1. Download the "Documentation" and the "Install Source Package".  2. Follow the steps in Android User's Guide to build the Android BSP for "evk_95" first.  $ export MY_ANDROID=`pwd` $ source build/envsetup.sh $ lunch evk_95-nxp_stable-userdebug $ export TARGET_RELEASE=nxp_stable $ build_build_var_cache $ ./imx-make.sh -j4 2>&1 | tee build-log.txt   According to the android_build/.repo/manifests/aosp-android-16.0.0_1.4.0.xml, you will see the AOSP version is android-16.0.0_r4. According to the PN7220 Android 16 porting guide (PN7160/PN7220 – Android 16 porting guide), the patches is for AOSP release android-16.0.0_r2. So fortunately, the AOSP release version between them is not big different.    Now, we start the porting: 1. Kernel Driver To establish connection with the PN7220, the Android stack uses the nxpnfc kernel driver.  You could download the driver from github below: nfcandroid_platform_drivers/drivers at br_ar_16_comm_infra_dev · nxp-nfc-infra/nfcandroid_platform_drivers · GitHub   The command is : git clone "https://github.com/nxp-nfc-infra/nfcandroid_platform_drivers.git" -b br_ar_16_comm_infra_dev There is driver for Kernel 6.6 and 6.12. So, please download the correct one for your porting. For example, the kernel in i.MX Android BSP Android 16.0.0_1.4.0 is 6.12. So I will use the 6.12 driver for my porting.   In your porting, make sure the PATH in Makefile and Kconfig files are setting properly.  For example in my porting: android_build/vendor/nxp-opensource/kernel_imx/drivers/nfc/pn7220$ tree . ├── common.c ├── common.h ├── i2c_drv.c ├── i2c_drv.h ├── Kbuild ├── Kconfig └── Makefile 0 directories, 7 files   For simplifying everything, we will only add a support for I2C and not SPI. Replace drivers/nfc/pn7220/Makefile default code with following code (for easier understanding) nxpnfc-i2c-objs = i2c_drv.o common.o obj-$(CONFIG_NXP_NFC_I2C) += nxpnfc_i2c.o   The contents of drivers/nfc/Makefile. Add the PN7220 like below: # SPDX-License-Identifier: GPL-2.0 # # Makefile for nfc devices # obj-$(CONFIG_NXP_NFC_I2C) += pn7220/ obj-$(CONFIG_NFC_FDP) += fdp/ obj-$(CONFIG_NFC_PN544) += pn544/ obj-$(CONFIG_NFC_MICROREAD) += microread/ obj-$(CONFIG_NFC_PN533) += pn533/ obj-$(CONFIG_NFC_MEI_PHY) += mei_phy.o obj-$(CONFIG_NFC_SIM) += nfcsim.o obj-$(CONFIG_NFC_PORT100) += port100.o obj-$(CONFIG_NFC_MRVL) += nfcmrvl/ obj-$(CONFIG_NFC_TRF7970A) += trf7970a.o obj-$(CONFIG_NFC_ST21NFCA) += st21nfca/ obj-$(CONFIG_NFC_ST_NCI) += st-nci/ obj-$(CONFIG_NFC_NXP_NCI) += nxp-nci/ obj-$(CONFIG_NFC_S3FWRN5) += s3fwrn5/ obj-$(CONFIG_NFC_ST95HF) += st95hf/ obj-$(CONFIG_NFC_VIRTUAL_NCI) += virtual_ncidev.o   The contents of drivers/nfc/Kconfig. Add the PN7220 like below: source "drivers/nfc/microread/Kconfig" source "drivers/nfc/nfcmrvl/Kconfig" source "drivers/nfc/st21nfca/Kconfig" source "drivers/nfc/st-nci/Kconfig" source "drivers/nfc/nxp-nci/Kconfig" source "drivers/nfc/s3fwrn5/Kconfig" source "drivers/nfc/st95hf/Kconfig" source "drivers/nfc/pn7220/Kconfig" endmenu   2. Adding the "nxpnfc" to the i.MX95 FRDM board device tree file android_build/vendor/nxp-opensource/kernel_imx/arch/arm64/boot/dts/freescale/imx95-15x15-frdm.dts   We need to check the connection between two boards and then to decide which pins to use in the device tree file. Here is the 40 pins connector on the PN7220: PN7220EVK_40pinsConnector.jpg Here is the 40 pins connector on the i.MX95 FRDM board. FRDM-imx95-40pinsConnector.png FRDM-imx95-40pinsConnector_left.png FRDM-imx95-40pinsConnector_right.png According to the 40 pins connection between PN7220 EVK and the i.MX95 FRDM board, I decided to use the I2C6 and the GPIO2_20, GPIO2_21 and GPIO2_26. So, in the imx95-15x15-frdm.dts, I added: &lpi2c6 { clock-frequency = <400000>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_lpi2c6>; status = "okay"; nxpnfc@28{ compatible = "nxp,nxpnfc"; reg = <0x28>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_nfc>; nxp,nxpnfc-irq = <&gpio2 26 0>; nxp,nxpnfc-ven = <&gpio2 21 0>; nxp,nxpnfc-mode_sw = <&gpio2 20 0>; }; }; And the IOMUX settings in the imx95-15x15-frdm.dts. pinctrl_nfc: nfcgrp { fsl,pins = < IMX95_PAD_GPIO_IO26__GPIO2_IO_BIT26 0x39e // IRQ IMX95_PAD_GPIO_IO21__GPIO2_IO_BIT21 0x39e // VEN IMX95_PAD_GPIO_IO20__GPIO2_IO_BIT20 0x39e // MODE_SW >; }; pinctrl_lpi2c6: lpi2c6grp { fsl,pins = < IMX95_PAD_GPIO_IO02__LPI2C6_SDA 0x40000b9e IMX95_PAD_GPIO_IO03__LPI2C6_SCL 0x40000b9e >; };   3. Modify the imx95_gki.fragment File:  android_build/vendor/nxp-opensource/kernel_imx/arch/arm64/configs/imx95_gki.fragment Add the "CONFIG_NXP_NFC_I2C=m" into the imx95_gki.fragment   4. Add the settings in your corresponding board configuration files in Android - Go to the android_build/device/nxp/imx9/evk_95/  - Modify the BoardConfig.mk. # Add KVM support BOARD_BOOTCONFIG += androidboot.hypervisor.vm.supported=true + # ---- selinux permissive ---- + BOARD_KERNEL_CMDLINE += androidboot.selinux=permissive # -------@block_sepolicy------- BOARD_SEPOLICY_DIRS := \ $(CONFIG_REPO_PATH)/imx9/sepolicy \ $(IMX_DEVICE_PATH)/sepolicy \ + vendor/nxp/nfc/sepolicy \ + vendor/nxp/nfc/sepolicy/nfc \ + vendor/nxp/emvco/sepolicy +include vendor/nxp/nfc/BoardConfigNfc.mk    - Add the "nxpnfc_i2c.ko" to the ShareBoardConfig.mk. Make sure the path and the filename are correct. ifeq ($(LOADABLE_KERNEL_MODULE),true) IMX_ANDROID_FIRST_STAGE_MODULES += \ $(KERNEL_OUT)/drivers/hwmon/hwmon.ko \ $(KERNEL_OUT)/drivers/hwmon/scmi-hwmon.ko \ .... .... .... $(KERNEL_OUT)/drivers/soc/imx/soc-imx9.ko \ $(KERNEL_OUT)/drivers/gpio/gpio-adp5585.ko \ $(KERNEL_OUT)/drivers/gpio/gpio-pca953x.ko \ $(KERNEL_OUT)/drivers/gpio/gpio-vf610.ko \ + $(KERNEL_OUT)/drivers/nfc/pn7220/nxpnfc_i2c.ko .... .... BOARD_VENDOR_KERNEL_MODULES += \ $(KERNEL_OUT)/drivers/media/i2c/ap1302.ko \ $(KERNEL_OUT)/drivers/media/i2c/ox03c10.ko \ $(KERNEL_OUT)/drivers/media/i2c/max96717_lib.ko \ .... .... $(KERNEL_OUT)/drivers/net/ethernet/freescale/enetc/fsl-enetc-vf.ko \ $(KERNEL_OUT)/drivers/net/ethernet/freescale/enetc/fsl-enetc4.ko \ $(KERNEL_OUT)/drivers/net/phy/realtek.ko \ $(KERNEL_OUT)/drivers/hwmon/pwm-fan.ko \ + $(KERNEL_OUT)/drivers/nfc/pn7220/nxpnfc_i2c.ko   - Add the INxpNfc and INxpEmvco to the device_framework_matrix.xml <compatibility-matrix version="1.0" type="framework"> <hal format="aidl" optional="true"> <name>nxp.hardware.secureime</name> <version>1</version> <interface> <name>ISecureIME</name> <instance>default</instance> </interface> </hal> <hal format="aidl" optional="true"> <name>nxp.hardware.ele</name> <version>1</version> <interface> <name>ISecureEnclave</name> <instance>default</instance> </interface> </hal> <hal format="aidl" optional="true"> <name>nxp.hardware.imx_dek_extractor</name> <version>1</version> <interface> <name>IDek_Extractor</name> <instance>default</instance> </interface> </hal> <hal format="aidl" optional="true"> <name>vendor.nxp.nxpnfc_aidl</name> <version>2</version> <interface> <name>INxpNfc</name> <instance>default</instance> </interface> </hal> <hal format="aidl" optional="true"> <name>vendor.nxp.emvco</name> <version>1</version> <interface> <name>INxpEmvco</name> <instance>default</instance> </interface> </hal> </compatibility-matrix>    - Add the following to the evk_95.mk # ------nfc------- $(call inherit-product, vendor/nxp/nfc/device-nfc.mk) $(call inherit-product, vendor/nxp/emvco/device-emvco.mk) PRODUCT_PACKAGES += \ android.hardware.nfc2-service.nxp PRODUCT_PACKAGES += \ com.nxp.emvco \ com.nxp.nfc \ nfc_nci_nxp_pn72xx   - Add the nxpnfc_i2c in init.rc exec u:r:vendor_modprobe:s0 -- /vendor/bin/modprobe -a -d \ /vendor/lib/modules nxpnfc_i2c write /sys/power/wake_lock nosleep   - Add nxpnfc to ueventd.nxp.rc /dev/ttymxc1 0666 nfc nfc /dev/ttymxc2 0666 nfc nfc /dev/nxpnfc 0666 nfc nfc   5. Apply the NXP AOSP patches I write a script to download the patches from the github. The script file and the android_build folder is on the same directory. Run the AOSP_adaptation.sh.  AOSP_adaptation.sh # nfcandroid_nfc_modules git clone "https://github.com/nxp-nfc-infra/nfcandroid_modules_nfc.git" cd nfcandroid_modules_nfc git checkout br_ar_16_comm_infra_dev cp -rf * ../android_build/packages/modules/Nfc cd .. # nfcandroid_nfc_hidlimpl git clone "https://github.com/nxp-nfc-infra/nfcandroid_nfc_hidlimpl.git" cd nfcandroid_nfc_hidlimpl git checkout br_ar_16_comm_infra_dev cp -rf * ../android_build/hardware/nxp/nfc cd .. # nfcandroid_frameworks git clone "https://github.com/nxp-nfc-infra/nfcandroid_frameworks.git" cd nfcandroid_frameworks git checkout br_ar_16_comm_infra_dev mkdir ../android_build/packages/modules/Nfc/framework cp -rf * ../android_build/packages/modules/Nfc/framework cd .. # nfcandroid_emvco_aidlimpl git clone "https://github.com/nxp-nfc-infra/nfcandroid_emvco_aidlimpl.git" cd nfcandroid_emvco_aidlimpl git checkout br_ar_16_comm_infra_dev mkdir ../android_build/hardware/nxp/emvco cp -rf * ../android_build/hardware/nxp/emvco cd .. # nfcandroid_platform_reference git clone "https://github.com/nxp-nfc-infra/nfcandroid_platform_reference.git" cd nfcandroid_platform_reference git checkout br_ar_16_comm_infra_dev cp -rf vendor/nxp/* ../android_build/vendor/nxp/ cd ..   Apply a patch. $ cd android_build/system/logging $ patch -p1 < ../../../nfcandroid_platform_reference/build_cfg/build_pf_patches/AROOT_system_logging.patch   Add TDA Test support: # Clone repositories for test applications and TDA support # nfcandroid_infra_test_apps git clone https://github.com/nxp-nfc-infra/nfcandroid_infra_test_apps.git cd nfcandroid_infra_test_apps/ git checkout br_ar_16_comm_infra_dev cd test_apps/ cp -rf SMCU_Switch/ ../../android_build/packages/apps/ cp -rf EMVCoModeSwitchApp/ ../../android_build/packages/apps/ cd ../.. # nfcandroid_infra_comm_libs git clone "https://github.com/nxp-nfc-infra/nfcandroid_infra_comm_libs.git" cd nfcandroid_infra_comm_libs git checkout br_ar_16_comm_infra_dev cp -rf nfc_tda/ ../android_build/packages/modules/Nfc/libnfc-nci/ cp -rf emvco_tda/ emvco_tda_test/ ../android_build/hardware/nxp/emvco/ cp -rf NfcTdaTestApp/ ../android_build/packages/apps/ cd ..   6. Put changes into hardwatre/interfaces/compatibility_matrices  File: hardware/interfaces/compatibility_matrices/compatibility_matrix.202504.xml <hal format="aidl"> <name>android.hardware.audio.effect</name> <version>1-3</version> <interface> <name>IFactory</name> <instance>default</instance> </interface> </hal> <hal format="aidl" optional="true"> <name>nxp.hardware.imx_dek_extractor</name> <version>1</version> <interface> <name>IDek_Extractor</name> <instance>default</instance> </interface> </hal> <hal format="aidl" optional="true"> <name>nxp.hardware.ele</name> <version>1</version> <interface> <name>ISecureEnclave</name> <instance>default</instance> </interface> </hal> <hal format="aidl" optional="true"> <name>vendor.nxp.nxpnfc_aidl</name> <version>2</version> <interface> <name>INxpNfc</name> <instance>default</instance> </interface> </hal> <hal format="aidl" optional="true"> <name>vendor.nxp.emvco</name> <version>1</version> <interface> <name>INxpEmvco</name> <instance>default</instance> </interface> </hal> <hal format="aidl" updatable-via-apex="true"> <name>android.hardware.authsecret</name> <version>1</version> <interface> <name>IAuthSecret</name> <instance>default</instance> </interface> </hal>   7. Add the firmware $ git clone https://github.com/NXP/nfc-NXPNFCC_FW.git $ cp -r nfc-NXPNFCC_FW/InfraFW/pn7220/64-bit-2.5/pn7220_64bits.so android_build/vendor/nxp/pn7220/firmware/lib64/libpn72xx_fw.so   8. Add the NXPAndroidDTA $git clone https://github.com/NXPNFCProject/NXPAndroidDTA.git $cd NXPAndroidDTA $git checkout br_ar_new_dta_arch cp -r NXPAndroidDTA android_build/vendor/nxp/   9. Some fixes before build: $ cd android_build $ mv hardware/nxp/nfc/snxxx/Android.bp hardware/nxp/nfc/snxxx/_Android.bp $ mv hardware/nxp/nfc/snxxx/halimpl/power-tracker/Android.bp hardware/nxp/nfc/snxxx/halimpl/power-tracker/_Android.bp $ mv hardware/nxp/secure_element/snxxx/aidl/Android.bp hardware/nxp/secure_element/snxxx/aidl/_Android.bp $ cd hardware/nxp/nfc $ rm pn8x -rf   Now, build the Android BSP again. Use "mm" to build the Android source code. After fixed all the errors of the AOSP build, use "imx-make.sh" to build the whole i.MX Android image.    When building the Android, there may have some errors during the build. I listed some errors and the workaround below for your reference.   Error: error: packages/modules/Nfc/tests/cts/tests/Android.bp:20:1: "CtsNfcTestCases" depends on undefined module "CtsAppTestStubsShared". Workaround : Comment out "CtsAppTestStubsShared" in packages/modules/Nfc/tests/cts/tests/Android.bp     Error: error: hardware/nxp/nfc/snxxx/halimpl_v2/power-tracker/Android.bp:17:1: "power_tracker_v2" depends on undefined module "nfc_nci_nxp_snxxx_headers_v2". Workaround: mv hardware/nxp/nfc/snxxx/halimpl_v2/power-tracker/Android.bp hardware/nxp/nfc/snxxx/halimpl_v2/power-tracker/_Android.bp     Error: error: platform_testing/Android.bp:255:1: module "continuous_native_tests" variant "android_common": depends on //packages/modules/Nfc/NfcNci/nci/jni:libnfc-nci-jni-tests which is not visible to this module You may need to add "//platform_testing" to its visibility error: platform_testing/Android.bp:255:1: module "continuous_native_tests" variant "android_common": depends on //packages/modules/Nfc/libnfc-nci/tests:libnfc-nci-tests which is not visible to this module You may need to add "//platform_testing" to its visibility Workaround: nano packages/modules/Nfc/NfcNci/nci/jni/Android.bp In cc_test {     name: "libnfc-nci-jni-tests", .. ..     visibility: [         "//platform_testing:__subpackages__",     ], Same in packages/modules/Nfc/libnfc-nci/tests/Android.bp     Error: FAILED: out/soong/.intermediates/packages/modules/Nfc/framework/framework-nfc.stubs.source.system/android_common/exportable/framework-nfc.stubs.source.system-stubs.srcjar out/soong/.intermediates/packages/modules/Nfc/framework/framework-nfc.stubs.source.system/android_common/exportable/framework-nfc.stubs.source.system_annotations.zip out/soong/.intermediates/packages/modules/Nfc/framework/framework-nfc.stubs.source.system/android_common/exportable/framework-nfc.stubs.source.system_api.txt out/soong/.intermediates/packages/modules/Nfc/framework/framework-nfc.stubs.source.system/android_common/exportable/framework-nfc.stubs.source.system_removed.txt out/soong/.intermediates/prebuilts/sdk/framework-nfc.api.system.latest/gen/framework-nfc.api.system.latest:52: error: Binary breaking change: Removed method android.nfc.NfcOemExtension.emulateNfcTechnologyATag(boolean,byte,byte,byte,byte[],byte,byte[]) [RemovedMethod] out/soong/.intermediates/prebuilts/sdk/framework-nfc.api.system.latest/gen/framework-nfc.api.system.latest:64: error: Binary breaking change: Removed method android.nfc.NfcOemExtension.overwriteRoutingTable(int,int,int,int,int) [RemovedMethod] out/soong/.intermediates/prebuilts/sdk/framework-nfc.api.system.latest/gen/framework-nfc.api.system.latest:77: error: Binary breaking change: Removed field android.nfc.NfcOemExtension.EMULATE_NFC_A_TAG_STATUS_FAILED_INTERNAL [RemovedField] out/soong/.intermediates/prebuilts/sdk/framework-nfc.api.system.latest/gen/framework-nfc.api.system.latest:78: error: Binary breaking change: Removed field android.nfc.NfcOemExtension.EMULATE_NFC_A_TAG_STATUS_FAILED_NFC_NOT_ENABLED [RemovedField] out/soong/.intermediates/prebuilts/sdk/framework-nfc.api.system.latest/gen/framework-nfc.api.system.latest:79: error: Binary breaking change: Removed field android.nfc.NfcOemExtension.EMULATE_NFC_A_TAG_STATUS_OK [RemovedField] out/soong/.intermediates/prebuilts/sdk/framework-nfc.api.system.latest/gen/framework-nfc.api.system.latest:120: error: Binary breaking change: Removed method android.nfc.NfcOemExtension.Callback.onRoutingChangeCompleted() [RemovedMethod] out/soong/.intermediates/prebuilts/sdk/framework-nfc.api.system.latest/gen/framework-nfc.api.system.latest:160: error: Binary breaking change: Removed method android.nfc.RoutingStatus.getDefaultFelicaRoute() [RemovedMethod] Aborting: Found compatibility problems checking the public API (/home/nxa08017/android16_1.4.0/android_build/out/soong/.temp/sbox/d1717a17fe92a8b2da806db0f1cb87830019487b/packages/modules/Nfc/framework/java) against the API in /home/nxa08017/android16_1.4.0/android_build/out/soong/.temp/sbox/d1717a17fe92a8b2da806db0f1cb87830019487b/./out/soong/.intermediates/prebuilts/sdk/framework-nfc.api.public.latest/gen/framework-nfc.api.public.latest exit status 255 Workaround: Comment out the lines 52,64,77,78,79,120,160 in out/soong/.intermediates/prebuilts/sdk/framework-nfc.api.system.latest/gen/framework-nfc.api.system.latest     Error: out/soong/.intermediates/prebuilts/sdk/framework-nfc.api.public.latest/gen/framework-nfc.api.public.latest:77: error: Binary breaking change: Removed method android.nfc.NfcAdapter.isExitFramesSupported() [RemovedMethod] out/soong/.intermediates/prebuilts/sdk/framework-nfc.api.public.latest/gen/framework-nfc.api.public.latest:80: error: Binary breaking change: Removed method android.nfc.NfcAdapter.isPowerSavingModeEnabled() [RemovedMethod] out/soong/.intermediates/prebuilts/sdk/framework-nfc.api.public.latest/gen/framework-nfc.api.public.latest:81: error: Binary breaking change: Removed method android.nfc.NfcAdapter.isPowerSavingModeSupported() [RemovedMethod] out/soong/.intermediates/prebuilts/sdk/framework-nfc.api.public.latest/gen/framework-nfc.api.public.latest:91: error: Binary breaking change: Removed method android.nfc.NfcAdapter.setPowerSavingMode(boolean) [RemovedMethod] out/soong/.intermediates/prebuilts/sdk/framework-nfc.api.public.latest/gen/framework-nfc.api.public.latest:196: error: Binary breaking change: Removed method android.nfc.cardemulation.CardEmulation.getPollingLoopFiltersForService(android.content.ComponentName) [RemovedMethod] out/soong/.intermediates/prebuilts/sdk/framework-nfc.api.public.latest/gen/framework-nfc.api.public.latest:197: error: Binary breaking change: Removed method android.nfc.cardemulation.CardEmulation.getPollingLoopPatternFiltersForService(android.content.ComponentName) [RemovedMethod] out/soong/.intermediates/prebuilts/sdk/framework-nfc.api.public.latest/gen/framework-nfc.api.public.latest:202: error: Binary breaking change: Removed method android.nfc.cardemulation.CardEmulation.isDeviceScreenOnRequiredForService(android.content.ComponentName) [RemovedMethod] out/soong/.intermediates/prebuilts/sdk/framework-nfc.api.public.latest/gen/framework-nfc.api.public.latest:203: error: Binary breaking change: Removed method android.nfc.cardemulation.CardEmulation.isDeviceUnlockRequiredForService(android.content.ComponentName) [RemovedMethod] out/soong/.intermediates/prebuilts/sdk/framework-nfc.api.public.latest/gen/framework-nfc.api.public.latest:214: error: Binary breaking change: Removed method android.nfc.cardemulation.CardEmulation.setRequireDeviceScreenOnForService(android.content.ComponentName,boolean) [RemovedMethod] out/soong/.intermediates/prebuilts/sdk/framework-nfc.api.public.latest/gen/framework-nfc.api.public.latest:215: error: Binary breaking change: Removed method android.nfc.cardemulation.CardEmulation.setRequireDeviceUnlockForService(android.content.ComponentName,boolean) [RemovedMethod] out/soong/.intermediates/prebuilts/sdk/framework-nfc.api.public.latest/gen/framework-nfc.api.public.latest:248: error: Binary breaking change: Removed method android.nfc.cardemulation.CardEmulation.NfcEventCallback.onOffHostAidSelected(String,String) [RemovedMethod] Aborting: Found compatibility problems checking the public API (/home/nxa08017/android16_1.4.0/android_build/out/soong/.temp/sbox/6245059c063e0ae76fa4356a9b840b923ddb8764/packages/modules/Nfc/framework/java) against the API in /home/nxa08017/android16_1.4.0/android_build/out/soong/.temp/sbox/6245059c063e0ae76fa4356a9b840b923ddb8764/./out/soong/.intermediates/prebuilts/sdk/framework-nfc.api.public.latest/gen/framework-nfc.api.public.latest exit status 255 Workaround: Same as the previous workaround. Comment out the lines (line number shown in error) in out/soong/.intermediates/prebuilts/sdk/framework-nfc.api.public.latest/gen/framework-nfc.api.public.latest.     Error: FAILED: out/soong/.intermediates/system/sepolicy/vendor_sepolicy.cil.raw/android_common/evk_95/vendor_sepolicy.cil.raw out/host/linux-x86/bin/checkpolicy -C -M -L -c 30 -o out/soong/.intermediates/system/sepolicy/vendor_sepolicy.cil.raw/android_common/evk_95/vendor_sepolicy.cil.raw out/soong/.intermediates/system/sepolicy/vendor_sepolicy.conf/android_common/evk_95/vendor_sepolicy.conf && out/host/linux-x86/bin/build_sepolicy filter_out -f out/soong/.intermediates/system/sepolicy/reqd_policy_mask.cil/android_common/reqd_policy_mask.cil -t out/soong/.intermediates/system/sepolicy/vendor_sepolicy.cil.raw/android_common/evk_95/vendor_sepolicy.cil.raw # hash of input list: 7a5f97fdfa590e2ec5a2c6b745c65293680d0202c9b5869c1425905c209b9bf1 vendor/nxp/emvco/sepolicy/service.te:1:ERROR 'Duplicate declaration of type' at token ';' on line 21764: type hal_emvco_service, hal_service_type, service_manager_type; #line 1 "vendor/nxp/emvco/sepolicy/service.te" checkpolicy:  error(s) encountered while parsing configuration 11:50:27 ninja failed with: exit status 1 Workaround: nano vendor/nxp/emvco/sepolicy/hwservice.te Change the hal_emvco_service to hal_emvco_hwservice like this: type hal_emvco_hwservice, hwservice_manager_type;   nano vendor/nxp/emvco/sepolicy/hwservice_contexts vendor.nxp.emvco::INxpEmvco                             u:object_r:hal_emvco_hwservice:s0   nano vendor/nxp/emvco/sepolicy/hal_emvco_default.te + allow hal_emvco_default hal_emvco_hwservice:hwservice_manager { add find };   Error: FAILED: out/soong/.intermediates/hardware/nxp/nfc/intf/nxpnfc/aidl/vendor.nxp.nxpnfc_aidl_interface/checkhash_2.timestamp if [ $(cd 'hardware/nxp/nfc/intf/nxpnfc/aidl/aidl_api/vendor.nxp.nxpnfc_aidl/2' && { find ./ -name "*.aidl" -print0 | LC_ALL=C sort -z | xargs -0 sha1sum && echo 1; } | sha1sum | cut -d " " -f 1) = $(tail -1 'hardware/nxp/nfc/intf/nxpnfc/aidl/aidl_api/vendor.nxp.nxpnfc_aidl/2/.hash') ]; then touch out/soong/.intermediates/hardware/nxp/nfc/intf/nxpnfc/aidl/vendor.nxp.nxpnfc_aidl_interface/checkhash_2.timestamp; else cat 'system/tools/aidl/build/message_check_integrity.txt' && exit 1; fi ############################################################################### # ERROR: Modification detected of stable AIDL API file                        # ############################################################################### Above AIDL file(s) has changed, resulting in a different hash. Hash values may be checked at runtime to verify interface stability. If a device is shipped with this change by ignoring this message, it has a high risk of breaking later when a module using the interface is updated, e.g., Mainline modules. Workaround: echo $(cd 'hardware/nxp/nfc/intf/nxpnfc/aidl/aidl_api/vendor.nxp.nxpnfc_aidl/2' && { find ./ -name "*.aidl" -print0 | LC_ALL=C sort -z | xargs -0 sha1sum && echo 1; } | sha1sum | cut -d " " -f 1) d9e99a62ff5ebed44083a79577ec7ed32d264775 Then,  nano hardware/nxp/nfc/intf/nxpnfc/aidl/aidl_api/vendor.nxp.nxpnfc_aidl/2/.hash replace the value to d9e99a62ff5ebed44083a79577ec7ed32d264775   A runtime error: Problem: You will find the following failed about the permission in the log. java.lang.IllegalStateException: Signature|privileged permissions not in privileged permission allowlist: {com.android.nfc (/apex/com.android.nfcservices/priv-app/[email protected]😞 android.permission.OBSERVE_ROLE_HOLDERS}   Workaround: Add :     <privapp-permissions package="com.android.nfc">         <permission name="android.permission.OBSERVE_ROLE_HOLDERS"/>     </privapp-permissions> To the file : out/target/product/evk_95/system/etc/permissions/privapp-permissions-platform.xml     10. Download the image to the target board: - We use the tool UUU to download the image to the i.MX boards. Download the UUU from here : Releases · nxp-imx/mfgtools - Download the Android 16 BSP i.MX95 EVK demo image from the Android i.MX BSP web page first. There are UUU script and necessary image files already in the demo image package.  demo_image.png - Put the UUU executable file into the demo image folder. uuu_imx_android_flash.bat is the script also in the same folder. - After your Android BSP building is completed and succeed, copy the images to the demo image folder. The image files are located in android_build/out/target/product/evk_95/. - Switch the boot mode to "Download" mode on the i.MX95 FRDM board. - Run the UUU script to download the images to the FRDM board. uuu_imx_android_flash.bat -f imx95 -a -e -u 15x15-frdm -d 15x15-frdm uuu.png     Run the "TagInfo" on the board: - Download the TagInfo apk file from the NXP TagInfo App web page . - Use the "adb install" command to install the TagInfo to the FRDM board. C:\>adb install com.nxp.taginfo-6.2.0-play-release-protected.apk * daemon not running; starting now at tcp:5037 * daemon started successfully Performing Streamed Install Success   After TagInfo installed, the TagInfo icon will be available on the GUI. taginfo1.jpg   Run the TagInfo, and then put a card on the board. taginfo5.jpg taginfo4.jpg The information of the card will be show on the TagInfo App. taginfo3.jpg taginfo2.jpg   nxp.png   Reference: PN7160/PN7220 – Android 16 porting guide PN7220 NFC Frontend IC with Integrated Power Management | NXP Semiconductors Android OS for i.MX Applications Processors | NXP Semiconductors nxp-nfc-infra · GitHub        
查看全文
Prerequisites:  CLRC663 plus Low Power Card Detection   1// Antenna Size  The stronger the coupling between reader and card, the better the detection range.  Ideally, the NFC reader antenna should have a size and form factor similar to that of the target NFC tag antenna. In practice, the reader antenna is typically designed to be slightly larger—by approximately 10% to 20%—to ensure reliable coupling and performance.   2// Antenna Q-factor  Higher Q-factor typically serves higher detection range. The Q-factor should be selected in accordance with the target communication bit rate.(e.g. Q≈30 for 106 kbit/s).  The antenna Q factor is mainly defined by the mechanical design of the antenna itself, as well as by external damping resistors. However, for LPCD-insensitive systems, a zero-ohm damping resistor can be used, and the system should then be evaluated through testing.  3// Target tuning  The CLRC663 should typically be used with the asymmetrical tuning as there is no internal power regulation implemented.  However, in some cases, symmetrical tuning may be beneficial, as it can improve detection range and sensitivity. Care must be taken to ensure that, under varying conditions—such as antenna loading by different NFC tags or the presence of nearby metal, the TVDD current does not exceed the specified maximum limits.   In CLRC663 LPCD operation, detection performance improves with higher TX power. However, this also increases current consumption, so an appropriate trade-off must be determined.   As a starting point, an antenna impedance of approximately Z≈ 50 Ω can be used.   4// Receiver setting (external Rx resistors) Based on the AN11019 (chapter 4.4.1), the peak voltage between RxN and GND (or RxP and GND) shall be in the range of 1.2Vp - 1.7Vp. Generally, higher Rx voltage levels improve detection range. To increase LPCD sensitivity and range, it can be advantageous to operate close to the upper limit of the allowed Rx voltage.   Please note that excessively high RX voltage may lead to immediate false wake-ups.   5//LPCD Settings As a starting point, we recommend using the following settings:   Tomas_Parizek_0-1782894579107.png These settings provide robust immunity against false wake-ups and are highly efficient in terms of current consumption. The typical detection range for standard NFC tags is approximately 10 mm to 20 mm or even less in an application where the antenna is placed near a metal environment. Detection performance can be further improved by lowering the threshold settings +0 and -0. If this settings is used, we strongly advice using LPCD_FILTER feature as well. Alternatively, the user can use "high detection range option" + LPCD_FILTER. Tomas_Parizek_2-1782895496215.png After using these settings, we recommend running "Endless LPCD" for a while and checking for any false wake-up rates. Note: The LPCD filter feature helps prevent false wake-ups. This is especially important when the threshold is set to +0 and -0. When using thresholds of +0 and −0 it is also recommended to set the "CWMAX" parameter (address 0x2A) to 1b. 5.1// LPCD RF ON time  If the RF on-time is shorter than approximately 20 µs - 30 µs , the primary detuning effect is dominated by the physical design of the NFC tag. For longer RF on-times, the NFC tag becomes energized, and its electrical parameters begin to contribute significantly to the overall detuning. Based on this understanding, a longer RF on-time can help increase LPCD detection range. However, this comes at the cost of higher current consumption. Therefore, it is recommended to compensate by adjusting the RF off-time. See an example below.   Tomas_Parizek_0-1782896502650.png 5.2// LPCD Charge pump  This function allows the TX power to be increased exclusively during the LPCD RF On time.   This can be beneficial if you want to avoid increasing the power in active mode (e.g., by reducing the tuning impedance) but only increase it during LPCD operation.   By activating the LPCD charge pump, detection performance can be improved, but at the cost of increased current consumption.   If this feature is enabled, it is recommended to verify the LPCD RF ping using an oscilloscope. It may be necessary to increase the RF On time to allow the amplitude to properly settle. Especially for TVDD= 3.3V or lower. Tomas_Parizek_0-1782910292036.png 6// Summary   Mode  Tuning function Target impedance Q-factor Receiver voltage LPCD Threshold LPCD Filter LPCD Charge -pump RF On time  Standard Asymmetrical  20 Ω - 80 Ω  10 - 30 1.5 Vp +1 and -1 disable disable 10 us High detection range  Asymmetrical /Symmetrical (1) 20 Ω - 50 Ω >25 (2) 1.7 Vp +0 and -0 enable enable/ disable (3)  20 us-100 us   Note (1): Symmetrical tuning can only be applied if the TVDD current does not exceed the maximum allowable value after antenna loading caused by a card or metal object. Please ensure that this condition is met. Note (2): If high detection performance is required, the external antenna damping resistors are typically replaced with 0 Ω resistors, resulting in a higher antenna Q-factor. In this case, the user must verify that NFC communication continues to operate reliably. Due to the increased Q-factor, this configuration is typically limited to communication speeds of 106 kbit/s Note (3): Once the charge pump is enabled, the RF On time should be verified and adjusted if necessary. Please also note that the relationship between TX power and detection distance is not linear or unlimited. Beyond a certain point, enabling the charge pump provides only marginal improvements in detection distance.     Please note that the High Detection mode is generally more susceptible to false wake-ups and results in higher current consumption than the standard mode.
查看全文
This post provides guidance on how to port the example projects from the NXP NCI 2.0 NFC library to the MCXW71 Wireless MCU using SPI interface to communicate with PN7160 SPI EVK. To follow this guide, please use the following environment: MCUXpresso IDE 25.06.136. FRDM-MCXW71 SDK v25.12.00 (last available for MCUXpresso IDE). FRDM-MCXW71. OM27160B1 (PN7160 SPI EVK). Hardware Setup. The MCXW71 complies with the Arduino header standard as the OM27160B1 board, therefore you can connect directly the shield over the FRDM-MCXW71 as the pin connection match among both, allowing an easy connection between the devices. Take into consideration that this setup forces us to use the LPSPI1 instance of the MCXW71, it is possible to use another instance, but we would not be able to connect the boards directly, rather we would need to do the connections with jumpers. RomanVR_2-1776964886314.png Downloading base projects and adapting for MCXW71 port. To start with the porting work, download the NXP-NCI example project from this page. This compressed file contains the base project for different boards that will allow us to do the required modifications to add support for the MCXW71. Once downloaded, extract the SW6705 file into a known path (e.g. the Downloads folder) to later import the project to the IDE. The extracted folder should contain a .zip file with the examples that we will later import to the IDE. RomanVR_3-1776965056204.png Download the FRDM-MCXW71's SDK from the SDK Builder page, make sure to select the 25.12.00 version, as it is the latest SDK available to use along the MCUXpresso IDE. RomanVR_5-1776965144996.png Now we have to import the NXP-NCI2.0_MCUXpresso_examples.zip file we previously extracted to the IDE's workspace, to do so, click on the Import project(s) from file system and in the Project archive (zip) tab, browse for the extracted file of step 1 (NXP-NCI2.0_MCUXpresso_examples.zip) and click on Next >. NOTE: Don’t worry if the IDE shows an error message for not having the SDKs of the default boards (iMXRT1170, LPC55S6x, LPC82x) or having a different version, close the warning message, we only need these examples to copy the NCI library and example files. RomanVR_6-1776965251263.png RomanVR_7-1776965305716.png Your workspace should now look like the following image: RomanVR_8-1776965374185.png Import the hello_world example from the FRDM-MCXW71 SDK: RomanVR_9-1776965452594.png RomanVR_0-1777063242176.png Add the SPI drivers to the imported project by right clicking over the project, hover the cursor over the SDK Management option and select the option Manage SDK Components: RomanVR_11-1776966112046.png Select the driver, click Ok and if you are asked to refresh files accept it, after this you should be able to see the driver in the "drivers" folder of the project. RomanVR_12-1776966161256.png Copy the contents of the source folder of the iMXRT1170 project, as well as the NfcLibrary folder and paste them into the imported hello_world project: RomanVR_13-1776966215404.png         RomanVR_14-1776966224634.png Make sure to delete the hello_world.c and hello_word.mex files as we won't need it again. RomanVR_15-1776966329391.png            RomanVR_16-1776966350734.png After this process your project should look like the following image: RomanVR_17-1776966416175.png To avoid compiling issues, exclude from the build the files nfc_example_P2P.c and nfc_example_RW.c, to do so right click on the file, go to Resource Configurations and select Exclude from Build… and select for all configurations. Do this for each file. RomanVR_18-1776966481521.png Add the preprocessor macro: BOARD_NXPNCI_INTERFACE_SPI, as this is used by the example to select the interface with the board. To do this, right-click on the project and select Properties, then drop-down the C/C++ Build option and go to the Settings tab. Here, add the macro in the Preprocessor option, click on Apply and accept the index rebuild. RomanVR_19-1776966571549.png Add the root folder in C/C++ General > Paths and Symbols > Source Location tab, click on Ok and then Apply: RomanVR_20-1776966631332.png Still in Paths and Symbols, go to the Includes tab and add the source, TML and tool folders from workspace, click Ok and Apply. Make sure to add them one by one. RomanVR_21-1776966724329.png Now, go to C/C++ Build > Settings > Includes and add the following folders from Workspace. You can select all of them and add them at the same time or also do it one by one. Once done, click on Apply and Apply and Close. If you are asked to rebuild the index, do it. "${workspace_loc:/${ProjName}/source/TML}" "${workspace_loc:/${ProjName}/source/tool}" "${workspace_loc:/${ProjName}/NfcLibrary}" "${workspace_loc:/${ProjName}/NfcLibrary/inc}" "${workspace_loc:/${ProjName}/NfcLibrary/NdefLibrary}" "${workspace_loc:/${ProjName}/NfcLibrary/NdefLibrary/inc}" "${workspace_loc:/${ProjName}/NfcLibrary/NdefLibrary/src}" "${workspace_loc:/${ProjName}/NfcLibrary/NxpNci20}" "${workspace_loc:/${ProjName}/NfcLibrary/NxpNci20/inc}" "${workspace_loc:/${ProjName}/NfcLibrary/NxpNci20/src}" RomanVR_22-1776966780932.png Source Code Changes. In the board folder, open the board.h file and add the following definitions to refer to the peripherals and clocks to be used. Please notice that you may change the LPSPI instance, however you would need to connect jumpers instead of connecting directly the shield over the FRDM. #ifdef BOARD_NXPNCI_INTERFACE_SPI #define BOARD_NXPNCI_SPI_CLOCK (CLOCK_GetIpFreq(kCLOCK_Lpspi1)) #define BOARD_NXPNCI_SPI_INSTANCE (LPSPI1) #define BOARD_NXPNCI_SPI_BAUDRATE (400000) #endif #define BOARD_NXPNCI_IRQ_PORT (GPIOC) // J2.10 - GPIO0 [PN7160] - IRQ -> J2.10 GPIOC0 [MCXW71] #define BOARD_NXPNCI_VEN_PORT (GPIOA) // J4.1 - GPIO1 [PN7160] - VEN -> J1.8 GPIOA21 [MCXW71] #define BOARD_NXPNCI_DWL_PORT (GPIOA) // J4.2 - GPIO2 [PN7160] - REQ -> J1.7 GPIOA20 [MCXW71] #define BOARD_NXPNCI_IRQ_PIN (0U) #define BOARD_NXPNCI_VEN_PIN (21U) #define BOARD_NXPNCI_DWL_PIN (20U)   Now we need to add the required clock, peripheral and pin initialization for our board. To do this, go to the hardware_init.c file inside the board folder, and overwrite the BOARD_InitHardware function with the following: void BOARD_InitHardware(void) { BOARD_InitPins(); BOARD_BootClockRUN(); BOARD_InitDebugConsole(); CLOCK_SetIpSrc(kCLOCK_Lpspi1, kCLOCK_IpSrcFro192M); CLOCK_SetIpSrcDiv(kCLOCK_Lpspi1, kSCG_SysClkDivBy16); }   To add the correct pin multiplexing and configuration for our SPI and GPIO pins, go to the pin_mux.c file (also in the board folder) and overwrite the BOARD_InitPins function with the following: void BOARD_InitPins(void) { /* Clock Configuration: Peripheral clocks are enabled; module does not stall low power mode entry */ CLOCK_EnableClock(kCLOCK_GpioA); CLOCK_EnableClock(kCLOCK_GpioC); CLOCK_EnableClock(kCLOCK_PortA); CLOCK_EnableClock(kCLOCK_PortB); CLOCK_EnableClock(kCLOCK_PortC); /*IF SHORTING SH11, SH12, SH13, SH14 needed for LPSPI1*/ const port_pin_config_t portb0_pin46_config = {/* Internal pull-up resistor is enabled */ (uint16_t)kPORT_PullUp, /* Low internal pull resistor value is selected. */ (uint16_t)kPORT_LowPullResistor, /* Fast slew rate is configured */ (uint16_t)kPORT_FastSlewRate, /* Passive input filter is disabled */ (uint16_t)kPORT_PassiveFilterDisable, /* Open drain output is disabled */ (uint16_t)kPORT_OpenDrainDisable, /* Low drive strength is configured */ (uint16_t)kPORT_LowDriveStrength, /* Normal drive strength is configured */ (uint16_t)kPORT_NormalDriveStrength, /* Pin is configured as LPSPI0_PCS0 */ (uint16_t)kPORT_MuxAlt2, /* Pin Control Register fields [15:0] are not locked */ (uint16_t)kPORT_UnlockRegister}; /* PORTB0 (pin 46) is configured as LPSPI1_PCS0 */ PORT_SetPinConfig(PORTB, 0U, &portb0_pin46_config); const port_pin_config_t portb1_pin47_config = {/* Internal pull-up resistor is enabled */ (uint16_t)kPORT_PullUp, /* Low internal pull resistor value is selected. */ (uint16_t)kPORT_LowPullResistor, /* Fast slew rate is configured */ (uint16_t)kPORT_FastSlewRate, /* Passive input filter is disabled */ (uint16_t)kPORT_PassiveFilterDisable, /* Open drain output is disabled */ (uint16_t)kPORT_OpenDrainDisable, /* Low drive strength is configured */ (uint16_t)kPORT_LowDriveStrength, /* Normal drive strength is configured */ (uint16_t)kPORT_NormalDriveStrength, /* Pin is configured as LPSPI0_SIN */ (uint16_t)kPORT_MuxAlt2, /* Pin Control Register fields [15:0] are not locked */ (uint16_t)kPORT_UnlockRegister}; /* PORTB1 (pin 47) is configured as LPSPI1_SIN */ PORT_SetPinConfig(PORTB, 1U, &portb1_pin47_config); const port_pin_config_t portb3_pin1_config = {/* Internal pull-up resistor is enabled */ (uint16_t)kPORT_PullUp, /* Low internal pull resistor value is selected. */ (uint16_t)kPORT_LowPullResistor, /* Fast slew rate is configured */ (uint16_t)kPORT_FastSlewRate, /* Passive input filter is disabled */ (uint16_t)kPORT_PassiveFilterDisable, /* Open drain output is disabled */ (uint16_t)kPORT_OpenDrainDisable, /* Low drive strength is configured */ (uint16_t)kPORT_LowDriveStrength, /* Normal drive strength is configured */ (uint16_t)kPORT_NormalDriveStrength, /* Pin is configured as LPSPI0_SOUT */ (uint16_t)kPORT_MuxAlt2, /* Pin Control Register fields [15:0] are not locked */ (uint16_t)kPORT_UnlockRegister}; /* PORTB3 (pin 1) is configured as LPSPI1_SOUT */ PORT_SetPinConfig(PORTB, 3U, &portb3_pin1_config); const port_pin_config_t portb2_pin48_config = {/* Internal pull-up resistor is enabled */ (uint16_t)kPORT_PullUp, /* Low internal pull resistor value is selected. */ (uint16_t)kPORT_LowPullResistor, /* Fast slew rate is configured */ (uint16_t)kPORT_FastSlewRate, /* Passive input filter is disabled */ (uint16_t)kPORT_PassiveFilterDisable, /* Open drain output is disabled */ (uint16_t)kPORT_OpenDrainDisable, /* Low drive strength is configured */ (uint16_t)kPORT_LowDriveStrength, /* Normal drive strength is configured */ (uint16_t)kPORT_NormalDriveStrength, /* Pin is configured as LPSPI0_SCK */ (uint16_t)kPORT_MuxAlt2, /* Pin Control Register fields [15:0] are not locked */ (uint16_t)kPORT_UnlockRegister}; /* PORTA19 (pin 14) is configured as LPSPI1_SCK */ PORT_SetPinConfig(PORTB, 2U, &portb2_pin48_config); /*IF SHORTING SH11, SH12, SH13, SH14 needed for LPSPI1*/ const port_pin_config_t irq_pin = {/* Internal pull-up/down resistor is disabled */ (uint16_t)kPORT_PullUp, /* Low internal pull resistor value is selected. */ (uint16_t)kPORT_LowPullResistor, /* Fast slew rate is configured */ (uint16_t)kPORT_FastSlewRate, /* Passive input filter is disabled */ (uint16_t)kPORT_PassiveFilterDisable, /* Open drain output is disabled */ (uint16_t)kPORT_OpenDrainDisable, /* Low drive strength is configured */ (uint16_t)kPORT_LowDriveStrength, /* Normal drive strength is configured */ (uint16_t)kPORT_NormalDriveStrength, /* Pin is configured as PTC0 */ (uint16_t)kPORT_MuxAsGpio, /* Pin Control Register fields [15:0] are not locked */ (uint16_t)kPORT_UnlockRegister}; /* PORTC0 (pin 37) is configured as PTC0 */ PORT_SetPinConfig(PORTC, 0U, &irq_pin); const port_pin_config_t ven_pin = {/* Internal pull-up/down resistor is disabled */ (uint16_t)kPORT_PullDisable, /* Low internal pull resistor value is selected. */ (uint16_t)kPORT_LowPullResistor, /* Fast slew rate is configured */ (uint16_t)kPORT_FastSlewRate, /* Passive input filter is disabled */ (uint16_t)kPORT_PassiveFilterDisable, /* Open drain output is disabled */ (uint16_t)kPORT_OpenDrainDisable, /* Low drive strength is configured */ (uint16_t)kPORT_LowDriveStrength, /* Normal drive strength is configured */ (uint16_t)kPORT_NormalDriveStrength, /* Pin is configured as PTA20 */ (uint16_t)kPORT_MuxAsGpio, /* Pin Control Register fields [15:0] are not locked */ (uint16_t)kPORT_UnlockRegister}; /* PORTA20 (pin 17) is configured as PTA20 */ PORT_SetPinConfig(PORTA, 20U, &ven_pin); const port_pin_config_t req_pin = {/* Internal pull-up/down resistor is disabled */ (uint16_t)kPORT_PullDisable, /* Low internal pull resistor value is selected. */ (uint16_t)kPORT_LowPullResistor, /* Fast slew rate is configured */ (uint16_t)kPORT_FastSlewRate, /* Passive input filter is disabled */ (uint16_t)kPORT_PassiveFilterDisable, /* Open drain output is disabled */ (uint16_t)kPORT_OpenDrainDisable, /* Low drive strength is configured */ (uint16_t)kPORT_LowDriveStrength, /* Normal drive strength is configured */ (uint16_t)kPORT_NormalDriveStrength, /* Pin is configured as PTA21 */ (uint16_t)kPORT_MuxAsGpio, /* Pin Control Register fields [15:0] are not locked */ (uint16_t)kPORT_UnlockRegister}; /* PORTA21 (pin 18) is configured as PTA21 */ PORT_SetPinConfig(PORTA, 21U, &req_pin); const port_pin_config_t portc2_pin39_config = {/* Internal pull-up/down resistor is disabled */ (uint16_t)kPORT_PullDisable, /* Low internal pull resistor value is selected. */ (uint16_t)kPORT_LowPullResistor, /* Fast slew rate is configured */ (uint16_t)kPORT_FastSlewRate, /* Passive input filter is disabled */ (uint16_t)kPORT_PassiveFilterDisable, /* Open drain output is disabled */ (uint16_t)kPORT_OpenDrainDisable, /* Low drive strength is configured */ (uint16_t)kPORT_LowDriveStrength, /* Normal drive strength is configured */ (uint16_t)kPORT_NormalDriveStrength, /* Pin is configured as LPUART1_RX */ (uint16_t)kPORT_MuxAlt3, /* Pin Control Register fields [15:0] are not locked */ (uint16_t)kPORT_UnlockRegister}; /* PORTC2 (pin 39) is configured as LPUART1_RX */ PORT_SetPinConfig(PORTC, 2U, &portc2_pin39_config); const port_pin_config_t portc3_pin40_config = {/* Internal pull-up/down resistor is disabled */ (uint16_t)kPORT_PullDisable, /* Low internal pull resistor value is selected. */ (uint16_t)kPORT_LowPullResistor, /* Fast slew rate is configured */ (uint16_t)kPORT_FastSlewRate, /* Passive input filter is disabled */ (uint16_t)kPORT_PassiveFilterDisable, /* Open drain output is disabled */ (uint16_t)kPORT_OpenDrainDisable, /* Low drive strength is configured */ (uint16_t)kPORT_LowDriveStrength, /* Normal drive strength is configured */ (uint16_t)kPORT_NormalDriveStrength, /* Pin is configured as LPUART1_TX */ (uint16_t)kPORT_MuxAlt3, /* Pin Control Register fields [15:0] are not locked */ (uint16_t)kPORT_UnlockRegister}; /* PORTC3 (pin 40) is configured as LPUART1_TX */ PORT_SetPinConfig(PORTC, 3U, &portc3_pin40_config); }   To add the required interfacing APIs specific of our chip, we need to modify the tml.c file from the TML folder, in this file overwrite the functions: INTF_INIT, INTF_WRITE and INTF_READ with the following: static void INTF_INIT(void) { lpspi_master_config_t userConfig; uint32_t srcFreq = 0; /*SPI configuration*/ LPSPI_MasterGetDefaultConfig(&userConfig); userConfig.baudRate = BOARD_NXPNCI_SPI_BAUDRATE; srcFreq = BOARD_NXPNCI_SPI_CLOCK; userConfig.whichPcs = (lpspi_which_pcs_t)kLPSPI_Pcs0; userConfig.pcsActiveHighOrLow = (lpspi_pcs_polarity_config_t)kLPSPI_PcsActiveLow; /*Initialize SPI*/ LPSPI_MasterInit(BOARD_NXPNCI_SPI_INSTANCE, &userConfig, srcFreq); } static status_t INTF_WRITE(uint8_t *pBuff, uint16_t buffLen) { uint8_t temp[1000]; temp[0] = 0x7F; memcpy(temp+1, pBuff, buffLen); masterXfer.txData = temp; masterXfer.rxData = NULL; masterXfer.dataSize = buffLen+1; masterXfer.configFlags = kLPSPI_MasterPcs0 | kLPSPI_MasterPcsContinuous | kLPSPI_MasterByteSwap;; return LPSPI_MasterTransferBlocking(BOARD_NXPNCI_SPI_INSTANCE, &masterXfer); } static status_t INTF_READ(uint8_t *pBuff, uint16_t buffLen) { status_t status; uint8_t temp[257]; temp[0] = 0xFF; masterXfer.txData = temp; masterXfer.rxData = temp; masterXfer.dataSize = buffLen+1; masterXfer.configFlags = kLPSPI_MasterPcs0 | kLPSPI_MasterPcsContinuous | kLPSPI_MasterByteSwap;; status = LPSPI_MasterTransferBlocking(BOARD_NXPNCI_SPI_INSTANCE, &masterXfer); if(status == kStatus_Success) memcpy(pBuff, temp+1, buffLen); SDK_DelayAtLeastUs(10, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY); return status; } #endif   We also need to overwrite the functions: tml_Init, tml_DeInit and tml_Reset to adapt them to use the specific APIs for the GPIOs of our board. static Status tml_Init(void) { gpio_pin_config_t in_config = {kGPIO_DigitalInput, 0}; gpio_pin_config_t out_config = {kGPIO_DigitalOutput, 0}; GPIO_PinInit(BOARD_NXPNCI_IRQ_PORT, BOARD_NXPNCI_IRQ_PIN, &in_config); GPIO_PinInit(BOARD_NXPNCI_VEN_PORT, BOARD_NXPNCI_VEN_PIN, &out_config); GPIO_PinInit(BOARD_NXPNCI_DWL_PORT, BOARD_NXPNCI_DWL_PIN, &out_config); INTF_INIT(); return SUCCESS; } static Status tml_DeInit(void) { GPIO_PortClear(BOARD_NXPNCI_VEN_PORT, 1U << BOARD_NXPNCI_VEN_PIN); return SUCCESS; } static Status tml_Reset(void) { /* Set DWL_REQ low for NCI protocol */ GPIO_PortClear(BOARD_NXPNCI_DWL_PORT, 1U << BOARD_NXPNCI_DWL_PIN); GPIO_PortClear(BOARD_NXPNCI_VEN_PORT, 1U << BOARD_NXPNCI_VEN_PIN); Sleep(10); GPIO_PortSet(BOARD_NXPNCI_VEN_PORT, 1U << BOARD_NXPNCI_VEN_PIN); Sleep(10); return SUCCESS; }   Finally, modify the main file so it uses the APIs to initialize our board clocks and pins: #include <stdio.h> #include <string.h> #include "app.h" #include "board.h" #include "pin_mux.h" #include "fsl_debug_console.h" extern void nfc_example (void); int main(void) { BOARD_InitHardware(); #ifdef BOARD_NXPNCI_INTERFACE_I2C PRINTF("\nRunning the NXP-NCI2.0 example (I2C interface)\n"); #else PRINTF("\nRunning the NXP-NCI2.0 example (SPI interface)\n"); #endif nfc_example(); } Testing the example. At this point we have everything set to build and flash our example with SPI interface, you may proceed to build and debug/flash the example by pressing the blue beetle button: RomanVR_23-1776969017743.png Once the example is flashed, open a serial terminal such as Teraterm with the following settings: Baudrate: 115200. Data: 8 bits. Parity: None. Stop bits: 1 bit. No flow control. While running, the example should output the following logs to the terminal: RomanVR_24-1776969098939.png When a tag is placed near the antenna, the example should print the tag information in the terminal as shown: RomanVR_25-1776969122735.png  
查看全文
The TDAEV8035 evaluation board is inserted into the connector slot located on the top side of the PN7642 EVK, as shown in the figure below.   Tomas_Parizek_0-1783430718849.png   Dedicated jumper settings are required to ensure proper connection and operation of the TDAEV8035 extension board.   J23 - Position 2-3 J65, J63, J64 - Closed  J59 - Closed (Positions 1-2, 3-4, 5-6) Once the jumpers are configured correctly, users can run the example applications provided in the PN7642 MCUXpresso SDK.   Tomas_Parizek_0-1783431007072.png   After building the example project, select the right card slot (TDA8035) on the board. By default, the SIM card slot (Slot 1) is used. To use the contact card slot instead, modify the slot selection in the following section of the code.   Tomas_Parizek_1-1783431121171.png   E_AUX_SLOT1 - SIM slot (default)  E_AUX_SLOT2 - Contact card slot  The selected card slot is indicated by a red LED. D1 - SIM slot  D2 - Contact Card slot Once all required settings have been applied, the example application can be started and a contact card can be inserted into the selected card slot.    The results can be viewed in the console.   Tomas_Parizek_0-1783431467282.png
查看全文
Introduction. 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. The hardware required to follow this guide is: FRDM-MCXN947 development board as host MCU. PNEV5190BP (based on PN5190) as the NFC transceiver Software Setup. MCXN947 SDK version: 26.06.00 NFCReaderLibrary version: 07.16.00 PN5190 FW version: 0x20D MCUxpresso IDE version: 25.6 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 For any additional configuration, please see PNEV5190B evaluation board quick start guide. 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. Habib_MS_0-1781134009079.png             Habib_MS_1-1781134021054.png 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. Habib_MS_1-1781196999826.png #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_0-1781198808350.png /****************************************************************** * 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_1-1781198875355.png /***************************************************************** * 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_2-1781198913604.png /***************************************************************** * 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 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: Habib_MS_4-1781199007051.png #include "phDriver.h" #include <board.h> #include "BoardSelection.h" #include <fsl_lpspi.h> #include <fsl_clock.h> #include <fsl_port.h> #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_5-1781199067774.png 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_0-1781200864120.png Habib_MS_1-1781200889109.png 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_2-1781200981954.png 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_3-1781201256179.png   #include "phDriver.h" #include "BoardSelection.h" #include "fsl_device_registers.h" #include <fsl_gpio.h> #include <fsl_ctimer.h> /* *********************************************************************************************************** * 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_4-1781201344846.png Habib_MS_5-1781201376952.png 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_7-1781201652469.png 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_0-1781201935240.png 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; uint8_t bPortGpio; 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); bPortGpio = (uint8_t)((dwPinNumber & 0xFF00)>>8); 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_1-1781202317214.png uint8_t phDriver_PinRead(uint32_t dwPinNumber, phDriver_Pin_Func_t ePinFunc) { uint8_t bValue; uint32_t intStatus; uint8_t bGpioNum; uint8_t bPinNum; /* Extract the Pin, Gpio details from dwPinNumber */ bPinNum = (uint8_t)(dwPinNumber & 0xFF); bGpioNum = (uint8_t)((dwPinNumber & 0xFF00)>>8); 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_3-1781202436423.png void phDriver_PinWrite(uint32_t dwPinNumber, uint8_t bValue) { uint8_t bGpioNum; uint8_t bPinNum; /* Extract the Pin, Gpio details from dwPinNumber */ bPinNum = (uint8_t)(dwPinNumber & 0xFF); bGpioNum = (uint8_t)((dwPinNumber & 0xFF00)>>8); GPIO_PinWrite((GPIO_Type *)pGpiosBaseAddr[GPIO_PORT], bPinNum, bValue); } void phDriver_PinClearIntStatus(uint32_t dwPinNumber) { uint8_t bGpioNum; uint8_t bPinNum; /* Extract the Pin, Gpio details from dwPinNumber */ bPinNum = (uint8_t)(dwPinNumber & 0xFF); bGpioNum = (uint8_t)((dwPinNumber & 0xFF00)>>8); /*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_4-1781202506101.png 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_5-1781202601491.png 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_6-1781202691439.png #ifdef PHDRIVER_FRDMMCXN947_PN5190_BOARD # include <Board_FRDM_MCXN947_PN5190.h> #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_7-1781202815632.png #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_8-1781202847396.png /*Check for MCXN controller based boards*/ #if defined (PHDRIVER_FRDMMCXN947_PN5190_BOARD) #define PHDRIVER_FRDM_MCXN947 #endif #ifdef PHDRIVER_FRDM_MCXN947 #include <fsl_debug_console.h> #include <stdio.h> #include <fsl_gpio.h> #include <fsl_ctimer.h> #include <fsl_clock.h> #include <fsl_lpspi.h> #endif Please replace this line.   #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_0-1781205399694.png   #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   #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_1-1781205512787.png #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 board -> pin_mux.c file, the following initializations need to be added: Habib_MS_3-1781205793803.png 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. Habib_MS_4-1781205847058.png Habib_MS_5-1781205872354.png Habib_MS_6-1781205919494.png 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-1781207973118.png #include "fsl_common.h" #include "fsl_port.h" #include "board.h" #include "clock_config.h" #include "pin_mux.h" Adding include paths   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. Habib_MS_2-1785533633824.png Habib_MS_3-1785533645497.png     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: Habib_MS_0-1781896206808.png #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 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: Habib_MS_0-1785536616039.png Habib_MS_1-1785536639784.png     Now you are able to build and debug following the chapter Testing Final Project Without OS but now with FreeRTOS.                                                                          
查看全文