Multi Source Translation Content

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

Multi Source Translation Content

讨论

排序依据:
FRDM-RW612 (Zephyr) — CTIMER0 MAT0/GPIO0 PWM 不切换,MAT1/MAT2 工作正常 开发板/SDK: FRDM-RW612,NXP-Zephyr v4.3.0 将板载 RGB LED(GPIO0=蓝色,GPIO1=红色,GPIO12=绿色)配置为 CTIMER0 上的 pwm-leds,通道分别为 0/1/2,使用共享 pinctrl-0 组中的 IO_MUX_CT0_MAT0_OUT_IO0、IO_MUX_CT0_MAT1_OUT_IO1、IO_MUX_CT0_MAT2_OUT_IO12。运行测试应用程序,对所有三个通道进行占空比循环测试。 红色和绿色 LED 的 PWM 工作正常(已使用 Saleae 逻辑分析仪确认——GPIO1 和 GPIO12 上的波形干净)。蓝色 LED (GPIO0/MAT0) 完全熄灭——逻辑分析仪显示一条直线,在任何占空比 (0–100%) 下都不会切换。数字GPIO(非PWM)切换GPIO0工作正常, 只有 CTIMER0 MAT0 通道无法输出 PWM;同一定时器实例上的 MAT1/MAT2 可以正常工作。 我们需要: 确认在 Zephyr 下,FRDM-RW612 上的 GPIO0/CT0_MAT0 是否为已知可用的 PWM 组合。 关于 RW612 上 CTIMER0 通道 0 的任何勘误/限制的指导。 任何可用的 .overlay例如,通过 CTIMER 对 GPIO0 进行 PWM 控制,以便我们进行比较。 frdm_rw612.overlay ``` #include / { pwm_outputs { 兼容 = "pwm-leds"; pwm_gpio0:pwm_gpio0 { pwms = <&ctimer0_pwm 0 PWM_KHZ(1) PWM_POLARITY_NORMAL>; }; pwm_gpio1:pwm_gpio1 { pwms = <&ctimer0_pwm 1 PWM_KHZ(1) PWM_POLARITY_NORMAL>; }; pwm_gpio12:pwm_gpio12 { pwms = <&ctimer0_pwm 2 PWM_KHZ(1) PWM_POLARITY_NORMAL>; }; }; 别名 { pwm-gpio0 = &pwm_gpio0; pwm-gpio1 = &pwm_gpio1; pwm-gpio12 = &pwm_gpio12; }; }; ctimer0_pwm: &ctimer0 { 兼容 = "nxp,ctimer-pwm"; 状态 = "好的" clk-source = <5>; clocks = <&clkctl1 MCUX_CTIMER0_CLK>; #pwm-cells = <3>; 模式 = <0>; 预缩放 = <0>; pinctrl-0 = <&pinmux_ctimer0_pwm>; pinctrl-names = "default"; }; &pinctrl { pinmux_ctimer0_pwm:pinmux_ctimer0_pwm { group0 { pinmux = < IO_MUX_CT0_MAT0_OUT_IO0 IO_MUX_CT0_MAT1_OUT_IO1 IO_MUX_CT0_MAT2_OUT_IO12 >; 转换速率 = "正常"; }; }; }; ``` 评估板 Re: FRDM-RW612 (Zephyr) — CTIMER0 MAT0/GPIO0 PWM not toggling, MAT1/MAT2 work fine 你好, 希望你一切都好。请问您能否帮我们确认一下,您是以哪个应用程序为基础的? 另外,您能否详细说明一下您是如何测量PWM信号的?FRDM 中每个 PWM 的特定引脚。 顺祝商祺! 里卡多
查看全文
MRF13750H AWR 型号 你好, 我正在尝试使用贵公司网站上提供的官方设计文件,将 MRF13750H 晶体管模型导入 Cadence AWR Microwave Office。 下载完设计套件和晶体管模型后,尝试打开模型时出现错误。我已附上错误信息的截图。 Luis_V_0-1789581238483.pngLuis_V_0-1789581238483.pngLuis_V_0-1789581238483.png 我已经联系了Cadence的技术支持。他们的团队也尝试下载并打开该模型,并确认遇到了完全相同的问题。 请您核实这些文件,并告知我如何解决这个问题? 最好的, 路易斯·V. 射频 Re: MRF13750H AWR MODEL 你好 Luis_V 再会! 该错误是由于兼容性问题导致的。您尝试安装的模型比较老旧,是为早期版本的 AWR 设计环境设计的。目前尚无计划对其进行更新以适应新版本的软件。 如果您需要使用此型号,最实用的解决方案是安装一个较旧版本的 AWR,例如 2015 年左右的版本(例如 AWR v11 或 v12),该版本与此型号兼容。这样应该可以避免遇到 GetIAwrUserIO DLL 错误。 对于可能由此导致的不便,我们深感抱歉。 希望这些信息对您有所帮助,如果您还需要其他帮助,请告诉我。 祝你今天过得愉快,一切顺利。 Re: MRF13750H AWR MODEL 你好,拉法, 我正在联系 Cadence 公司,看看他们是否可以提供旧版本的 AWR。与此同时,您能否帮我联系一下设计 MRF13750H-915MHz 板的工程师,或者其他可以帮我收集一些数据的人?我这里有NXP的这款产品,我们需要用它。 此外,您之前提到过您可以在您那边打开 ADS/AWR 来查看 T 型接头不连续性、斜接弯头、开路效应等。您能否给我发送一个窗口截图,以便我检查微带线的尺寸和特性?在等待 Cadence 的回复期间,如果您能运行负载牵引分析来找出源阻抗和负载阻抗值,我将不胜感激。 最好的, 路易斯·维拉纽瓦 Re: MRF13750H AWR MODEL 你好 Luis_V 再会! 由于 NXP 已决定(暂时)缩减射频领域的业务,我们该部门的许多同事已经离开了公司,这意味着可用的人员减少了。所以,请告诉我您有什么问题,我会尽力解答;如果我无法解答,我会将此事上报给客户经理寻求支持,但我不能与您分享任何人的联系方式。 感谢您的理解。 祝你今天过得愉快,一切顺利。
查看全文
imx93 上的 SAI 填充位配置 我在 Linux 系统下配置 imx 和编解码器之间的 sai 连接时遇到了困难。 编解码器为 AK4619,采用 4 通道 TDM 模式。48KHz / 32 位 TDM 模式下播放正常,MSB 优先且 MSB 对齐。 对于捕获,AK4619 仅支持 24 位。数据采用最高有效位对齐,这意味着非有效位位于相关位之后(有效位为 8-31)。另一方面,sai 将 FBT 设置为 23,这意味着有效位为 0-23。 我尝试查找相关设置,但没有找到。我知道 FBT 指示相关数据的起始位置,但我找不到哪个寄存器设置数据大小(在我的情况下是 24,而不是字长 32)。 需要设置哪个寄存器,或者需要在设备树中设置哪些配置?以下是我实际使用的相关配置: &sai3 { #sound-dai-cells = <0>; clocks = <&clk IMX93_CLK_SAI3_IPG>, <&clk IMX93_CLK_DUMMY>, <&clk IMX93_CLK_SAI3_GATE>, <&clk IMX93_CLK_DUMMY>, <&clk IMX93_CLK_DUMMY>, <&clk IMX93_CLK_AUDIO_PLL>; clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3", "pll8k"; assigned-clocks = <&clk IMX93_CLK_SAI3>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_sai3>; assigned-clock-parents = <&clk IMX93_CLK_AUDIO_PLL>; assigned-clock-rates = <24576000>; fsl,sai-mclk-direction-output; fsl,sai-asynchronous; status = "okay"; }; simple-audio-card,dai-link { link-name = "AK-4CHANNELS"; format = "i2s"; dai-tdm-slot-num = <4>; dai-tdm-slot-width = <32>; fsl,mclk-equal-bclk; cpu { sound-dai = <&sai3>; dai-tdm-slot-num = <4>; dai-tdm-slot-width = <32>; assigned-clocks = <&clk IMX93_CLK_SAI3>; }; codec { sound-dai = <&ak4619>; system-clock-frequency = <24576000>; assigned-clocks = <&clk IMX93_CLK_SAI3>; dai-tdm-slot-num = <4>; dai-tdm-slot-width = <32>; }; }; 我用示波器检查过了,sai 线上的数据看起来是正确的。 任何提示都将不胜感激。 Re: SAI padding bits configuration on imx93 谢谢。 问题是我不知道该在这个登记簿里写些什么。我能找到的唯一一份文件是 julienblanc_0-1789720432684.pngjulienblanc_0-1789720432684.pngjulienblanc_0-1789720432684.png 我已将我案例中的相关行高亮显示。所以,是的,我应该在 FBT 中写入 0b11111,但我如何知道只有 24 位是相关的呢?我的理解是,我不能使用 W0W 和 WNW,因为它们表示字长,而我的字长是 32 位。我在两个 RCRx 寄存器中都找不到任何相关信息。 此致, 朱利安 Re: SAI padding bits configuration on imx93 你好, 您在录制/播放时是否尝试过使用 ALSA 的 -f S32_LE 参数? 此配置并非在设备树中完成,如果要通过驱动程序进行配置,则需要在此处修改寄存器 TCR5/RCR5: https://github.com/nxp-imx/linux-imx/blob/b096ce610e956cc2596006343df8a2a26ed6e019/sound/soc/fsl/fsl_sai.h https://github.com/nxp-imx/linux-imx/blob/b096ce610e956cc2596006343df8a2a26ed6e019/sound/soc/fsl/fsl_sai.c 顺祝商祺! Re: SAI padding bits configuration on imx93 实际上,这些额外的部分似乎并没有造成任何问题。修改驱动程序,将正确的值写入 FBT 后,音频就能正常工作了。 顺祝商祺!
查看全文
FRDM-RW612(Zephyr) — CTIMER0 MAT0/GPIO0 PWMが切り替えられず、MAT1/MAT2は問題なく動作します ボード/SDK: FRDM-RW612、NXP-Zephyr v4.3.0 搭載のRGB LED(GPIO0=青、GPIO1=赤、GPIO12=緑)をpwm-ledとしてCTIMER0、それぞれチャネル0/1/2として、IO_MUX_CT0_MAT0_OUT_IO0、IO_MUX_CT0_MAT1_OUT_IO1、IO_MUX_CT0_MAT2_OUT_IO12を共用pinctrl-0グループで構成しました。3チャネルすべてでテストアプリをサイクルサイクルで実行しました。 赤色および緑色のLEDは正しくPWM制御されています(Saleaeロジックアナライザで確認済み - GPIO1およびGPIO12の波形は正常です)。青色LED(GPIO0/MAT0)は完全に消灯したままで、ロジックアナライザは平坦な線を示し、デューティサイクル(0~100%)のいずれにおいてもトグルは発生しません。GPIO0のデジタルGPIO(非PWM)トグルは問題なく動作します。 CTIMER0 MAT0チャネルのみがPWM出力に失敗します。同じタイマーインスタンス上のMAT1/MAT2は動作します。 必要なもの: GPIO0/CT0_MAT0がZephyrのFRDM-RW612上で既知の動作PWM組み合わせであるかどうかの確認。 RW612のチャネル0 CTIMER0に関するエラタムや制限に関するガイダンスがあります。 動作する.overlay例として、CTIMER を介して GPIO0 を PWM する例を挙げ、それと比較します。 frdm_rw612.オーバーレイ 「`」 #include < zephyr/dt-bindings/pwm/pwm.h> / { pwm_outputs { compatible = "pwm-leds"; pwm_gpio0: pwm_gpio0 { pwms = <&ctimer0_pwm 0 PWM_KHZ(1) PWM_POLARITY_NORMAL>; }; pwm_gpio1: pwm_gpio1 { pwms = <&ctimer0_pwm 1 PWM_KHZ(1) PWM_POLARITY_NORMAL>; }; pwm_gpio12: pwm_gpio12 { pwms = <&ctimer0_pwm 2 PWM_KHZ(1) PWM_POLARITY_NORMAL>; }; }; エイリアス { pwm-gpio0 = &pwm_gpio0; pwm-gpio1 = &pwm_gpio1; pwm-gpio12 = &pwm_gpio12; }; }; ctimer0_pwm: &ctimer0 { compatible = "nxp,ctimer-pwm"; ステータス = "okay" clk-source = <5>; クロック = <&clkctl1 MCUX_CTIMER0_CLK>; #pwm-cells = <3>; モード = <0>; プリスケール = <0>; pinctrl-0 = <&pinmux_ctimer0_pwm>; pinctrl-names = "default"; }; &pinctrl { pinmux_ctimer0_pwm: pinmux_ctimer0_pwm { グループ0 { pinmux = < IO_MUX_CT0_MAT0_OUT_IO0 IO_MUX_CT0_MAT1_OUT_IO1 IO_MUX_CT0_MAT2_OUT_IO12 >; スルーレート = "通常"; }; }; }; 「`」 評価ボード Re: FRDM-RW612 (Zephyr) — CTIMER0 MAT0/GPIO0 PWM not toggling, MAT1/MAT2 work fine こんにちは、 あなたの調子が良いといいのですが。どのアプリケーションを基準にしているのか、確認を手伝ってもらえますか? また、PWM信号をどのように測定しているのか、もう少し詳しく教えてもらえますか?各PWMに対応するFRDMの特定ピン。 よろしくお願いいたします。 リカルド
查看全文
S32 Design Studio for S32 プラットフォーム v3.4 ライセンスが切れました 私のS32 Design Studio for S32 プラットフォーム v3.4のライセンスが期限切れになりました。 私のアクティベーションコードのライセンスを延長してもらえますか? アイテム説明:S32 プラットフォーム v3.4向けS32 Design Studio 注文番号: S32DS-3-4_184061557 ライセンス総数: 101 アクティベーションコード: 878E-BE4B-A152-EB7E よろしくお願いします。 Re: S32 Design Studio for S32 Platform v3.4 License Expired こんにちは、 お客様のS32DSライセンスが延長されました。以前のコードを使用して、S32DSを再度有効化してください。
查看全文
NXP i.MX93 EVKのNPU温度と使用率を取得する方法 私はi.MX93 EVKを使っており、Ethos-UのNPU温度と稼働率(負荷)を実行時に監視したいのですが、このデータをどうやって取得できますか? 目的は、AIモデルの推論中にハードウェアパラメータを監視することです。 i.MX8MPlusで以下のパラメータを監視できます。i.MX93でも同様のことを実現したいです。 8Mプラス RAM=$(free -m | awk '/Mem:/ {print $3}') CPU_LOAD=$(vmstat 1 2 | tail -1 | awk '{print 100 - $15}') CPU_TEMP=$(awk '{print $1/1000}' /sys/class/thermal/thermal_zone0/temp 2>/dev/null || echo "N/A") GPU_TEMP=$(awk '{print $1/1000}' /sys/class/thermal/thermal_zone1/temp 2>/dev/null || echo "${CPU_TEMP}") GPU_LOAD=$(cat /sys/kernel/debug/gc/load 2>/dev/null | awk '/load/ {gsub("%","",$3); if (max=="" || $3>max) max=$3} END {if (max!="") print max "%"; else print "N/A"}') i.MX93 RAM=$(free -m | awk '/Mem:/ {print $3}') CPU_LOAD=$(vmstat 1 2 | tail -1 | awk '{print 100 - $15}') CPU_TEMP=$(awk '{print $1/1000}' /sys/class/thermal/thermal_zone0/temp) i.MX93 NPU(ethos-u)のGPU_LOADとGPU_TEMPをどうやって監視できますか? Linux Re: How to get NPU Temperature and utilization for NXP i.MX93 EVK こんにちは、@sonal-acldigital i.MX 8M Plusも i.MX 93も、NPU温度をリアルタイムで監視する方法を提供していません。 - imx8MP、thermal_zone0はCPUの温度を表し、thermal_zone1はSoCの温度を表します。 - imx93、thermal_zone0はCPUの温度を表します。 - NPU、 nputopのようなツールは存在しません。 パフォーマンスチューニングに関する情報については、セクション7.1.2を参照してください。「ハードウェアアクセラレータのプロファイリング」、 MLユーザーガイドに収録。 B.R Re: How to get NPU Temperature and utilization for NXP i.MX93 EVK @pengyong_zhang i.MX 8M Plusとi.MX 93の熱ゾーンについてご説明いただきありがとうございます。以下の点を明確にしていただけますか? i.MX8MPLUS 1. GPU温度: 個別のGPU温度を読み取る専用のシステムパス(/sys/class/thermal/thermal/thermal_zoneX/temp)はありますか?それともソックサーマルゾーン(thermal_zone1)だけでカバーされているのでしょうか? 2. GPU負荷: /sys/kernel/debug/gc/loadを読み込むことがGPU負荷の確認の標準的な方法ですか?それともMLユーザーガイドのセクション7.1.2に詳述されている手順も必要ですか? i.MX93: NPUの負荷と温度を監視するネイティブツール(nputopなど)がないため、次の点について質問させてください。推論の実行をNPUにオフロードした場合とCPUのみで実行した場合のCPU負荷の減少を測定することで、相対的なNPU使用率を導き出すことは妥当でしょうか? もしこの方法が推奨されていない場合、推論実行中のNPU活動を推定するために使える代替のドライバーノードやパフォーマンスカウンターはありますか? Re: How to get NPU Temperature and utilization for NXP i.MX93 EVK こんにちは、@sonal-acldigital 返信が遅くなり申し訳ありません。最近、ひどいウイルス性の風邪にかかり、しばらくの間高熱が続きました。今日やっと熱が下がった。 1.GPU温度を読み取る専用の経路はありません。 2. はい、/sys/kernel/debug/gc/loadによるGPU負荷監視が現在の方法です。 IMX93: NPU使用率は、プロファイリングを用いてご自身で計算する必要があります。 B.R
查看全文
I.MX95 LVDS 时钟输出无法更改 大家好, 问题1: 我正在内核 lf-6.12y 中开发单端口 LVDS 显示功能。我在 driver/gpu/drm/panel/panel-simple.c 中添加了自己的面板配置,但是当我测量时钟引脚时,时钟频率始终在 150Mhz 左右。但其他信号都正常。 但是,在 lf-6.18y 中,时钟可以正确输出,并且在双端口模式下,两个版本的时钟切换也都可以。这是已知问题还是我的操作失误?由于某些原因,我希望能在lf-6.12y版本中解决这个问题。 以下是我的设置 panel-simple.c: static const struct display_timing lt9211_test_timing = { 像素时钟= { 35916000, 35916000, 35916000 }, .hactive= { 280, 280, 280 }, .hfront_porch= { 40, 40, 40, }, .hback_porch= { 60, 60, 60 }, .hsync_len= { 30, 30, 30 }, .vactive= { 1424, 1424, 1424 }, .vfront_porch= { 15, 15, 15 }, .vback_porch= { 17, 17, 17}, .vsync_len= { 4, 4, 4 }, .flags= DISPLAY_FLAGS_DE_HIGH, }; static const struct panel_desc lt9211_test = { 时间= &lt9211_test_timing, .bpc= 8, .num_timings= 1, 。尺寸= { 。宽度= 292, 。高度= 111, }, .bus_format= MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA, .bus_flags= DRM_BUS_FLAG_DE_HIGH, .连接器类型= DRM_MODE_CONNECTOR_LVDS, }; 设备树中的 lvds 配置 &{/}{ lvds1_panel { //兼容 = "3ascreen,sa123hwv-l51"; 兼容 = "lt9211_test"; 背光 = <&lvds_backlight>; 状态 = "正常"; 港口 { panel_in: 端点 { 远程端点 = <&lvds1_out>; }; }; }; Q2: 在某些情况下,同一硬件中的数据通道和时钟之间的 LVDS 公共电压将无法对齐。或者某些信号缺失,例如 LVDS1 D3P 有信号但 D3N 没有信号。你知道这是为什么吗?某些程序会导致这种情况吗? Q3: 是否有任何配置可以改变LVDS时钟相位? 谢谢! Re: I.MX95 LVDS clock output can not be changed 问题1:这很可能是LF-6.12Y LVDS时钟驱动程序的一个已知限制/错误,而不是你的panel-simple.c文件的问题。时机把握失误。在单端口LVDS中,驱动/时钟路径很可能强制或四舍五入到大约148.5/150。MHz。由于 lf-6.18y 可以正常工作,实际的解决方法是将 lf-6.18y 的 LVDS/LDB 时钟更改向后移植到 lf-6.12y,或者修补 6.12y LVDS 驱动程序/PLL 时钟表,以允许使用您的 35.916 MHz 像素时钟。 git diff lf-6.12.y..lf-6.18.y -- \ drivers/gpu/drm/bridge/imx/imx95-ldb.c drivers/phy/freescale/phy-fsl-imx8mp-lvds.c drivers/clk/imx/clk-imx95-blk-ctl.c \ arch/arm64/boot/dts/freescale/imx95.dtsi \ arch/arm64/boot/dts/freescale/imx95-*-lvds* Q2:如果 LVDS 对中的一侧缺失,例如 D3P 有信号但 D3N 没有信号,这通常不是面板时序造成的。查看: LVDS通道启用:LVDS0/LVDS1不匹配 fsl,数据宽度 / fsl,数据映射 PHY 使能 连接器或PCB开路/短路 焊接问题 终止/探测方法 LVDS 输出引脚可能损坏 软件可能会导致错误的通道/线路/数据宽度设置,但差分对的一侧缺失强烈表明存在硬件、焊盘、布线、端接或测量问题。 Q3:对于 i.MX8MP LVDS,没有常规的设备树配置来改变 LVDS 时钟相位。改为修复时钟频率/时序/PHY设置。 Re: I.MX95 LVDS clock output can not be changed 太感谢了。 lvds补丁太有用了。
查看全文
MRF13750H AWR MODEL Hello, I am trying to import the MRF13750H transistor model into Cadence AWR Microwave Office using the official design files provided on your website. After downloading both the design kit and the transistor model an error is generated when attempting to open the model. I have attached a screenshot of the error message. Luis_V_0-1789581238483.pngLuis_V_0-1789581238483.pngLuis_V_0-1789581238483.png I have already contacted technical support at cadence. Their team attempted to download and open the model as well, and they confirmed that they encountered the exact same issue. Could you please verify these files and let me know how to resolve this? Best, Luis V. RF Re: MRF13750H AWR MODEL Hello Luis_V Good day! The error is due to compatibility issues. The model you are trying to install is quite old and was designed for earlier versions of AWR Design Environment. Currently, there are no plans to update it for newer versions of the software. If you need to use this model, the most practical solution is to install an older version of AWR, such as one from around 2015 (for example, AWR v11 or v12), which is compatible with this model. This should allow you to work without encountering the GetIAwrUserIO DLL error. We apologize for any inconvenience this may cause. I hope this information has helped you, please let me know if you need help with anything else. Have a great day and best of luck. Re: MRF13750H AWR MODEL Hello Rafa, I am reaching out to Cadence to see if they can provide an older version of AWR. In the meantime, could you connect me with the engineer who designed the MRF13750H-915MHz Board or someone who can help me gather some numbers? I have this product from NXP and we need to use it. Additionally, you mentioned earlier that you could open ADS/AWR on your end to view the tee-discontinuities, mitered bends, open-end effects, etc. Would you be able to send me a screenshot of the window so I can check the microstrip dimensions and characteristics? I would also appreciate if you could run a load-pull analysis to find the source and load impedance values while I wait on Cadence. Best, Luis Villanueva Re: MRF13750H AWR MODEL Hello Luis_V Good day! Since NXP has decided to ramp down operations in the RF area (for the moment), many of our colleagues from that department have left the company, meaning there are fewer people available. So, please let me know what questions you have, and I will try to answer them; if I can't, I will escalate the matter to get support from an AE, though I cannot share anyone's contact details with you. Thanks for your understanding. Have a great day and best of luck.
查看全文
RT1051: ENET IEEE1588 Timer Clock source Hi, In the RT1050 reference manual, I find the following: mastupristi_0-1789736651417.pngmastupristi_0-1789736651417.png I would like to know what the clock sources for the IEEE1588 timer can be. For example, can I choose a root clock derived from AUDIO_PLL? Which registers control the clock source of the IEEE1588 timer? best regards Max i.MXRT 105x
查看全文
RT1xxx ENET:写入 ATCOR 以更改循环值时,校正计数器是否会重置? 您好, 我想知道在写入 ATCOR 时,校正计数器(在 ENET 外设中)是否会重置。 或者,也许只有当 ATCOR 中的值发生变化时才会重置? 顺祝商祺! 最大值 i.MX RT102x i.MX RT105x
查看全文
RT1051:ENET IEEE1588 定时器时钟源 您好, 在 RT1050 参考 手册 中 , 我 发现了 以下内容 : mastupristi_0-1789736651417.pngmastupristi_0-1789736651417.png 我想知道IEEE1588定时器的时钟源有哪些。例如,我可以选择从 AUDIO_PLL 派生的根时钟吗? 哪些寄存器控制 IEEE1588 定时器的时钟源? 顺祝商祺! 最大值 i.MX RT105x
查看全文
How to get NPU Temperature and utilization for NXP i.MX93 EVK I am using i.MX93 EVK and want to monitor the Ethos-U NPU temperature & utilization(load) at runtime how can I get this data ? The agenda is to monitor the HW-parameters during the inference of AI-models. I could monitor the below parameters using i.MX8MPlus I want to achieve the similar for i.MX93. 8MPlus RAM=$(free -m | awk '/Mem:/ {print $3}') CPU_LOAD=$(vmstat 1 2 | tail -1 | awk '{print 100 - $15}') CPU_TEMP=$(awk '{print $1/1000}' /sys/class/thermal/thermal_zone0/temp 2>/dev/null || echo "N/A") GPU_TEMP=$(awk '{print $1/1000}' /sys/class/thermal/thermal_zone1/temp 2>/dev/null || echo "${CPU_TEMP}") GPU_LOAD=$(cat /sys/kernel/debug/gc/load 2>/dev/null | awk '/load/ {gsub("%","",$3); if (max=="" || $3>max) max=$3} END {if (max!="") print max "%"; else print "N/A"}') I.mx93 RAM=$(free -m | awk '/Mem:/ {print $3}') CPU_LOAD=$(vmstat 1 2 | tail -1 | awk '{print 100 - $15}') CPU_TEMP=$(awk '{print $1/1000}' /sys/class/thermal/thermal_zone0/temp) How can I monitor the GPU_LOAD & GPU_TEMP for i.MX93 npu(ethos-u) ? Linux Re: How to get NPU Temperature and utilization for NXP i.MX93 EVK Hi @sonal-acldigital  Neither the i.MX 8M Plus nor the i.MX 93 offers a method to monitor NPU temperature in real time. - imx8MP, thermal_zone0 represents the cpu-thermal temperature ,thermal_zone1 represents the soc-thermal temperature. - imx93, thermal_zone0 represents the cpu-thermal temperature. - NPU, There is no such tool like nputop. For information on performance tuning, please refer to Section 7.1.2, "Profiling for Hardware Accelerators," in the ML User Guide. B.R Re: How to get NPU Temperature and utilization for NXP i.MX93 EVK @pengyong_zhang Thanks for clarifying the thermal zones for the i.MX 8M Plus and i.MX 93. Could you please clarify the following: i.MX8MPLUS 1. GPU Temperature: Is there a dedicated system path (like /sys/class/thermal/thermal_zoneX/temp) to read individual GPU temperatures, or is it covered solely under the soc-thermal zone (thermal_zone1)? 2. GPU Load: Is reading /sys/kernel/debug/gc/load the standard method for checking GPU load, or is the process detailed in Section 7.1.2 of the ML User Guide required for this as well? i.MX93: Since there is no native tool (like nputop) to monitor NPU load and temperature, we would like to ask: Is it valid to derive relative NPU utilization by measuring the reduction in CPU load when offloading inference execution to the NPU vs. running on the CPU alone? If this method isn't recommended, is there any alternative driver node or performance counter we can use to estimate NPU activity during an inference run? Re: How to get NPU Temperature and utilization for NXP i.MX93 EVK Hi @sonal-acldigital  Sorry for the late reply. I recently had a severe viral cold and had a high fever for a while. The fever just broke today. 1. There is no dedicated path to read the GPU temperature. 2. Yes, GPU load monitoring via /sys/kernel/debug/gc/load is the current method. IMX93: You need to calculate the NPU utilization yourself using profiling. B.R
查看全文
如何获取 NXP i.MX93 EVK 的 NPU 温度和利用率 我正在使用 i.MX93 EVK,想要监控 Ethos-U NPU 在运行时的温度和利用率(负载),请问如何获取这些数据? 本次议程旨在监测人工智能模型推理过程中的硬件参数。 我可以使用 i.MX8MPlus 监测以下参数,我想在 i.MX93 中实现类似的功能。 8MPlus RAM=$(free -m | awk '/Mem:/ {print $3}') CPU_LOAD=$(vmstat 1 2 | tail -1 | awk '{print 100 - $15}') CPU_TEMP=$(awk '{print $1/1000}' /sys/class/thermal/thermal_zone0/temp 2>/dev/null || echo "N/A") GPU_TEMP=$(awk '{print $1/1000}' /sys/class/thermal/thermal_zone1/temp 2>/dev/null || echo "${CPU_TEMP}") GPU_LOAD=$(cat /sys/kernel/debug/gc/load 2>/dev/null | awk '/load/ {gsub("%", "$3"); if (max== || $3>max) max=$3} END {if (max!=) print max "%"; else print "N/A"}') i.MX 93 RAM=$(free -m | awk '/Mem:/ {print $3}') CPU_LOAD=$(vmstat 1 2 | tail -1 | awk '{print 100 - $15}') CPU_TEMP=$(awk '{print $1/1000}' /sys/class/thermal/thermal_zone0/temp) 如何监测 i.MX93 npu(ethos-u) 的 GPU_LOAD 和 GPU_TEMP? Linux Re: How to get NPU Temperature and utilization for NXP i.MX93 EVK 你好@sonal-acldigital i.MX 8M Plus 和 i.MX 93 都没有提供实时监测 NPU 温度的方法。 - imx8MP,thermal_zone0 表示 CPU 温度,thermal_zone1 表示 SoC 温度。 - imx93,thermal_zone0 表示 CPU 温度。 - NPU,没有像 nputop 这样的工具。 有关性能调优的信息,请参阅第 7.1.2 节。《机器学习用户指南》中的“硬件加速器性能分析”。 B.R Re: How to get NPU Temperature and utilization for NXP i.MX93 EVK @pengyong_zhang感谢您澄清 i.MX 8M Plus 和 i.MX 93 的热区划分。请您澄清以下问题: i.MX8MPLUS 1. GPU 温度:是否有专门的系统路径(如 /sys/class/thermal/thermal_zoneX/temp)来读取单个 GPU 温度,还是仅包含在 soc-thermal 区域(thermal_zone1)中? 2. GPU 负载:读取 /sys/kernel/debug/gc/load 是检查 GPU 负载的标准方法吗?还是也需要按照 ML 用户指南第 7.1.2 节中详述的过程进行检查? i.MX93: 由于没有像 nputop 这样的原生工具来监测 NPU 负载和温度,我们想问:将推理执行卸载到 NPU 与单独在 CPU 上运行相比,通过测量 CPU 负载的减少量来推导出相对 NPU 利用率是否有效? 如果这种方法不推荐,是否有其他驱动节点或性能计数器可以用来估算推理运行期间的 NPU 活动? Re: How to get NPU Temperature and utilization for NXP i.MX93 EVK 你好@sonal-acldigital 抱歉回复晚了。我前段时间得了重感冒,还持续高烧了一段时间。今天刚退烧。 1.没有专用的路径来读取GPU温度。 2. 是的,目前通过 /sys/kernel/debug/gc/load 进行 GPU 负载监控的方法就是如此。 IMX93: 您需要使用性能分析自行计算 NPU 利用率。 B.R
查看全文
I.MX95 LVDSクロック出力は変更できません こんにちは、みんな、 Q1: カーネルのlf-6.12yでシングルポートのLVDSディスプレイを作っています。ドライバ/GPU/drm/panel/panel-simple.cで自分でパネル設定を追加しましたが、クロックピンを測定しているときはいつも150MHz前後でした。しかし、他の信号は正常に機能していた。 しかし、lf-6.18yではクロック出力は正しくでき、デュアルポートモードではクロック変更も両バージョンで問題ありません。これは既知の問題でしょうか、それとも私のミスでしょうか?なぜなら、いくつかの理由でこの問題をlf-6.12yで解決できればと思っているからです。 以下は私の設定です panel-simple.c: static const struct display_timing lt9211_test_timing = { .pixelclock= { 35916000, 35916000, 35916000 }, .hactive= { 280, 280, 280 }, .hfront_porch= { 40, 40, 40, }, .hback_porch= { 60, 60, 60 }, .hsync_len= { 30, 30, 30 }, .vactive= { 1424, 1424, 1424 }, .vfront_porch= { 15, 15, 15 }, .vback_porch= { 17, 17, 17}, .vsync_len= { 4, 4, 4 }, .フラグ= DISPLAY_FLAGS_DE_HIGH、 }; static const struct panel_desc lt9211_test = { タイミング= &lt9211_test_timing、 .bpc= 8、 .num_timings= 1、 。サイズ= { 。幅= 292、 。身長= 111、 }、 .bus_format= MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA、 .bus_flags= DRM_BUS_FLAG_DE_HIGH、 .connector_type= DRM_MODE_CONNECTOR_LVDS、 }; デバイスツリー内の私の lvds 設定 &{/}{ lvds1_panel { //compatible = "3ascreen,sa123hwv-l51"; compatible = "lt9211_test"; バックライト = <&lvds_backlight>; ステータス = "正常"; ポート { panel_in: エンドポイント { リモートエンドポイント = <&lvds1_out>; }; }; }; Q2: 特定の条件下では、同じハードウェア内でデータレーンとクロック間でLVDSの共通電圧が整列しないこともあります。あるいは、LVDS1のD3Pには信号があるがD3Nには信号がないなど、何らかの信号が欠落している場合もある。なぜこうなったのか、何かアイデアはありますか?一部のプログラムがこれを引き起こす可能性はありますか? Q3: どんな設定でもLVDSのクロック位相をシフトできますか? よろしくお願いします。 Re: I.MX95 LVDS clock output can not be changed Q1: これはおそらくあなたのパネルではなく、既知のlf-6.12y LVDSクロックドライバーの制限やバグである可能性が高いです。タイミングのミス。シングルポートのLVDSでは、ドライバ/クロック経路が約148.5/150に強制または丸められている可能性が高いですMHzlf-6.18yが動作するため、実用的な解決策はLVDS/LDBクロックの変更をlf-6.18yからlf-6.12yにバックポートするか、6.12y LVDSドライバー/PLLクロックテーブルをパッチして35.916 MHzピクセルクロックを可能にすることです。 git diff lf-6.12.y..lf-6.18.y -- \ ドライバ/GPU/DRM/ブリッジ/IMX/IMX95-LDB.C ドライバ/phy/freescale/phy-fsl-imx8mp-lvds.c ドライバ/clk/imx/clk-imx95-blk-ctl.c \ arch/arm64/boot/dts/freescale/imx95.dtsi \ arch/arm64/boot/dts/freescale/imx95-*-lvds* Q2: 例えばD3Pには信号があるのにD3Nに信号がない場合、通常はパネルタイミングが原因ではありません。チェック: LVDSチャネルのイネーブルメント:LVDS0/LVDS1のミスマッチ fsl、データ幅 / fsl、データマッピング PHYイネーブルメント コネクタまたは基板の断線/短絡 はんだ付けの問題 終端/プロービング方法 LVDS出力ピンが損傷している可能性があります ソフトウェアが誤ったチャネル/レーン/データ幅設定を引き起こすことがありますが、差動ペアの片側が欠けているとハードウェア、パッド、ルーティング、終端、または測定の問題を強く示唆しています。 Q3: i.MX8MP LVDSの場合、LVDSのクロック位相をシフトするための通常のデバイスツリー構成はありません。クロック周波数、タイミング、PHY設定を修正してください。 Re: I.MX95 LVDS clock output can not be changed 本当にありがとうございます。 LVDSパッチはとても役に立ちます。
查看全文
PN7160 NXP-NCI MCUxpresso for VS Code Example Project for MCXA156 Introduction This document provides a guide on how to integrate the FRDM-MCXA156 as a host for the PN7160 using the examples provided in the “PN7160 NXP-NCI MCUXpresso Example Project” package. The hardware required to follow this guide is: FRDM-MCXA156 development board as host MCU. OM27160A1/OM27160B1 (PN7160 EVK) as the NFC controller. MCUxpresso for VS code extension Software setup. PN7160 NXP-NCI MCUXpresso Example Project version: 1.2 MCXN947 SDK version: 26.06 PN7160 version: 12.50.11. Hardware connections. When using OM27160B1 (SPI Host Interface): The FRDM-MCXA156 schematic document is available on this page. In the case of SPI connections, to use PN7160 directly with the Arduino headers a rework is needed for the FRDM because SDO(MOSI) and SS (Chip select) are not connected as default (as shown in the next figure). You should move R59 and R60 from pad 2 to pad 3 to enable these connections. Habib_MS_0-1781809327131.pngHabib_MS_0-1781809327131.png Note: You can connect the SPI pins available in Mikro bus header with jumpers, but in this example, the signals are routed through the pins enabled by the rework configuration. Once clarified this, these are the pins used in this example. Name PORT I2C0_SDA P0_16 I2C0_SCL P0_17 LPSPI1_SDI P2_16 LPSPI1_SDO P2_13 LPSPI1_SCK P2_12 LPSPI1_SS P2_6 IRQ P1_15 VEN P1_14 REQ P3_16   Software Changes This section describes the software changes required to run an “NXP-NCI2.0” example with the MCXA156, 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 PN7160. To begin the integration, we first need to import a hello_world project from the FRDM-MCXA156 SDK (v26.06.00) into MCUXpresso IDE for VS Code. For this purpose, download and install the FRDM-MCXA156 repository (version 26.06) using the extension available in the Quickstart panel by selecting Import Repository. For more information about this process, you can consult the corresponding guide. Importing NCI2.0 examples Download the “PN7160 NXP-NCI MCUXpresso Example Project” zip from the product page and extract in a known folder. This will be useful for later use.  Importing base project 1. In the Quick Start panel click on “Import Example from Repository” in VS code. Habib_MS_1-1781809359168.pngHabib_MS_1-1781809359168.png 2. Select “FRDM-MCXA156” in board setting.   Habib_MS_1-1785802139304.pngHabib_MS_1-1785802139304.png 3. In the template will search for the “hello_world” example, select Freestanding Applications, chose the location and click on “import”. Habib_MS_0-1785802110562.pngHabib_MS_0-1785802110562.png Importing SDK drivers Once the project is added to the workspace we will need to add the required drivers, which are the SPI driver in case the OM27160B1HN is being used, or the I2C driver if the OM27160A1HN is being used. For this we need to add the following code in the prj.cfg file. Habib_MS_0-1781809845396.pngHabib_MS_0-1781809845396.png Spoiler (Highlight to read) CONFIG_MCUX_COMPONENT_driver.lpi2c=y CONFIG_MCUX_COMPONENT_driver.lpspi=y CONFIG_MCUX_COMPONENT_driver.lpi2c=y CONFIG_MCUX_COMPONENT_driver.lpspi=y Add the example source code to the newly created MCXA156 project Delete the hello_world.c of the project files folder of the MCXA156 project. From the “NXP-NCI2.0_iMXRT1170_examples” extracted just drag and drop in the project files folder the following files and folders. Habib_MS_0-1781809900813.pngHabib_MS_0-1781809900813.png Habib_MS_1-1781809927413.pngHabib_MS_1-1781809927413.png When you drag and drop a file into VS code a window will appear asking whether you want to link the file or copy it. Please select “Copy files.” Habib_MS_2-1781809983781.pngHabib_MS_2-1781809983781.png The project folder should look like this: Habib_MS_3-1781810001861.pngHabib_MS_3-1781810001861.png After dragging and dropping all the files, the CMakeLists.txt file is automatically updated to include all the copied .c files. An example of this is shown below: Habib_MS_4-1781810063910.pngHabib_MS_4-1781810063910.png However, .h files are not automatically linked, so they must be added manually. Please copy and paste the following includes into the CMakeLists.txt file: Habib_MS_5-1781810096008.pngHabib_MS_5-1781810096008.png Spoiler (Highlight to read) mcux_add_include( BASE_PATH ${CMAKE_CURRENT_LIST_DIR} INCLUDES tool TML NfcLibrary/inc NfcLibrary/NdefLibrary/inc INCLUDES NfcLibrary/NxpNci20/inc . ) mcux_add_include( BASE_PATH ${CMAKE_CURRENT_LIST_DIR} INCLUDES tool TML NfcLibrary/inc NfcLibrary/NdefLibrary/inc INCLUDES NfcLibrary/NxpNci20/inc . ) Preprocessor Interface macro Depending on the interface to be used to communicate with the PN7160, a preprocessor macro must be defined in the CMakelist.txt BOARD_NXPNCI_INTERFACE_SPI (For using SPI with OM27160B1) BOARD_NXPNCI_INTERFACE_I2C (For using I2C with OM27160A1) Additionally, it is necessary to add the macro called REMOVE_P2P_SUPPORT. Please make sure that this Macro is included. Spoiler (Highlight to read) mcux_add_macro( CC "BOARD_NXPNCI_INTERFACE_I2C=1\ REMOVE_P2P_SUPPORT=1") mcux_add_macro( CC "BOARD_NXPNCI_INTERFACE_I2C=1\ REMOVE_P2P_SUPPORT=1") Note: The following sections are exemplified using the SPI interface (BOARD_NXPNCI_INTERFACE_SPI macro). After making the modifications described below, the interface used by the example can be changed simply by setting the macro to BOARD_NXPNCI_INTERFACE_I2C. Board definitions In the board.h file we will add the following definitions in order to refer to the different peripherals and clocks to be used, you can find this file in the following path: {PrjRootDirPath}\ frdmmcxa156\frdmmcxa156\board.h Habib_MS_1-1781810404448.pngHabib_MS_1-1781810404448.png Spoiler (Highlight to read) #ifdef BOARD_NXPNCI_INTERFACE_I2C #define BOARD_NXPNCI_I2C_CLOCK (CLOCK_GetLpi2cClkFreq(0U)) #define BOARD_NXPNCI_I2C_INSTANCE (LPI2C0) #define BOARD_NXPNCI_I2C_BAUDRATE (100000) #define BOARD_NXPNCI_I2C_ADDR (0x28) #endif #ifdef BOARD_NXPNCI_INTERFACE_SPI #define BOARD_NXPNCI_SPI_CLOCK (CLOCK_GetLpspiClkFreq(1U)) #define BOARD_NXPNCI_SPI_INSTANCE (LPSPI1) #define BOARD_NXPNCI_SPI_BAUDRATE (400000) #endif #define BOARD_NXPNCI_IRQ_PORT (GPIO1) #define BOARD_NXPNCI_VEN_PORT (GPIO1) #define BOARD_NXPNCI_DWL_PORT (GPIO3) #define BOARD_NXPNCI_IRQ_PIN (15U) #define BOARD_NXPNCI_VEN_PIN (14U) #define BOARD_NXPNCI_DWL_PIN (16U) #ifdef BOARD_NXPNCI_INTERFACE_I2C #define BOARD_NXPNCI_I2C_CLOCK (CLOCK_GetLpi2cClkFreq(0U)) #define BOARD_NXPNCI_I2C_INSTANCE (LPI2C0) #define BOARD_NXPNCI_I2C_BAUDRATE (100000) #define BOARD_NXPNCI_I2C_ADDR (0x28) #endif #ifdef BOARD_NXPNCI_INTERFACE_SPI #define BOARD_NXPNCI_SPI_CLOCK (CLOCK_GetLpspiClkFreq(1U)) #define BOARD_NXPNCI_SPI_INSTANCE (LPSPI1) #define BOARD_NXPNCI_SPI_BAUDRATE (400000) #endif #define BOARD_NXPNCI_IRQ_PORT (GPIO1) #define BOARD_NXPNCI_VEN_PORT (GPIO1) #define BOARD_NXPNCI_DWL_PORT (GPIO3) #define BOARD_NXPNCI_IRQ_PIN (15U) #define BOARD_NXPNCI_VEN_PIN (14U) #define BOARD_NXPNCI_DWL_PIN (16U) Code modifications to the TML component In the source tml.c source file the following modifications are made, you can find this file in the following path: {{PrjRootDirPath }>frdmmcxa156_hello_world\TML Habib_MS_2-1781810455046.pngHabib_MS_2-1781810455046.png Spoiler (Highlight to read) 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; } 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; } Habib_MS_3-1781810501153.pngHabib_MS_3-1781810501153.png Spoiler (Highlight to read) static void INTF_INIT(void) { lpspi_master_config_t masterConfig; LPSPI_MasterGetDefaultConfig(&masterConfig); masterConfig.baudRate = BOARD_NXPNCI_SPI_BAUDRATE; masterConfig.whichPcs = (lpspi_which_pcs_t) kLPSPI_Pcs1; masterXfer.configFlags = kLPSPI_MasterPcs1 | kLPSPI_MasterPcsContinuous | kLPSPI_MasterByteSwap; LPSPI_MasterInit(BOARD_NXPNCI_SPI_INSTANCE, &masterConfig, BOARD_NXPNCI_SPI_CLOCK); } static void INTF_INIT(void) { lpspi_master_config_t masterConfig; LPSPI_MasterGetDefaultConfig(&masterConfig); masterConfig.baudRate = BOARD_NXPNCI_SPI_BAUDRATE; masterConfig.whichPcs = (lpspi_which_pcs_t) kLPSPI_Pcs1; masterXfer.configFlags = kLPSPI_MasterPcs1 | kLPSPI_MasterPcsContinuous | kLPSPI_MasterByteSwap; LPSPI_MasterInit(BOARD_NXPNCI_SPI_INSTANCE, &masterConfig, BOARD_NXPNCI_SPI_CLOCK); } Habib_MS_4-1781810544149.pngHabib_MS_4-1781810544149.png Spoiler (Highlight to read) 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_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; } Code modifications for ports, pins and clocks initialization In the file “hardware_init.c” in the board folder of the project, write the following function as shown, in order to add port and clock peripheral initializations. Habib_MS_5-1781810589344.pngHabib_MS_5-1781810589344.png Spoiler (Highlight to read) /* * Copyright 2024 NXP * * SPDX-License-Identifier: BSD-3-Clause */ /*${header:start}*/ #include "pin_mux.h" #include "fsl_clock.h" #include "fsl_reset.h" #include "board.h" #include /*${header:end}*/ /*${function:start}*/ void BOARD_InitHardware(void) { CLOCK_SetClockDiv(kCLOCK_DivLPI2C0, 1u); CLOCK_AttachClk(kFRO12M_to_LPI2C0); CLOCK_SetClockDiv(kCLOCK_DivLPSPI1, 1u); CLOCK_AttachClk(kFRO12M_to_LPSPI1); BOARD_InitPins(); BOARD_InitBootClocks(); BOARD_InitDebugConsole(); } /*${function:end}*/ /* * Copyright 2024 NXP * * SPDX-License-Identifier: BSD-3-Clause */ /*${header:start}*/ #include "pin_mux.h" #include "fsl_clock.h" #include "fsl_reset.h" #include "board.h" #include /*${header:end}*/ /*${function:start}*/ void BOARD_InitHardware(void) { CLOCK_SetClockDiv(kCLOCK_DivLPI2C0, 1u); CLOCK_AttachClk(kFRO12M_to_LPI2C0); CLOCK_SetClockDiv(kCLOCK_DivLPSPI1, 1u); CLOCK_AttachClk(kFRO12M_to_LPSPI1); BOARD_InitPins(); BOARD_InitBootClocks(); BOARD_InitDebugConsole(); } /*${function:end}*/ In the pin_mux.c file modifies the function called BOARD_InitPins(); accordingly, this file can be seen in the following path: {PrjRootDirPath}\ frdmmcxa156\hello_world \pin_mux.c Spoiler (Highlight to read) void BOARD_InitPins(void) { CLOCK_EnableClock(kCLOCK_GateGPIO1); /* GPIO3: Peripheral clock is enabled */ CLOCK_EnableClock(kCLOCK_GateGPIO3); /* PORT0: Peripheral clock is enabled */ CLOCK_EnableClock(kCLOCK_GatePORT0); CLOCK_EnableClock(kCLOCK_GatePORT1); CLOCK_EnableClock(kCLOCK_GatePORT2); CLOCK_EnableClock(kCLOCK_GatePORT3); /* GPIO1 peripheral is released from reset */ RESET_ReleasePeripheralReset(kGPIO1_RST_SHIFT_RSTn); /* GPIO3 peripheral is released from reset */ RESET_ReleasePeripheralReset(kGPIO3_RST_SHIFT_RSTn); RESET_ReleasePeripheralReset(kLPUART0_RST_SHIFT_RSTn); RESET_ReleasePeripheralReset(kPORT0_RST_SHIFT_RSTn); RESET_ReleasePeripheralReset(kLPSPI0_RST_SHIFT_RSTn); RESET_ReleasePeripheralReset(kPORT1_RST_SHIFT_RSTn); RESET_ReleasePeripheralReset(kLPSPI1_RST_SHIFT_RSTn); RESET_ReleasePeripheralReset(kPORT3_RST_SHIFT_RSTn); RESET_ReleasePeripheralReset(kPORT2_RST_SHIFT_RSTn); const port_pin_config_t port0_2_pin78_config = {/* Internal pull-up resistor is enabled */ kPORT_PullUp, /* 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, /* Normal drive strength is configured */ kPORT_NormalDriveStrength, /* Pin is configured as LPUART0_RXD */ kPORT_MuxAlt2, /* Digital input enabled */ kPORT_InputBufferEnable, /* Digital input is not inverted */ kPORT_InputNormal, /* Pin Control Register fields [15:0] are not locked */ kPORT_UnlockRegister}; /* PORT0_2 (pin 78) is configured as LPUART0_RXD */ PORT_SetPinConfig(PORT0, 2U, &port0_2_pin78_config); const port_pin_config_t port0_3_pin79_config = {/* Internal pull-up resistor is enabled */ kPORT_PullUp, /* 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, /* Normal drive strength is configured */ kPORT_NormalDriveStrength, /* Pin is configured as LPUART0_TXD */ kPORT_MuxAlt2, /* Digital input enabled */ kPORT_InputBufferEnable, /* Digital input is not inverted */ kPORT_InputNormal, /* Pin Control Register fields [15:0] are not locked */ kPORT_UnlockRegister}; /* PORT0_3 (pin 79) is configured as LPUART0_TXD */ PORT_SetPinConfig(PORT0, 3U, &port0_3_pin79_config); const port_pin_config_t port2_13_pin35_config = { kPORT_PullDisable, kPORT_LowPullResistor, kPORT_FastSlewRate, kPORT_PassiveFilterDisable, kPORT_OpenDrainDisable, kPORT_LowDriveStrength, kPORT_NormalDriveStrength, /* Pin is configured as LPSPI1_SDO */ kPORT_MuxAlt2, kPORT_InputBufferEnable, kPORT_InputNormal, kPORT_UnlockRegister}; PORT_SetPinConfig(PORT2, 13U, &port2_13_pin35_config); const port_pin_config_t port2_12_pin34_config = { kPORT_PullDisable, kPORT_LowPullResistor, kPORT_FastSlewRate, kPORT_PassiveFilterDisable, kPORT_OpenDrainDisable, kPORT_LowDriveStrength, kPORT_NormalDriveStrength, /* Pin is configured as LPSPI1_SCK */ kPORT_MuxAlt2, kPORT_InputBufferEnable, kPORT_InputNormal, kPORT_UnlockRegister}; PORT_SetPinConfig(PORT2, 12U, &port2_12_pin34_config); const port_pin_config_t port2_16_pin37_config = { kPORT_PullDisable, kPORT_LowPullResistor, kPORT_FastSlewRate, kPORT_PassiveFilterDisable, kPORT_OpenDrainDisable, kPORT_LowDriveStrength, kPORT_NormalDriveStrength, /* Pin is configured as LPSPI1_SDI */ kPORT_MuxAlt2, kPORT_InputBufferEnable, kPORT_InputNormal, kPORT_UnlockRegister}; PORT_SetPinConfig(PORT2, 16U, &port2_16_pin37_config); const port_pin_config_t port2_6_pin28_config = { kPORT_PullDisable, kPORT_LowPullResistor, kPORT_FastSlewRate, kPORT_PassiveFilterDisable, kPORT_OpenDrainDisable, kPORT_LowDriveStrength, kPORT_NormalDriveStrength, /* Pin is configured as LPSPI1_PCS0 */ kPORT_MuxAlt2, kPORT_InputBufferEnable, kPORT_InputNormal, kPORT_UnlockRegister}; PORT_SetPinConfig(PORT2, 6U, &port2_6_pin28_config); const port_pin_config_t port1_15_pin8_config = { kPORT_PullDisable, kPORT_LowPullResistor, kPORT_FastSlewRate, kPORT_PassiveFilterDisable, kPORT_OpenDrainDisable, kPORT_LowDriveStrength, kPORT_NormalDriveStrength, /* Pin is configured as GPIO1 15 */ kPORT_MuxAlt0, kPORT_InputBufferEnable, kPORT_InputNormal, kPORT_UnlockRegister}; PORT_SetPinConfig(PORT1, 15U, &port1_15_pin8_config); const port_pin_config_t port1_14_pin7_config = { kPORT_PullUp, kPORT_LowPullResistor, kPORT_FastSlewRate, kPORT_PassiveFilterDisable, kPORT_OpenDrainDisable, kPORT_LowDriveStrength, kPORT_NormalDriveStrength, /* Pin is configured as GPIO1 14 */ kPORT_MuxAlt0, kPORT_InputBufferEnable, kPORT_InputNormal, kPORT_UnlockRegister}; PORT_SetPinConfig(PORT1, 14U, &port1_14_pin7_config); const port_pin_config_t port3_16_pin59_config = { kPORT_PullUp, kPORT_LowPullResistor, kPORT_FastSlewRate, kPORT_PassiveFilterDisable, kPORT_OpenDrainDisable, kPORT_LowDriveStrength, kPORT_NormalDriveStrength, /* Pin is configured as GPIO3 16 */ kPORT_MuxAlt0, kPORT_InputBufferEnable, kPORT_InputNormal, kPORT_UnlockRegister}; PORT_SetPinConfig(PORT3, 16U, &port3_16_pin59_config); const port_pin_config_t port0_16_pin83_config = { kPORT_PullDisable, kPORT_LowPullResistor, kPORT_FastSlewRate, kPORT_PassiveFilterDisable, kPORT_OpenDrainDisable, kPORT_LowDriveStrength, kPORT_NormalDriveStrength, /* Pin is configured as LPI2C0 SDA */ kPORT_MuxAlt2, kPORT_InputBufferEnable, kPORT_InputNormal, kPORT_UnlockRegister}; PORT_SetPinConfig(PORT0, 16U, &port0_16_pin83_config); const port_pin_config_t port0_17_pin84_config = { kPORT_PullDisable, kPORT_LowPullResistor, kPORT_FastSlewRate, kPORT_PassiveFilterDisable, kPORT_OpenDrainDisable, kPORT_LowDriveStrength, kPORT_NormalDriveStrength, /* Pin is configured as LPI2C0 SCL */ kPORT_MuxAlt2, kPORT_InputBufferEnable, kPORT_InputNormal, kPORT_UnlockRegister}; PORT_SetPinConfig(PORT0, 17U, &port0_17_pin84_config); } void BOARD_InitPins(void) { CLOCK_EnableClock(kCLOCK_GateGPIO1); /* GPIO3: Peripheral clock is enabled */ CLOCK_EnableClock(kCLOCK_GateGPIO3); /* PORT0: Peripheral clock is enabled */ CLOCK_EnableClock(kCLOCK_GatePORT0); CLOCK_EnableClock(kCLOCK_GatePORT1); CLOCK_EnableClock(kCLOCK_GatePORT2); CLOCK_EnableClock(kCLOCK_GatePORT3); /* GPIO1 peripheral is released from reset */ RESET_ReleasePeripheralReset(kGPIO1_RST_SHIFT_RSTn); /* GPIO3 peripheral is released from reset */ RESET_ReleasePeripheralReset(kGPIO3_RST_SHIFT_RSTn); RESET_ReleasePeripheralReset(kLPUART0_RST_SHIFT_RSTn); RESET_ReleasePeripheralReset(kPORT0_RST_SHIFT_RSTn); RESET_ReleasePeripheralReset(kLPSPI0_RST_SHIFT_RSTn); RESET_ReleasePeripheralReset(kPORT1_RST_SHIFT_RSTn); RESET_ReleasePeripheralReset(kLPSPI1_RST_SHIFT_RSTn); RESET_ReleasePeripheralReset(kPORT3_RST_SHIFT_RSTn); RESET_ReleasePeripheralReset(kPORT2_RST_SHIFT_RSTn); const port_pin_config_t port0_2_pin78_config = {/* Internal pull-up resistor is enabled */ kPORT_PullUp, /* 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, /* Normal drive strength is configured */ kPORT_NormalDriveStrength, /* Pin is configured as LPUART0_RXD */ kPORT_MuxAlt2, /* Digital input enabled */ kPORT_InputBufferEnable, /* Digital input is not inverted */ kPORT_InputNormal, /* Pin Control Register fields [15:0] are not locked */ kPORT_UnlockRegister}; /* PORT0_2 (pin 78) is configured as LPUART0_RXD */ PORT_SetPinConfig(PORT0, 2U, &port0_2_pin78_config); const port_pin_config_t port0_3_pin79_config = {/* Internal pull-up resistor is enabled */ kPORT_PullUp, /* 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, /* Normal drive strength is configured */ kPORT_NormalDriveStrength, /* Pin is configured as LPUART0_TXD */ kPORT_MuxAlt2, /* Digital input enabled */ kPORT_InputBufferEnable, /* Digital input is not inverted */ kPORT_InputNormal, /* Pin Control Register fields [15:0] are not locked */ kPORT_UnlockRegister}; /* PORT0_3 (pin 79) is configured as LPUART0_TXD */ PORT_SetPinConfig(PORT0, 3U, &port0_3_pin79_config); const port_pin_config_t port2_13_pin35_config = { kPORT_PullDisable, kPORT_LowPullResistor, kPORT_FastSlewRate, kPORT_PassiveFilterDisable, kPORT_OpenDrainDisable, kPORT_LowDriveStrength, kPORT_NormalDriveStrength, /* Pin is configured as LPSPI1_SDO */ kPORT_MuxAlt2, kPORT_InputBufferEnable, kPORT_InputNormal, kPORT_UnlockRegister}; PORT_SetPinConfig(PORT2, 13U, &port2_13_pin35_config); const port_pin_config_t port2_12_pin34_config = { kPORT_PullDisable, kPORT_LowPullResistor, kPORT_FastSlewRate, kPORT_PassiveFilterDisable, kPORT_OpenDrainDisable, kPORT_LowDriveStrength, kPORT_NormalDriveStrength, /* Pin is configured as LPSPI1_SCK */ kPORT_MuxAlt2, kPORT_InputBufferEnable, kPORT_InputNormal, kPORT_UnlockRegister}; PORT_SetPinConfig(PORT2, 12U, &port2_12_pin34_config); const port_pin_config_t port2_16_pin37_config = { kPORT_PullDisable, kPORT_LowPullResistor, kPORT_FastSlewRate, kPORT_PassiveFilterDisable, kPORT_OpenDrainDisable, kPORT_LowDriveStrength, kPORT_NormalDriveStrength, /* Pin is configured as LPSPI1_SDI */ kPORT_MuxAlt2, kPORT_InputBufferEnable, kPORT_InputNormal, kPORT_UnlockRegister}; PORT_SetPinConfig(PORT2, 16U, &port2_16_pin37_config); const port_pin_config_t port2_6_pin28_config = { kPORT_PullDisable, kPORT_LowPullResistor, kPORT_FastSlewRate, kPORT_PassiveFilterDisable, kPORT_OpenDrainDisable, kPORT_LowDriveStrength, kPORT_NormalDriveStrength, /* Pin is configured as LPSPI1_PCS0 */ kPORT_MuxAlt2, kPORT_InputBufferEnable, kPORT_InputNormal, kPORT_UnlockRegister}; PORT_SetPinConfig(PORT2, 6U, &port2_6_pin28_config); const port_pin_config_t port1_15_pin8_config = { kPORT_PullDisable, kPORT_LowPullResistor, kPORT_FastSlewRate, kPORT_PassiveFilterDisable, kPORT_OpenDrainDisable, kPORT_LowDriveStrength, kPORT_NormalDriveStrength, /* Pin is configured as GPIO1 15 */ kPORT_MuxAlt0, kPORT_InputBufferEnable, kPORT_InputNormal, kPORT_UnlockRegister}; PORT_SetPinConfig(PORT1, 15U, &port1_15_pin8_config); const port_pin_config_t port1_14_pin7_config = { kPORT_PullUp, kPORT_LowPullResistor, kPORT_FastSlewRate, kPORT_PassiveFilterDisable, kPORT_OpenDrainDisable, kPORT_LowDriveStrength, kPORT_NormalDriveStrength, /* Pin is configured as GPIO1 14 */ kPORT_MuxAlt0, kPORT_InputBufferEnable, kPORT_InputNormal, kPORT_UnlockRegister}; PORT_SetPinConfig(PORT1, 14U, &port1_14_pin7_config); const port_pin_config_t port3_16_pin59_config = { kPORT_PullUp, kPORT_LowPullResistor, kPORT_FastSlewRate, kPORT_PassiveFilterDisable, kPORT_OpenDrainDisable, kPORT_LowDriveStrength, kPORT_NormalDriveStrength, /* Pin is configured as GPIO3 16 */ kPORT_MuxAlt0, kPORT_InputBufferEnable, kPORT_InputNormal, kPORT_UnlockRegister}; PORT_SetPinConfig(PORT3, 16U, &port3_16_pin59_config); const port_pin_config_t port0_16_pin83_config = { kPORT_PullDisable, kPORT_LowPullResistor, kPORT_FastSlewRate, kPORT_PassiveFilterDisable, kPORT_OpenDrainDisable, kPORT_LowDriveStrength, kPORT_NormalDriveStrength, /* Pin is configured as LPI2C0 SDA */ kPORT_MuxAlt2, kPORT_InputBufferEnable, kPORT_InputNormal, kPORT_UnlockRegister}; PORT_SetPinConfig(PORT0, 16U, &port0_16_pin83_config); const port_pin_config_t port0_17_pin84_config = { kPORT_PullDisable, kPORT_LowPullResistor, kPORT_FastSlewRate, kPORT_PassiveFilterDisable, kPORT_OpenDrainDisable, kPORT_LowDriveStrength, kPORT_NormalDriveStrength, /* Pin is configured as LPI2C0 SCL */ kPORT_MuxAlt2, kPORT_InputBufferEnable, kPORT_InputNormal, kPORT_UnlockRegister}; PORT_SetPinConfig(PORT0, 17U, &port0_17_pin84_config); } Configure the main.c as follows: Habib_MS_0-1781813861103.pngHabib_MS_0-1781813861103.png Spoiler (Highlight to read) #include #include #include "board.h" #include "app.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(); } #include #include #include "board.h" #include "app.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(); } Building and Debugging the example For building the example, please click on this button and if you followed this guide accordingly the project should compile without errors: Habib_MS_1-1781813991676.pngHabib_MS_1-1781813991676.png Habib_MS_2-1781813999778.pngHabib_MS_2-1781813999778.png Open a serial terminal such as Teraterm with the following settings: Habib_MS_3-1781814017721.pngHabib_MS_3-1781814017721.png  Start a debug session by clicking this button: Habib_MS_4-1781814064724.pngHabib_MS_4-1781814064724.png Once running, the example should look as follows: Habib_MS_5-1781814084057.pngHabib_MS_5-1781814084057.png  When tapping a card on the antenna, the card information will be shown: Habib_MS_6-1781814110924.pngHabib_MS_6-1781814110924.png NFC Controller Solutions
查看全文
NFC Reader Library Migration to FRDM-MCXN947 on VS code Introduction. This document provides a guide for using the PN5190 NFC frontend with the FRDM-MCXN947 development board and the NFC Reader Library in the MCUxpresso for VS code extension. 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 Hardware connections. The PNEV5190 comes with a Kinetis K82F as a host MCU to drive the PN5190 To enable SPI communication between the MCXN947 and the PN5190, the PNEV5190 board must be prepared as follows: Power up board correctly Enable external SPI pins Disable K82F interface with PN5190 Power up and jumper configuration To correctly power up the board.: – 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-1782499687907.pngHabib_MS_0-1782499687907.png Routing NFC module communication pins to JP1 To enable the pins on JP1 for communication, we must enable bus switch U10 and disable bus switch U12 in the NFC Host Interface. These switches enable or disable the connections from K82 to PN5190 SPI pins, and expose the SPI interface to an external host. Remove short on R5 to disable communication routing to K82F. Place short on R7 to enable communication routing to JP1 pins. Habib_MS_1-1782499777420.pngHabib_MS_1-1782499777420.png For FRDM-MCXN947 side, no modifications are necessary.  The pins used are available in Header J1 and J2. Which are shown in the following table.     Name MCXN947 PN5190 SCK J2.12 JP1.1 MOSI J2.8 JP1.2 MISO J2.10 JP1.3 SSEL J2.6 JP1.4 IRQ J1.16 JP1.5 RESET J2.2 JP6.1 GND J2.14 JP1.10 SUCCESS J2.17* FAIL J2.15* DWL J2.13* * Pins that need to be configured for library compatibility but are not used and do not need to be connected. Software Changes This section describes the software changes required to run the NfcrdlibEx1_DiscoveryLoop example from the NFC Reader Library. This example implements a detection loop that displays information about any tag detected by the PN5190 in a terminal, such as the UID, SAK, and Product Type for MIFARE-based cards. Please download the NFC Reader Library for the PN5190 from NFC Reader Library | NXP Semiconductors. To begin the integration, we first need to import a hello_world project from the FRDM-MCXN947 SDK (v26.06.00) into MCUXpresso IDE for VS Code. For this purpose, download and install the FRDM-MCXN947 repository (version 26.06) using the extension available in the Quickstart panel by selecting Import Repository. For more information about this process, please refer to the corresponding user guide. Importing NFC Reader library. Download the “NFC Reader Library” zip from the product page and extract in a known folder. This will be useful for later use.  If available, please use the latest version of the NFC Reader Library. Importing base project 1. In the Quick Start panel click on “Import Example from Repository” in VS code. Habib_MS_0-1782500337538.pngHabib_MS_0-1782500337538.png 2. Select “FRDM-MCXN947” in board setting. Habib_MS_0-1785876833645.pngHabib_MS_0-1785876833645.png 3. In the template will search for the “freertos_hello_cm33_core0” example, select Freestanding Application, chose the location and click on “import”. Habib_MS_1-1785876872899.pngHabib_MS_1-1785876872899.png Importing SDK drivers Once the project is added to the workspace we will need to add the required drivers, which are SPI, CTIMER and CMSIS drivers. For this we need to add the following code in the prj.cfg file. Habib_MS_3-1782500385724.pngHabib_MS_3-1782500385724.png Spoiler (Highlight to read) CONFIG_MCUX_COMPONENT_driver.lpflexcomm_lpspi=y CONFIG_MCUX_COMPONENT_driver.ctimer=y CONFIG_MCUX_COMPONENT_driver.CMSIS=y CONFIG_MCUX_COMPONENT_driver.lpflexcomm_lpspi=y CONFIG_MCUX_COMPONENT_driver.ctimer=y CONFIG_MCUX_COMPONENT_driver.CMSIS=y Add the source code Discovery Loop Example Firstly, delete the file freertos_hello.c created by the project. From the “NxpNfcRdLib_PN5190_v07.16.00_PUB” extracted, find and drag and drop the following files on in the project files folder: NfcrdlibEx1_EmvcoProfile.c, phApp_Helper.c, phApp_Init.c, phApp_PN5190_Init.c. You can find these files in the following path: {NxpNfcRdLibRoot} \Examples\NfcrdlibEx1_DiscoveryLoop\src Habib_MS_2-1782504550792.pngHabib_MS_2-1782504550792.png When you drag and drop a file into VS code a window will appear asking whether you want to link the file or copy it. Please select “Copy files.” Habib_MS_3-1782504569947.pngHabib_MS_3-1782504569947.png After dragging and dropping any file, the CMakeLists.txt file is automatically updated to include all the copied .c files. If you selected all these files, the generated code will appear as follows: Habib_MS_4-1782504588274.pngHabib_MS_4-1782504588274.png Additionally, we need to add the file “NfcrdlibEx1_DiscoveryLoop.c” which is the main source file of the project, to achieve this also please drag and drop in the project files folder. Habib_MS_5-1782504604217.pngHabib_MS_5-1782504604217.png At this point, the project should look like this:        Habib_MS_0-1785877154551.pngHabib_MS_0-1785877154551.png Add the example source code to the newly created MCXN947 project From the “NxpNfcRdLib_PN5190_v07.14.00_PUB” extracted just drag and drop in the project files folder the following folders. Habib_MS_0-1782504704260.pngHabib_MS_0-1782504704260.png Habib_MS_1-1782504734285.pngHabib_MS_1-1782504734285.png Habib_MS_2-1782504750818.pngHabib_MS_2-1782504750818.png Habib_MS_3-1782504795659.pngHabib_MS_3-1782504795659.png Once these folders are added the project should look like this: Habib_MS_1-1785877203826.pngHabib_MS_1-1785877203826.png Define FRDM-MCXN947 SDK preprocessor symbol We need to make some changes to the compiler preprocessor configuration related to the NFC reader library, to do this we need to modify the Cmakelist.txt PH_OSAL_FREERTOS PHDRIVER_FRDMMCXN947_PN5190_BOARD NXPBUILD_CUSTOMER_HEADER_INCLUDED PHDRIVER_MCXN947_SPI_POLLING Habib_MS_0-1782505699286.pngHabib_MS_0-1782505699286.png Spoiler (Highlight to read) mcux_add_macro( CC"NXPBUILD_CUSTOMER_HEADER_INCLUDED\ PHDRIVER_FRDMMCXN947_PN5190_BOARD\ PH_OSAL_FREERTOS\ PHDRIVER_MCXN947_SPI_POLLING" ) mcux_add_macro( CC"NXPBUILD_CUSTOMER_HEADER_INCLUDED\ PHDRIVER_FRDMMCXN947_PN5190_BOARD\ PH_OSAL_FREERTOS\ PHDRIVER_MCXN947_SPI_POLLING" ) These symbols are added so the preprocessor knows which header files to include at build time. PHDRIVER_FRDMMCXN947_PN5190_BOARD will help include the BoardSelection.h header, the file that is going to define addresses for registers and peripherals of MCXN947. PH_OSAL_FREERTOS will include headers related to OS operation, meaning that the project will work with operative system (at the end of this guide you will find the steps to add NULLOS support). NXPBUILD_CUSTOMER_HEADER_INCLUDED will add headers to add and select the NFC reader and host that will be used in the project. PHDRIVER_MCXN947_SPI_POLLING: if is defined the example will perform SPI communication by polling method, and if not, will be perform through non-blocking transfers. Modifying the Driver Abstraction Layer (DAL) The added folder DAL will contain the important changes to be able to use the MCXN947 as host device since it will contain all the changes regarding SPI, timer and GPIO configurations required by the library to work properly. Board_FRDM_MCXN947_PN5190.h We need to create a header file that will contain important macros used by the library that are related to the host specific SPI, timer and GPIO peripherals, as well as interrupt vectors and priorities, clock sources and addresses. This file is required to be inside the “boards” folder which is inside DAL. 1. Go to explorer window and select “add file” on the boards folder: Habib_MS_1-1782505314578.pngHabib_MS_1-1782505314578.png 2. Write the file’s name as follows (Board_FRDM_MCXN947_PN5190.h) and click enter: Habib_MS_2-1782505345384.pngHabib_MS_2-1782505345384.png A window like the one shown in the following figure will appear. However, it can be discarded. This window is intended to add the newly created file to the CMakeLists.txt file, but we will instead include the entire folder later. Habib_MS_3-1782505364793.pngHabib_MS_3-1782505364793.png Inside this file, some important macros related to the SPI peripheral and the important pins to be handled (IRQ, Chip Select, Reset) are defined. Habib_MS_4-1782505388079.pngHabib_MS_4-1782505388079.png Spoiler (Highlight to read) #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 #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 << 😎 | 28) /**< Reset pin, Pin28, PIO0_28 */ #define PHDRIVER_PIN_IRQ ((GPIO_PORT << 😎 | 31) /**< IRQ pin, Pin10, PIO0_10 */ /* For 5190 busy is same as IRQ */ #define PHDRIVER_PIN_BUSY ((GPIO_PORT << 😎 | 31) /**< IRQ pin, Pin31, PIO0_31 */ #define PHDRIVER_PIN_DWL ((GPIO_PORT << 😎 | 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 << 😎 | 0) /**< GPIO, Port 1, Pin0 */ #define PHDRIVER_PIN_FAIL ((GPIO_PORT1 << 😎 | 1) /**< GPIO, Port 1, Pin1 */ /****************************************************************** * PIN Pull-Up/Pull-Down configurations. ******************************************************************/ #define PHDRIVER_PIN_RESET_PULL_CFG PH_DRIVER_PULL_UP #define PHDRIVER_PIN_IRQ_PULL_CFG PH_DRIVER_PULL_DOWN #define PHDRIVER_PIN_WKUP_PULL_CFG PH_DRIVER_PULL_UP #define PHDRIVER_PIN_CLK_PULL_CFG PH_DRIVER_PULL_UP #define PHDRIVER_PIN_DWL_PULL_CFG PH_DRIVER_PULL_UP #define PHDRIVER_PIN_NSS_PULL_CFG PH_DRIVER_PULL_UP #define PHDRIVER_PIN_BUSY_PULL_CFG PH_DRIVER_PULL_UP We define the macros as well for the interrupt vector of MCXN947, its priority, handler and trigger type. Habib_MS_5-1782505436112.pngHabib_MS_5-1782505436112.png Spoiler (Highlight to read) /****************************************************************** * 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*/ /****************************************************************** * IRQ PIN NVIC settings ******************************************************************/ #define EINT_IRQn GPIO00_IRQn /*Adding interrupt vector A of GPIO*/ #define EINT_PRIORITY 7 /*Default interrupt priority for GPIO*/ #define CLIF_IRQHandler GPIO00_IRQHandler /*Interrupt handler for vector A*/ #define PIN_IRQ_TRIGGER_TYPE PH_DRIVER_INTERRUPT_RISINGEDGE /*Rising edge Trigger*/ As well as some macros for pin logic levels. Habib_MS_6-1782505468893.pngHabib_MS_6-1782505468893.png Spoiler (Highlight to read) /***************************************************************** * 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 /***************************************************************** * Front End Reset logic level settings ****************************************************************/ #define PH_DRIVER_SET_HIGH 1 /**< Logic High. */ #define PH_DRIVER_SET_LOW 0 /**< Logic Low. */ #define RESET_POWERDOWN_LEVEL PH_DRIVER_SET_LOW #define RESET_POWERUP_LEVEL PH_DRIVER_SET_HIGH Finally, we define macros for the base address of CTIMER and SPI peripherals, clock frequencies, interrupt vectors and related pins. Habib_MS_7-1782505509612.pngHabib_MS_7-1782505509612.png Spoiler (Highlight to read) /***************************************************************** * 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_ */ /***************************************************************** * SPI Configuration ****************************************************************/ #define PHDRIVER_MCXN947_SPI_MASTER LPSPI1 #define PHDRIVER_MCXN947_SPI_DATA_RATE 5000000U #define PHDRIVER_MCXN947_SPI_CLK_SRC SPI_MASTER_CLOCK_FREQ #define PHDRIVER_MCXN947_SPI_IRQ LP_FLEXCOMM1_IRQn #define SPI_IRQ_PRIORITY 6 /*SPI interrupt priority*/ #define PHDRIVER_PIN_SSEL 27U/* Chip Select, Pin6, SPI */ #define PHDRIVER_PIN_SCK 25U/* SPI clock, Pin7, SPI */ #define PHDRIVER_PIN_MISO 26U/* MISO, Pin8, SPI */ #define PHDRIVER_PIN_MOSI 24U/* MOSI, Pin9, SPI */ #define PHDRIVER_FC1_SPI_DIV kCLOCK_DivFlexcom1Clk #define PHDRIVER_FC1_SPI_CLK kFRO12M_to_FLEXCOMM1 /*Clock to attach to Flexcomm1*/ /***************************************************************** * Timer Configuration ****************************************************************/ #define PH_DRIVER_SDK_CTIMER CTIMER0 /*CTIMER0 base*/ #define PH_DRIVER_SDK_CTIMER_CLK kCLOCK_DivCtimer0Clk/*CTIMER0 clock*/ #define PH_DRIVER_SDK_CTIMER_NVIC CTIMER0_IRQn /*Interrupt vector*/ #define PH_DRIVER_SDK_CTIMER_PRIORITY 4 #define PH_DRIVER_SDK_CTIMER_CLK_FREQ CLOCK_GetCTimerClkFreq(0U) /*CTIMER0 Clock frequency*/ #endif /* DAL_BOARDS_BOARD_FRDM_MCXN947_PN5190_H_ */ MCXN947 SPI and SDK files  Now, inside DAL > src folder we will create a folder named “MCXN947” that will contain 2 source files: phbalReg_Mcxn947Spi.c phDriver_Mcxn947SDK.c 1. Firstly, we will need to delete the “KinetisSDK” folder located in the src folder to avoid multiple definition issues. Please right-click on src/KinetisSDK and click on “Delete”: Habib_MS_1-1782505869521.pngHabib_MS_1-1782505869521.png   2. A window as the following figure will appear, please click on “Move to Recycle Bin”: Habib_MS_2-1782505893781.pngHabib_MS_2-1782505893781.png 3. In the same folder please right-click and click on “New folder…”: Habib_MS_3-1782505917835.pngHabib_MS_3-1782505917835.png 4. Write the folder’s name as follows (MCXN947) and click enter: Habib_MS_4-1782505943176.pngHabib_MS_4-1782505943176.png 5. Add both files following the same steps mentioned in the section Board_FRDM_MCXN947_PN5190.h but with those files (phbalReg_Mcxn947Spi.c and phDriver_Mcxn947SDK.c). We will add these source files in the CMake_List.txt on the next step. Once these files are added the src folder should look like this: Habib_MS_5-1782505974388.pngHabib_MS_5-1782505974388.png 6. Finally, we will add both files to the CMakeLists.txt file so they are included in the compilation process. Please add the following code in the CMake_list.txt file: Habib_MS_6-1782505996170.pngHabib_MS_6-1782505996170.png Spoiler (Highlight to read) mcux_add_source(BASE_PATH ${CMAKE_CURRENT_LIST_DIR} SOURCES "DAL/src/MCXN947/phbalReg_Mcxn947Spi.c" "DAL/src/MCXN947/phDriver_Mcxn947SDK.c") mcux_add_source(BASE_PATH ${CMAKE_CURRENT_LIST_DIR} SOURCES "DAL/src/MCXN947/phbalReg_Mcxn947Spi.c" "DAL/src/MCXN947/phDriver_Mcxn947SDK.c") Although the Kinetis SDK folder has been deleted, it is still referenced in the CMakeLists.txt file. Please remove those includes from this file. Now, we will return to the MCUXpresso extension. Within these source files, we will modify the functions inherited from other board host implementations, replacing them with configurations specific to the MCXN947 peripheral drivers, including SPI, timers, GPIOs, and interrupt handlers. These modifications are based on SDK examples such as ctimer_match_interrupt_example_cm33_core0 and lpspi_polling_b2b_transfer_master_cm33_core0. phbalReg_Mcxn947Spi.c: In this file we first need to include the necessary files and include the headers and callbacks to ensure the correct functionality: Habib_MS_1-1782506156720.pngHabib_MS_1-1782506156720.png Spoiler (Highlight to read) #include "phDriver.h" #include #include "BoardSelection.h" #include #include #include #define PHBAL_REG_MCXN947_SPI_ID 0x0FU /**< ID for MCXN947 SPI BAL component */ #define RX_BUFFER_SIZE_MAX 272U /* Receive Buffer size while exchange */ #ifndef PHDRIVER_MCXN947_SPI_POLLING lpspi_master_handle_t g_masterHandle; /* LPSPI user callback */ void LPSPI_MasterUserCallback(LPSPI_Type *base, lpspi_master_handle_t *handle, status_t status, void *userData); #endif static void phbalReg_Mcxn947SpiConfig(void); #ifndef PHDRIVER_MCXN947_SPI_POLLING volatile bool isTransferCompleted = false; void LPSPI_MasterUserCallback(LPSPI_Type *base, lpspi_master_handle_t *handle, status_t status, void *userData) { if (status == kStatus_Success) { __NOP(); } isTransferCompleted = true; } #endif #include "phDriver.h" #include #include "BoardSelection.h" #include #include #include #define PHBAL_REG_MCXN947_SPI_ID 0x0FU /**< ID for MCXN947 SPI BAL component */ #define RX_BUFFER_SIZE_MAX 272U /* Receive Buffer size while exchange */ #ifndef PHDRIVER_MCXN947_SPI_POLLING lpspi_master_handle_t g_masterHandle; /* LPSPI user callback */ void LPSPI_MasterUserCallback(LPSPI_Type *base, lpspi_master_handle_t *handle, status_t status, void *userData); #endif static void phbalReg_Mcxn947SpiConfig(void); #ifndef PHDRIVER_MCXN947_SPI_POLLING volatile bool isTransferCompleted = false; void LPSPI_MasterUserCallback(LPSPI_Type *base, lpspi_master_handle_t *handle, status_t status, void *userData) { if (status == kStatus_Success) { __NOP(); } isTransferCompleted = true; } #endif After, we will define the phbalReg_Init function, which will be used by the library to initialize the SPI peripheral in this case, and it is defined as follows: Habib_MS_2-1782506214363.pngHabib_MS_2-1782506214363.png Spoiler (Highlight to read) /** * \brief Initialize the Rw612 SPI BAL layer. * * \return Status code * \retval #PH_DRIVER_SUCCESS Operation successful. * \retval #PH_ERR_INVALID_DATA_PARAMS Parameter structure size is invalid. */ phStatus_t phbalReg_Init( void * pDataParams, uint16_t wSizeOfDataParams) { lpspi_master_config_t userConfig; uint32_t srcFreq = 0; if((pDataParams == NULL) || (sizeof(phbalReg_Type_t) != wSizeOfDataParams)) { return (PH_DRIVER_ERROR | PH_COMP_DRIVER); } ((phbalReg_Type_t *)pDataParams)->wId = PH_COMP_DRIVER | PHBAL_REG_MCXN947_SPI_ID; ((phbalReg_Type_t *)pDataParams)->bBalType = PHBAL_REG_TYPE_SPI; /*Initialize Flexcomm1 clock*/ /* attach FRO 12M to FLEXCOMM1 */ CLOCK_SetClkDiv(PHDRIVER_FC1_SPI_DIV, 1u); CLOCK_AttachClk(PHDRIVER_FC1_SPI_CLK); /*Configure SPI pins*/ phbalReg_Mcxn947SpiConfig(); /*SPI configuration*/ LPSPI_MasterGetDefaultConfig(&userConfig); userConfig.baudRate = PHDRIVER_MCXN947_SPI_DATA_RATE; srcFreq = SPI_MASTER_CLOCK_FREQ; userConfig.whichPcs = (lpspi_which_pcs_t)kLPSPI_Pcs0; userConfig.pcsActiveHighOrLow = (lpspi_pcs_polarity_config_t)kLPSPI_PcsActiveLow; userConfig.pcsToSckDelayInNanoSec = 1000000000U / (userConfig.baudRate * 1U); userConfig.lastSckToPcsDelayInNanoSec = 1000000000U / (userConfig.baudRate * 1U); userConfig.betweenTransferDelayInNanoSec = 1000000000U / (userConfig.baudRate * 1U); /*Initialize SPI*/ #ifdef PHDRIVER_MCXN947_SPI_POLLING LPSPI_MasterInit(PHDRIVER_MCXN947_SPI_MASTER, &userConfig, srcFreq); #else LPSPI_MasterInit(PHDRIVER_MCXN947_SPI_MASTER, &userConfig, srcFreq); LPSPI_MasterTransferCreateHandle(PHDRIVER_MCXN947_SPI_MASTER, &g_masterHandle, LPSPI_MasterUserCallback, NULL); #endif return PH_DRIVER_SUCCESS; } /** * \brief Initialize the Rw612 SPI BAL layer. * * \return Status code * \retval #PH_DRIVER_SUCCESS Operation successful. * \retval #PH_ERR_INVALID_DATA_PARAMS Parameter structure size is invalid. */ phStatus_t phbalReg_Init( void * pDataParams, uint16_t wSizeOfDataParams) { lpspi_master_config_t userConfig; uint32_t srcFreq = 0; if((pDataParams == NULL) || (sizeof(phbalReg_Type_t) != wSizeOfDataParams)) { return (PH_DRIVER_ERROR | PH_COMP_DRIVER); } ((phbalReg_Type_t *)pDataParams)->wId = PH_COMP_DRIVER | PHBAL_REG_MCXN947_SPI_ID; ((phbalReg_Type_t *)pDataParams)->bBalType = PHBAL_REG_TYPE_SPI; /*Initialize Flexcomm1 clock*/ /* attach FRO 12M to FLEXCOMM1 */ CLOCK_SetClkDiv(PHDRIVER_FC1_SPI_DIV, 1u); CLOCK_AttachClk(PHDRIVER_FC1_SPI_CLK); /*Configure SPI pins*/ phbalReg_Mcxn947SpiConfig(); /*SPI configuration*/ LPSPI_MasterGetDefaultConfig(&userConfig); userConfig.baudRate = PHDRIVER_MCXN947_SPI_DATA_RATE; srcFreq = SPI_MASTER_CLOCK_FREQ; userConfig.whichPcs = (lpspi_which_pcs_t)kLPSPI_Pcs0; userConfig.pcsActiveHighOrLow = (lpspi_pcs_polarity_config_t)kLPSPI_PcsActiveLow; userConfig.pcsToSckDelayInNanoSec = 1000000000U / (userConfig.baudRate * 1U); userConfig.lastSckToPcsDelayInNanoSec = 1000000000U / (userConfig.baudRate * 1U); userConfig.betweenTransferDelayInNanoSec = 1000000000U / (userConfig.baudRate * 1U); /*Initialize SPI*/ #ifdef PHDRIVER_MCXN947_SPI_POLLING LPSPI_MasterInit(PHDRIVER_MCXN947_SPI_MASTER, &userConfig, srcFreq); #else LPSPI_MasterInit(PHDRIVER_MCXN947_SPI_MASTER, &userConfig, srcFreq); LPSPI_MasterTransferCreateHandle(PHDRIVER_MCXN947_SPI_MASTER, &g_masterHandle, LPSPI_MasterUserCallback, NULL); #endif return PH_DRIVER_SUCCESS; } We have to define the phbalReg_Exchange function as well, which is used for communicating via SPI with the PN5190. Habib_MS_3-1782506250553.pngHabib_MS_3-1782506250553.png   Habib_MS_4-1782506278106.pngHabib_MS_4-1782506278106.png Spoiler (Highlight to read) 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; } phStatus_t phbalReg_Exchange( void * pDataParams, uint16_t wOption, uint8_t * pTxBuffer, uint16_t wTxLength, uint16_t wRxBufSize, uint8_t * pRxBuffer, uint16_t * pRxLength ) { phStatus_t status = PH_DRIVER_SUCCESS; uint8_t * pRxBuf; status_t lpspiStatus; lpspi_transfer_t g_masterXfer; uint8_t g_dummyBuffer[RX_BUFFER_SIZE_MAX]; if(pRxBuffer == NULL) { pRxBuf = g_dummyBuffer; } else { pRxBuf = pRxBuffer; } if(pTxBuffer == NULL) { wTxLength = wRxBufSize; g_dummyBuffer[0] = 0xFF; pTxBuffer = g_dummyBuffer; } memset(&g_masterXfer, 0, sizeof(lpspi_transfer_t)); /* Set up the transfer */ g_masterXfer.txData = pTxBuffer; g_masterXfer.rxData = pRxBuf; g_masterXfer.dataSize = wTxLength; g_masterXfer.configFlags = kLPSPI_MasterPcs0 | kLPSPI_MasterPcsContinuous | kLPSPI_MasterByteSwap; /* Start transfer */ #ifdef PHDRIVER_MCXN947_SPI_POLLING lpspiStatus = LPSPI_MasterTransferBlocking(PHDRIVER_MCXN947_SPI_MASTER, &g_masterXfer); #else lpspiStatus = LPSPI_MasterTransferNonBlocking(PHDRIVER_MCXN947_SPI_MASTER, &g_masterHandle, &g_masterXfer); /* Wait transfer complete */ while (!isTransferCompleted) { } #endif if (lpspiStatus != kStatus_Success) { return (PH_DRIVER_FAILURE | PH_COMP_DRIVER); } if (pRxLength != NULL) { *pRxLength = wTxLength; } #ifndef PHDRIVER_MCXN947_SPI_POLLING SDK_DelayAtLeastUs(300U, BOARD_BOOTCLOCKPLL150M_CORE_CLOCK); #endif return status; } Finally, we will define the phbalReg_Mcxn947SpiConfig function, which is called by phbalReg_Init to configure the SPI pins on the MCXN947: Habib_MS_5-1782506335570.pngHabib_MS_5-1782506335570.png Spoiler (Highlight to read) 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); } static void phbalReg_Mcxn947SpiConfig(void) { const port_pin_config_t port0_24_pinB6_config = { kPORT_PullUp, kPORT_LowPullResistor, kPORT_SlowSlewRate, kPORT_PassiveFilterDisable, kPORT_OpenDrainDisable, kPORT_LowDriveStrength, /* Pin is configured as FC1_P0 */ kPORT_MuxAlt2, kPORT_InputBufferEnable, kPORT_InputNormal, kPORT_UnlockRegister}; /* PORT0_24 (pin B6) is configured as SPI_MOSI */ PORT_SetPinConfig(PORT0, 24U, &port0_24_pinB6_config); const port_pin_config_t port0_25_pinA6_config = { kPORT_PullUp, kPORT_LowPullResistor, kPORT_SlowSlewRate, kPORT_PassiveFilterDisable, kPORT_OpenDrainDisable, kPORT_LowDriveStrength, /* Pin is configured as FC1_P1 */ kPORT_MuxAlt2, kPORT_InputBufferEnable, kPORT_InputNormal, kPORT_UnlockRegister}; /* PORT0_25 (pin A6) is configured as SPI_SCK */ PORT_SetPinConfig(PORT0, 25U, &port0_25_pinA6_config); const port_pin_config_t port0_26_pinF10_config = { kPORT_PullUp, kPORT_LowPullResistor, kPORT_SlowSlewRate, kPORT_PassiveFilterDisable, kPORT_OpenDrainDisable, kPORT_LowDriveStrength, /* Pin is configured as FC1_P2 */ kPORT_MuxAlt2, kPORT_InputBufferEnable, kPORT_InputNormal, kPORT_UnlockRegister}; /* PORT0_26 (pin F10) is configured as SPI_MISO */ PORT_SetPinConfig(PORT0, 26U, &port0_26_pinF10_config); const port_pin_config_t port0_27_pinE10_config = { kPORT_PullUp, kPORT_LowPullResistor, kPORT_SlowSlewRate, kPORT_PassiveFilterDisable, kPORT_OpenDrainDisable, kPORT_LowDriveStrength, /* Pin is configured as FC1_P3 */ kPORT_MuxAlt2, kPORT_InputBufferEnable, kPORT_InputNormal, kPORT_UnlockRegister}; /* PORT0_27 (pin E10) is configured as SPI_CS */ PORT_SetPinConfig(PORT0, 27U, &port0_27_pinE10_config); } phDriver_Mcxn947SDK.c: In this file we will have the following definitions and includes that describe relevant characteristics of the ctimer (configuration structures, interrupt handlers and maximum count value), and of the GPIO port: Habib_MS_1-1782506665356.pngHabib_MS_1-1782506665356.png Spoiler (Highlight to read) #include "phDriver.h" #include "BoardSelection.h" #include "fsl_device_registers.h" #include #include /* *********************************************************************************************************** * Internal Definitions * ********************************************************************************************************** */ #define MCXN947_TIMER_MAX_32BIT 0xFFFFFFFFU #define CTIMER_HANDLER CTIMER0_IRQHandler /* *********************************************************************************************************** * * Type Definitions *********************************************************************************************************** */ volatile bool ctimerIsrFlag = false; /* *********************************************************************************************************** * Global and Static Variables * * Match Configuration for CTIMER Channel 0*/ static ctimer_match_config_t matchConfig0; /* Total Size: NNNbytes * ********************************************************************************************************** */ /* Array initializer of GPIO peripheral base pointers */ static const GPIO_Type *pGpiosBaseAddr[] = GPIO_BASE_PTRS; static pphDriver_TimerCallBck_t pCTimerCallBack; static volatile uint8_t dwTimerExp; static const gpio_interrupt_config_t aInterruptTypes[] = {kGPIO_InterruptLogicZero, /* Unused. */ kGPIO_InterruptLogicZero, kGPIO_InterruptLogicOne, kGPIO_InterruptRisingEdge, kGPIO_InterruptFallingEdge, kGPIO_InterruptEitherEdge, }; /* *********************************************************************************************************** * Private Functions Prototypes * ********************************************************************************************************** */ static void phDriver_CTimerIsrCallBack(void); #include "phDriver.h" #include "BoardSelection.h" #include "fsl_device_registers.h" #include #include /* *********************************************************************************************************** * Internal Definitions * ********************************************************************************************************** */ #define MCXN947_TIMER_MAX_32BIT 0xFFFFFFFFU #define CTIMER_HANDLER CTIMER0_IRQHandler /* *********************************************************************************************************** * * Type Definitions *********************************************************************************************************** */ volatile bool ctimerIsrFlag = false; /* *********************************************************************************************************** * Global and Static Variables * * Match Configuration for CTIMER Channel 0*/ static ctimer_match_config_t matchConfig0; /* Total Size: NNNbytes * ********************************************************************************************************** */ /* Array initializer of GPIO peripheral base pointers */ static const GPIO_Type *pGpiosBaseAddr[] = GPIO_BASE_PTRS; static pphDriver_TimerCallBck_t pCTimerCallBack; static volatile uint8_t dwTimerExp; static const gpio_interrupt_config_t aInterruptTypes[] = {kGPIO_InterruptLogicZero, /* Unused. */ kGPIO_InterruptLogicZero, kGPIO_InterruptLogicOne, kGPIO_InterruptRisingEdge, kGPIO_InterruptFallingEdge, kGPIO_InterruptEitherEdge, }; /* *********************************************************************************************************** * Private Functions Prototypes * ********************************************************************************************************** */ static void phDriver_CTimerIsrCallBack(void); We will define the following functions to initialize and stop the timer, and to enable timer interruptions and its callback: Habib_MS_2-1782506722983.pngHabib_MS_2-1782506722983.png Habib_MS_3-1782506736273.pngHabib_MS_3-1782506736273.png Spoiler (Highlight to read) 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; } phStatus_t phDriver_TimerStart(phDriver_Timer_Unit_t eTimerUnit, uint32_t dwTimePeriod, pphDriver_TimerCallBck_t pTimerCallBack) { uint64_t qwTimerCnt; uint32_t dwTimerFreq; dwTimerFreq = PH_DRIVER_SDK_CTIMER_CLK_FREQ; qwTimerCnt = dwTimerFreq; qwTimerCnt = (qwTimerCnt / eTimerUnit); qwTimerCnt = (dwTimePeriod * qwTimerCnt); /* 32-bit timers. */ if(qwTimerCnt > (uint64_t)MCXN947_TIMER_MAX_32BIT) { return PH_DRIVER_ERROR | PH_COMP_DRIVER; } if(pTimerCallBack == NULL) /* Timer Start is blocking call. */ { dwTimerExp = 0; pCTimerCallBack = phDriver_CTimerIsrCallBack; } else /* Call the Timer callback. */ { pCTimerCallBack = pTimerCallBack; } /*Configure & start CTIMER*/ /*Ctimer config structure*/ ctimer_config_t config; /*Timer mode, init*/ CTIMER_GetDefaultConfig(&config); CTIMER_Init(PH_DRIVER_SDK_CTIMER, &config); CTIMER_EnableInterrupts(PH_DRIVER_SDK_CTIMER, kCTIMER_Match0InterruptEnable|kCTIMER_Capture0InterruptEnable); /* Configuration match 0 */ matchConfig0.enableCounterReset = true; matchConfig0.enableCounterStop = false; matchConfig0.matchValue = (uint32_t)qwTimerCnt; matchConfig0.outControl = kCTIMER_Output_NoAction; matchConfig0.outPinInitState = false; matchConfig0.enableInterrupt = true; EnableIRQ(PH_DRIVER_SDK_CTIMER_NVIC); NVIC_SetPriority(PH_DRIVER_SDK_CTIMER_NVIC, PH_DRIVER_SDK_CTIMER_PRIORITY); /*Setup Match*/ CTIMER_SetupMatch(PH_DRIVER_SDK_CTIMER, kCTIMER_Match_0, &matchConfig0); /*Start*/ CTIMER_StartTimer(PH_DRIVER_SDK_CTIMER); while (true) { /* Check whether an interrupt occurred */ if (true == ctimerIsrFlag && dwTimerExp) { /* Clear interrupt flag*/ ctimerIsrFlag = false; break; } } return PH_DRIVER_SUCCESS; } Habib_MS_4-1782506821715.pngHabib_MS_4-1782506821715.png Spoiler (Highlight to read) 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; } 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_4-1784224063232.pngHabib_MS_4-1784224063232.png Spoiler (Highlight to read) phStatus_t phDriver_PinConfig(uint32_t dwPinNumber, phDriver_Pin_Func_t ePinFunc, phDriver_Pin_Config_t *pPinConfig) { gpio_pin_config_t sGpioConfig; uint8_t bPinNum; if((ePinFunc == PH_DRIVER_PINFUNC_BIDIR) || (pPinConfig == NULL)) { return PH_DRIVER_ERROR | PH_COMP_DRIVER; } /* Extract the Pin, Gpio, Port details from dwPinNumber */ bPinNum = (uint8_t)(dwPinNumber & 0xFF); sGpioConfig.pinDirection = (ePinFunc == PH_DRIVER_PINFUNC_OUTPUT) ? kGPIO_DigitalOutput:kGPIO_DigitalInput; sGpioConfig.outputLogic = pPinConfig->bOutputLogic; if(ePinFunc == PH_DRIVER_PINFUNC_INTERRUPT) { gpio_interrupt_config_t intConfig = aInterruptTypes[(uint8_t)pPinConfig->eInterruptConfig]; GPIO_GpioClearInterruptFlags((GPIO_Type *)pGpiosBaseAddr[GPIO_PORT], bPinNum); GPIO_SetPinInterruptConfig((GPIO_Type *)pGpiosBaseAddr[GPIO_PORT], bPinNum, intConfig); EnableIRQ(EINT_IRQn); GPIO_PinInit((GPIO_Type *)pGpiosBaseAddr[GPIO_PORT],bPinNum,&sGpioConfig); } else { GPIO_PinInit((GPIO_Type *)pGpiosBaseAddr[GPIO_PORT],bPinNum,&sGpioConfig); } return PH_DRIVER_SUCCESS; } phStatus_t phDriver_PinConfig(uint32_t dwPinNumber, phDriver_Pin_Func_t ePinFunc, phDriver_Pin_Config_t *pPinConfig) { gpio_pin_config_t sGpioConfig; uint8_t bPinNum; if((ePinFunc == PH_DRIVER_PINFUNC_BIDIR) || (pPinConfig == NULL)) { return PH_DRIVER_ERROR | PH_COMP_DRIVER; } /* Extract the Pin, Gpio, Port details from dwPinNumber */ bPinNum = (uint8_t)(dwPinNumber & 0xFF); sGpioConfig.pinDirection = (ePinFunc == PH_DRIVER_PINFUNC_OUTPUT) ? kGPIO_DigitalOutput:kGPIO_DigitalInput; sGpioConfig.outputLogic = pPinConfig->bOutputLogic; if(ePinFunc == PH_DRIVER_PINFUNC_INTERRUPT) { gpio_interrupt_config_t intConfig = aInterruptTypes[(uint8_t)pPinConfig->eInterruptConfig]; GPIO_GpioClearInterruptFlags((GPIO_Type *)pGpiosBaseAddr[GPIO_PORT], bPinNum); GPIO_SetPinInterruptConfig((GPIO_Type *)pGpiosBaseAddr[GPIO_PORT], bPinNum, intConfig); EnableIRQ(EINT_IRQn); GPIO_PinInit((GPIO_Type *)pGpiosBaseAddr[GPIO_PORT],bPinNum,&sGpioConfig); } else { GPIO_PinInit((GPIO_Type *)pGpiosBaseAddr[GPIO_PORT],bPinNum,&sGpioConfig); } return PH_DRIVER_SUCCESS; } Habib_MS_3-1784224025491.pngHabib_MS_3-1784224025491.png Spoiler (Highlight to read) uint8_t phDriver_PinRead(uint32_t dwPinNumber, phDriver_Pin_Func_t ePinFunc) { uint8_t bValue; uint32_t intStatus; uint8_t bPinNum; /* Extract the Pin, Gpio details from dwPinNumber */ bPinNum = (uint8_t)(dwPinNumber & 0xFF); if(ePinFunc == PH_DRIVER_PINFUNC_INTERRUPT) { /*Get value of pin interrupt status*/ intStatus = GPIO_PinGetInterruptFlag((GPIO_Type *)pGpiosBaseAddr[GPIO_PORT], bPinNum); bValue = intStatus ? 1:0; } else { /*Read pin value*/ bValue = (uint8_t)GPIO_PinRead((GPIO_Type *)pGpiosBaseAddr[GPIO_PORT], bPinNum); } return bValue; } uint8_t phDriver_PinRead(uint32_t dwPinNumber, phDriver_Pin_Func_t ePinFunc) { uint8_t bValue; uint32_t intStatus; uint8_t bPinNum; /* Extract the Pin, Gpio details from dwPinNumber */ bPinNum = (uint8_t)(dwPinNumber & 0xFF); if(ePinFunc == PH_DRIVER_PINFUNC_INTERRUPT) { /*Get value of pin interrupt status*/ intStatus = GPIO_PinGetInterruptFlag((GPIO_Type *)pGpiosBaseAddr[GPIO_PORT], bPinNum); bValue = intStatus ? 1:0; } else { /*Read pin value*/ bValue = (uint8_t)GPIO_PinRead((GPIO_Type *)pGpiosBaseAddr[GPIO_PORT], bPinNum); } return bValue; } Habib_MS_2-1784223977410.pngHabib_MS_2-1784223977410.png Spoiler (Highlight to read) void phDriver_PinWrite(uint32_t dwPinNumber, uint8_t bValue) { uint8_t bPinNum; /* Extract the Pin, Gpio details from dwPinNumber */ bPinNum = (uint8_t)(dwPinNumber & 0xFF); GPIO_PinWrite((GPIO_Type *)pGpiosBaseAddr[GPIO_PORT], bPinNum, bValue); } void phDriver_PinClearIntStatus(uint32_t dwPinNumber) { uint8_t bPinNum; /* Extract the Pin, Gpio details from dwPinNumber */ bPinNum = (uint8_t)(dwPinNumber & 0xFF); /*Clear interrupt flag*/ GPIO_GpioClearInterruptFlags((GPIO_Type *)pGpiosBaseAddr[GPIO_PORT], (1U << bPinNum)); } void phDriver_PinWrite(uint32_t dwPinNumber, uint8_t bValue) { uint8_t bPinNum; /* Extract the Pin, Gpio details from dwPinNumber */ bPinNum = (uint8_t)(dwPinNumber & 0xFF); GPIO_PinWrite((GPIO_Type *)pGpiosBaseAddr[GPIO_PORT], bPinNum, bValue); } void phDriver_PinClearIntStatus(uint32_t dwPinNumber) { uint8_t bPinNum; /* Extract the Pin, Gpio details from dwPinNumber */ bPinNum = (uint8_t)(dwPinNumber & 0xFF); /*Clear interrupt flag*/ GPIO_GpioClearInterruptFlags((GPIO_Type *)pGpiosBaseAddr[GPIO_PORT], (1U << bPinNum)); } It is also necessary to add functions required for the library to function correctly. Habib_MS_8-1782506978124.pngHabib_MS_8-1782506978124.png Spoiler (Highlight to read) 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; } void phDriver_EnterCriticalSection(void) { NVIC_DisableIRQ(EINT_IRQn); } void phDriver_ExitCriticalSection(void) { NVIC_EnableIRQ(EINT_IRQn); } phStatus_t phDriver_IRQPinRead(uint32_t dwPinNumber) { phStatus_t bGpioVal = false; bGpioVal = phDriver_PinRead(dwPinNumber, PH_DRIVER_PINFUNC_INPUT); return bGpioVal; } phStatus_t phDriver_IRQPinPoll(uint32_t dwPinNumber, phDriver_Pin_Func_t ePinFunc, phDriver_Interrupt_Config_t eInterruptType) { uint8_t bGpioState = 0; if ((eInterruptType != PH_DRIVER_INTERRUPT_RISINGEDGE) && (eInterruptType != PH_DRIVER_INTERRUPT_FALLINGEDGE)) { return PH_DRIVER_ERROR | PH_COMP_DRIVER; } if (eInterruptType == PH_DRIVER_INTERRUPT_FALLINGEDGE) { bGpioState = 1; } while(phDriver_PinRead(dwPinNumber, ePinFunc) == bGpioState); return PH_DRIVER_SUCCESS; } Finally, here, we will have the definition of the timer interrupt handler and ISR callback. Habib_MS_9-1782507031648.pngHabib_MS_9-1782507031648.png Spoiler (Highlight to read) 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; } void CTIMER0_IRQHandler(void) { /* Clear interrupt flag.*/ CTIMER_ClearStatusFlags(PH_DRIVER_SDK_CTIMER, kCTIMER_Match0Flag|kCTIMER_Capture0Flag); /* Single shot timer. Stop it. */ CTIMER_StopTimer(PH_DRIVER_SDK_CTIMER); CTIMER_DisableInterrupts(PH_DRIVER_SDK_CTIMER, kCTIMER_Match0InterruptEnable|kCTIMER_Capture0InterruptEnable); pCTimerCallBack(); ctimerIsrFlag = true; } static void phDriver_CTimerIsrCallBack(void) { dwTimerExp = 1; } With these additions, we have all the functions needed (based on the FRDM-MCXN947 SDK) by the library to communicate with the PN5190. BoardSelection.h In this header file, which is found at “DAL > cfg” we will add the definition set in the preprocessor settings to use the FRDM-MCXN947 board as host by adding the following lines to the file: Habib_MS_10-1782507079841.pngHabib_MS_10-1782507079841.png   Spoiler (Highlight to read) #ifdef PHDRIVER_FRDMMCXN947_PN5190_BOARD # include #endif #ifdef PHDRIVER_FRDMMCXN947_PN5190_BOARD # include #endif ph_NxpBuild_App.h In this header found at “intfs” folder, we will add our board support to use it with the PN5190 by adding the following change: Habib_MS_1-1782507715135.pngHabib_MS_1-1782507715135.png Spoiler (Highlight to read) #if defined(PHDRIVER_LPC1769PN5190_BOARD) \ || defined(PHDRIVER_K82F_PNEV5190B_BOARD)\ || defined(PHDRIVER_FRDMMCXN947_PN5190_BOARD) # define NXPBUILD__PHHAL_HW_PN5190 #endif #if defined(PHDRIVER_LPC1769PN5190_BOARD) \ || defined(PHDRIVER_K82F_PNEV5190B_BOARD)\ || defined(PHDRIVER_FRDMMCXN947_PN5190_BOARD) # define NXPBUILD__PHHAL_HW_PN5190 #endif phApp_Init.h In this header located at “intfs” folder we will add the required include files for the initialization of our board and enable the correct debug interface. Habib_MS_2-1782507771262.pngHabib_MS_2-1782507771262.png Spoiler (Highlight to read) /*Check for MCXN controller based boards*/ #if defined (PHDRIVER_FRDMMCXN947_PN5190_BOARD) #define PHDRIVER_FRDM_MCXN947 #endif #ifdef PHDRIVER_FRDM_MCXN947 #include #include #include #include #include #include #endif /*Check for MCXN controller based boards*/ #if defined (PHDRIVER_FRDMMCXN947_PN5190_BOARD) #define PHDRIVER_FRDM_MCXN947 #endif #ifdef PHDRIVER_FRDM_MCXN947 #include #include #include #include #include #include #endif Spoiler (Highlight to read) #if defined(PHDRIVER_KINETIS_K82)|| defined(PHDRIVER_FRDM_MCXN947) #if defined(PHDRIVER_KINETIS_K82)|| defined(PHDRIVER_FRDM_MCXN947) phApp_Init.c Finally, in this source file we will add the initialization code for the MCXN947 to complement the initialization macros defined in the previous phApp_Init.h file modification. Here we will call functions to initialize clocks and UART pins. Habib_MS_3-1782507864930.pngHabib_MS_3-1782507864930.png Spoiler (Highlight to read) #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 #ifdef PHDRIVER_FRDM_MCXN947 #include "fsl_common.h" #include "pin_mux.h" #include "clock_config.h" #include "board.h" static void phApp_MCXN947_Init(void){ BOARD_InitBootPins(); BOARD_InitBootClocks(); BOARD_InitDebugConsole(); } #endif Spoiler (Highlight to read) #elif defined(PHDRIVER_FRDM_MCXN947) phApp_MCXN947_Init(); #elif defined(PHDRIVER_FRDM_MCXN947) phApp_MCXN947_Init(); These functions are used to initialize the correspondent clocks of each peripheral such as CTIMER, the input pins multiplexor for selecting GPIO functionality and FLEXCOMM for SPI. In here we also set the GPIO functionality for pins P0_31 and P0_28 (IRQ and RESET), as well as UART3 for printing the tag information on the serial port connected to the computer. Additionally, we need to set the NVIC priority to ensure that interrupts can occur. Add the NVIC_SetPriority() function to phApp_Configure_IRQ(). Habib_MS_5-1782507924509.pngHabib_MS_5-1782507924509.png Spoiler (Highlight to read) #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 #ifdef PH_PLATFORM_HAS_ICFRONTEND #if !(defined(PH_OSAL_LINUX) && defined(NXPBUILD__PHHAL_HW_PN5190)) phDriver_Pin_Config_t pinCfg; NVIC_SetPriority(EINT_IRQn, EINT_PRIORITY); pinCfg.bOutputLogic = PH_DRIVER_SET_LOW; pinCfg.bPullSelect = PHDRIVER_PIN_IRQ_PULL_CFG; pinCfg.eInterruptConfig = PIN_IRQ_TRIGGER_TYPE; phDriver_PinConfig(PHDRIVER_PIN_IRQ, PH_DRIVER_PINFUNC_INTERRUPT, &pinCfg); #endif pin_mux.c Inside the function “BOARD_InitBootPins()” which is defined in pin_mux.c file, the following initializations need to be added, you can find this file in the following path: {PrjRootDirPath}\frdmmcxn947_Discovery_Loop\frdmmcxn947_cm33_core0\cm33_core0   Habib_MS_6-1782507961225.pngHabib_MS_6-1782507961225.png Spoiler (Highlight to read) 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(); } void BOARD_InitBootPins(void) { /* Use FRO HF clock for some of the Ctimers */ CLOCK_SetClkDiv(kCLOCK_DivCtimer0Clk, 1u); CLOCK_AttachClk(kFRO_HF_to_CTIMER0); CLOCK_EnableClock(kCLOCK_Gpio0); CLOCK_EnableClock(kCLOCK_Gpio1); BOARD_InitPins(); } Additionally, within the “BOARD_InitPins()” function available in the same file, we will replace the function to add initializations of the GPIO and UART pins. Habib_MS_7-1782507998410.pngHabib_MS_7-1782507998410.png Habib_MS_8-1782508012260.pngHabib_MS_8-1782508012260.png Habib_MS_9-1782508024569.pngHabib_MS_9-1782508024569.png Spoiler (Highlight to read) 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); } 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-1785878023889.pngHabib_MS_0-1785878023889.png Spoiler (Highlight to read) #include "fsl_common.h" #include "fsl_port.h" #include "board.h" #include "clock_config.h" #include "pin_mux.h" #include "fsl_common.h" #include "fsl_port.h" #include "board.h" #include "clock_config.h" #include "pin_mux.h" Delete phOsal files We must delete from the path “phOsal > src > NullOs > portable” the files: “phOsal_Port_CM3.c”,“phOsal_Port_PN76xx.c” and “phOsal_Port_PN74xxxx.c”. This has the purpose of avoiding any multiple definition errors when compiling the final project. Although these files have been deleted, they are still referenced in the CMakeLists.txt file. Please remove those includes from this file. Add all header files in CMakeList.txt As mentioned previously, the CMakeList.txt is automatically updated when you copy a .c file. However, .h files are not automatically linked, so they must be added manually. Please copy and paste the following includes into the CMakeLists.txt file: Habib_MS_0-1782508446885.pngHabib_MS_0-1782508446885.png Spoiler (Highlight to read) mcux_add_include( BASE_PATH ${CMAKE_CURRENT_LIST_DIR} INCLUDES NxpNfcRdLib/intfs NxpNfcRdLib/types NxpNfcRdLib/comps/phacDiscLoop/src/Sw intfs DAL/boards DAL/cfg DAL/inc phOsal/inc . ) mcux_add_include( BASE_PATH ${CMAKE_CURRENT_LIST_DIR} INCLUDES NxpNfcRdLib/intfs NxpNfcRdLib/types NxpNfcRdLib/comps/phacDiscLoop/src/Sw intfs DAL/boards DAL/cfg DAL/inc phOsal/inc . ) Add _DSB and _ISB support As final modification step, please include in {PrjRootDirPath}\NxpNfcRdLib\comps\phhalHw\src\Pn5190\phhalHw_Pn5190_Int.c the “cmsis_gcc.h” to support of _DSB and _ISB functions. Habib_MS_2-1782508515584.pngHabib_MS_2-1782508515584.png Testing Final Project with FreeRTOS After making all the previous changes and modifications, the migration is now complete, and we can proceed to compile and flash the example to MCXN947. Please “clean” the project before building by right clicking on the project as follows: Habib_MS_1-1785878094753.pngHabib_MS_1-1785878094753.png To run the project, we will need a serial terminal like Tera Term with the following settings: - 115200 baud rate. - 8 data bits. - No parity. - One stop bit, - No flow control. Once the program is flashed and the serial terminal configured, we can reset the board and power the PNEV5190BP. You should see an output similar to the following: Habib_MS_4-1782508585568.pngHabib_MS_4-1782508585568.png Now if any NFC tag is close to the PNEV5190BP’s antenna, you should see the information displayed as shown in the image below: Habib_MS_5-1782508604979.pngHabib_MS_5-1782508604979.png Changing OS preprocessor macro This section presents the steps to follow to add the possibility of easily choosing whether to have OS support or not.  This guide is based as default with FREERTOS, but the NFC reader library offers the possibility to run without OS, firstly, we need to change the preprocessor macro PH_OSAL_FREERTOS to PH_OSAL_NULLOS in the CMakeList.txt, as shown the following image: Habib_MS_6-1782508642319.pngHabib_MS_6-1782508642319.png Finally, to avoid multiple definition issues when we change between NULLOS and FREERTOS, we will discard the SysTickHandler for FREERTOS side located in port.c when the NULLOS macro is defined, to achieve this we need to add a replacement of the file port.c since the included FreeRTOS is shared with all projects of the repository, and if we modify this file, it will be modified in all projects. 1. Go to the explorer window, right-click on the project and click on “New File…”. Habib_MS_5-1785877420766.pngHabib_MS_5-1785877420766.png 2. Write the file’s name as follows (port.c) and click enter: Habib_MS_4-1785877388377.pngHabib_MS_4-1785877388377.png 3. Add this file into the CMakeList.txt file to include port.c into the compilation process: Habib_MS_3-1785877308864.pngHabib_MS_3-1785877308864.png Spoiler (Highlight to read) mcux_add_source(BASE_PATH ${CMAKE_CURRENT_LIST_DIR} SOURCES "port.c") mcux_add_source(BASE_PATH ${CMAKE_CURRENT_LIST_DIR} SOURCES "port.c") 4. Please copy and paste all the content form of the port.c located on the following path to the port.c we created: {SdkRootDirPath}/rtos/freertos/freertos-kernel-upstream/portable/GCC/ARM_CM33_NTZ/non_secure Habib_MS_1-1785877681949.pngHabib_MS_1-1785877681949.png 5. Replace the SysTick_Handler() of the port.c we created to the following function: Habib_MS_11-1782508854714.pngHabib_MS_11-1782508854714.png Spoiler (Highlight to read) #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 #ifndef PH_OSAL_NULLOS void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */ { uint32_t ulPreviousMask; ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); traceISR_ENTER(); { /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { traceISR_EXIT_TO_SCHEDULER(); /* Pend a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } else { traceISR_EXIT(); } } portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); } #endif 6. Finally, we will ignore the port.c of the FreeRTOS folder, please add the following code to the CMakeList.txt: Habib_MS_2-1785878166328.pngHabib_MS_2-1785878166328.png Spoiler (Highlight to read) mcux_project_remove_source( BASE_PATH ${SdkRootDirPath}/rtos/freertos/freertos-kernel-upstream/portable/GCC/ARM_CM33_NTZ/non_secure SOURCES port.c ) mcux_project_remove_source( BASE_PATH ${SdkRootDirPath}/rtos/freertos/freertos-kernel-upstream/portable/GCC/ARM_CM33_NTZ/non_secure SOURCES port.c ) Please rebuild and test as the steps mentioned in the section Testing Final Project with FreeRTOS. NFC Reader Library
查看全文
2026年美国领先的白标SEO专家 将客户的 SEO 工作交给外部合作伙伴,只有当该合作伙伴确实具备相应的技术实力时,才能奏效。广告公司需要的不仅仅是供应商,而是了解抓取预算、结构化数据、内容策略,以及日益重要的如何针对人工智能驱动的搜索进行优化的白标 SEO 专家,而不仅仅是承诺排名却没有明确方法论的公司。 本指南着眼于 2026 年为美国机构提供服务的领先白标 SEO 专家,特别评估他们的技术和战略能力的深度,而不仅仅是他们网站上列出的服务范围。 2026 年领先的白标 SEO 专家 1. 阿拉伯搜索引擎优化 Arab SEO 团队在技术 SEO、本地 SEO、电子商务 SEO、国际 SEO、AI SEO 和生成式引擎优化 (GEO) 方面拥有专家级的深度。真正的专家与普通供应商的区别在于方法论——Arab SEO 的多语言和人工智能驱动搜索方法建立在结构化、可重复的流程之上,而不是一次性的策略,这对于一家代理机构同时信任拥有数十个不同客户账户的合作伙伴来说至关重要。 2. SEO 通告 SEO Circular 的专家们专注于企业级技术 SEO——这类大型的、拥有数千页的网站,一个被忽视的抓取问题就可能抑制整个域的排名。其团队在国际和多语言 SEO 方面的经验也使其成为与跨国经营的客户合作的代理机构的有力选择。 3. 三重思维 Triple Minds 的团队以代理服务为核心,这意味着其专家完全专注于执行质量,而不是销售或客户获取——这在交付一致性方面是一个结构性优势。 4. 半化 Semify 的专家拥有多年构建可定制本地 SEO 活动的经验,其流程专门围绕帮助小型机构逐步扩展其 SEO 服务而构建。 5. SEOReseller SEOReseller 团队专注于提供全方位管理的服务,处理完整的 SEO 流程——技术、内容和链接——日常执行中几乎不需要代理机构的参与。 6. DashClicks DashClicks 将其 SEO 专家与专为报告和客户管理而构建的软件平台相结合,使代理机构能够通过自动化仪表板了解专家的工作情况。 7. 霍斯 HOTH 的专家们在完善的文档记录和标准化的方案框架内工作,使得机构能够轻松理解他们的流程,并向客户解释。 8. 增强能力 Boostability 团队在为大量小型客户提供一致的 SEO 质量方面积累了丰富的专业知识——这与管理少数大型企业客户所需的技能截然不同。 9. 销售 Vendasta 的专家们在一个更广泛的市场平台上工作,SEO 是众多白标服务之一,代理机构可以通过单一团队关系访问这些服务。 10. 法特乔 FATJOE 的专家专注于快速、产品化的交付成果——快速完成单个链接建设或内容订单,而不是持续的战略合作。 究竟是什么将专业供应商与普通供应商区分开来? 真正的SEO专家应该能够用具体、专业的术语解释他们的工作流程,而不仅仅是列出服务类别。注意以下信号: 他们可以详细解释他们的技术审计流程——他们使用哪些工具,他们具体检查哪些内容,以及如何对发现的问题进行优先级排序。 他们有一套完善的内容策略流程,该流程与真实的搜索意图研究挂钩,而不仅仅是关键词密度目标。 他们可以清楚地描述他们的链接建设方法,包括链接的来源以及如何评估链接质量。 他们对人工智能搜索有着明确的观点,因为人工智能搜索重塑搜索引擎优化的速度比近年来任何算法更新都要快。 他们可以展示真实客户项目的前后对比数据,即使数据经过匿名化处理。 为什么专业深度比服务广度更重要 选择白标合作伙伴时,很容易根据他们列出的服务数量来决定,但一个提供十项服务但服务内容浅薄的供应商,其价值通常不如一个提供五项服务但服务内容真正深入的供应商。机构应该更重视合作伙伴的实际技术能力——诊断和解决实际问题的能力——而不是一长串可能执行得好也可能执行得不好的服务类别。 向任何白标SEO专家提出的问题 请一步一步地向我介绍一下你们的技术审核流程。 您如何决定要创作哪些内容,又基于哪些研究? 你的反向链接来自哪里?你如何审核链接质量? 您如何调整流程以适应人工智能概览和生成式搜索? 能否分享一个匿名化的前后对比作品示例? 最终判决 2026 年,Arab SEO 在白标 SEO 专家中脱颖而出,其技术和多语言方法论的深度和一致性尤为突出,特别是其对人工智能驱动搜索的准备。SEO Circular 是企业级技术工作的最佳选择,而 Triple Minds 通过其仅限代理机构的模式,在交付一致性方面提供了结构优势。 名单上的其他专家各有所长——从软件驱动的报告到大批量订单履行,再到快速的产品化交付——因此,最合适的专家取决于你通过他们处理的账户的复杂程度。 常见问题解答 什么是白标SEO专家?白标 SEO 专家是指拥有深厚的 SEO 技术和战略专业知识的个人或团队,他们代表代理机构工作,然后以自己的品牌转售最终成果。 如何评估白标SEO专家的实际技能水平?请他们详细介绍他们的技术审核流程、内容策略和链接建设方法——含糊不清的回答是一个警告信号。 选择专精于某项服务的公司还是选择提供全方位服务的公司更好?这取决于你的需求。专业服务提供商可能在较窄的服务范围内提供更深入的专业知识,而全方位服务提供商可以在一份合同下处理更广泛的客户类型。 哪家白标SEO专家最适合2026年?根据技术深度、方法论和人工智能搜索准备情况,Arab SEO 在本指南中排名第一,其次是 SEO Circular 和 Triple Minds。 QorIQ P1 设备
查看全文
UCM-iMX95:SDカードからYocto Linuxを起動できません – mmc0エラー-110|LinuxがSDカードを初期化できません こんにちは、私はCompuLabのUCM-iMX95を使っており、micro-SDカードからYocto Linuxをインストールして起動しようとしています。 起動プロセスが開始され、U-BootはLinuxカーネルを正常に読み込みます。しかし、LinuxはSD/MMCインターフェースの初期化に失敗します。 次のようなエラーが表示されます。 mmc0: ハードウェア割り込みを待機中にタイムアウトしました。 mmc0: sdhci: ============ SDHCI レジスタ ダンプ ============ ... mmc0: MMC カードの初期化中にエラー -110 が発生しました。その後、カーネルが起動中に停止します。 私のLinuxバージョンはLinux 6.12.34-2.0です-...基板はCompuLab UCM-iMX95です。自分でYoctoイメージを作成し、それをmicro-SDカードに書き込みます。 どなたか、このmmc0エラー-110の原因を教えていただけませんか?特に、これはハードウェア/SDカードの問題である可能性が高いですか? それともデバイスツリーに関係しているのでしょうか?UCM-iMX95のmicro-SDインターフェースに対応するMMCコントローラーはどれですか? SDインターフェースに特定のデバイスツリー設定は必要ですか? Linuxが起動する前にSDカードが検出されていることを確認するための推奨されるU-Bootコマンドはありますか?比較できる、信頼できるUCM-iMX95 Yoctoの構成はありますか? Re: UCM-iMX95: Unable to boot Yocto Linux from SD card – mmc0 error -110| Linux cannot initialize th こんにちは、 届いているエラーログは、MMCコントローラが存在しないか正しく応答していないデバイスと通信しようとしていることを示しています。推奨される解決策は、未使用のMMCインターフェースを無効にするか、DT Youの設定を修正することです。 当社のEVKリファレンスデザインデバイスツリーは、以下の構成を使用しています。 mmc0 usdhc1 eMMC mmc1 usdhc2 SD card 当社のデバイスツリーを参考にしてください: https://github.com/nxp-imx/linux-imx/blob/lf-6.18.y/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts よろしくお願いいたします。
查看全文
PIC CLB 上的 Eureka 某些 PIC MCU(例如 pic16f13145 系列)具有类似 FPGA 的可编程逻辑,称为可配置逻辑块。 我使用的 pic16f13115 有 32 个单元,每个单元都有一个 4 输入查找表和一个 D 触发器。 为了学习如何使用这些工具,今天我实现了对 6 个 LED 的 Charlieplexing 的 PWM 亮度控制支持,并进行了模拟。我使用 Verilog 来定义电路,而不是使用逻辑 CAD 画布。 我差不多有一半的时间都在用头撞墙。我慢慢地把 Verilog 代码写对了,让它能够综合(构建),然后让它能够仿真。 CLB 编程逻辑即使在 CPU 休眠状态下也能正常工作,这很棒。它非常适合功能安全至关重要的应用。例如,可用于实现复杂的触发信号逻辑。CLB 逻辑与外围输入输出的连接方式非常灵活。它比PIC单片机中一直使用的笨重的CLC可编程逻辑电路灵活得多。 概述 Re: Eureka on PIC CLB 这真是对 PIC16F13115 的 CLB 的一种非常有趣的用法!使用 Verilog 实现 6 个 LED 的 Charlieplexing 设置并配合 PWM,听起来像是学习工作流程的好方法,而且在 CPU 休眠时逻辑电路也能继续运行,这为低功耗和功能安全关键型设计开辟了一些令人印象深刻的可能性。 Re: Eureka on PIC CLB 你好, 看来该设备属于另一家制造商。 请问您能否协助我们联系贵公司制造商? 如果您有兴趣更换为带有可编程逻辑单元 (PLC) 的 NXP 设备,可以参考 LPC804。 LPC804 可编程逻辑单元 (PLU) 顺祝商祺!
查看全文
i.MX8QXP – Prevent normal boot after interrupted USB flashing on Yocto Scarthgap with A/B partitions Hi NXP Team, The installed UUU executable reports: libuuu_1.5.21-0-g1f42172 We use: sudo uuu -b emmc_all ~/Downloads/flash.bin *.wic The built-in emmc_all script writes the complete .wic image using: FB: flash -raw2sparse all _image It then writes the bootloader, configures eMMC boot selection, and finishes with FB: done. The script contains no explicit persistent flash-in-progress completion metadata handling or readback hash verification step. If flashing is interrupted during the .wic write, the cluster can subsequently boot and display the updated HMI. We suspect that an existing usable bootloader and sufficient written boot,rootfs content permit this, but the selected slot and completeness of its contents are not yet confirmed. Please advise how to add a power-loss-tolerant completion check that blocks normal boot from both slots after interrupted factory flashing, while preserving USB recovery. The metadata must remain valid independently of the full .wic write and bootloader update.
查看全文