Multi Source Translation Content

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

Multi Source Translation Content

讨论

排序依据:
imx93でLPUART8を使用してコンソールを有効にする チームの皆さん、こんにちは。 i.MX93 EVKキットでは、 LPUART8をコンソールとして使用するボードを起動しようとしていますが、デフォルトのコンソールはLPUART1です。つまり、 u-boot dts、linux-imx dts、imx93_evk.c、imx93_evk.hで変更を行いました。 しかし、シリアルログを確認できず、EVKキットJ1001ヘッダーのピン32&33 (LPUART8のALTモード)を使用して確認しました。この設定も機能しません。変更内容と手順を教えてください。 よろしくお願いします。 ロビー Re: Enabling console using LPUART8 for imx93 こんにちは、 @AldoG さん。 LPUART8も使用しています 問題は、オプティーデバッグを有効にするとボードがハングアップして起動しないことです。CFG_TEE_CORE_LOG_LEVEL=3 U-Boot SPL 2024.04 (2026年3月27日 04:41:39 +0000) SOC: 0xa1009300 LC: 0x2040010 PMIC: オーバードライブ電圧モード Vx読み取りカウント(2728)がVxしきい値(1763)を超えているため、起動を続行します。 DDR: 3733MTS M33準備OK 通常起動 BOOTROMから起動しようとしています ブートステージ:プライマリブート 画像オフセット 0x0、ページサイズ 0x200、IVT オフセット 0x0 ROM_APIを使用して0x54000からイメージをロードします よろしくお願いいたします。 ラク**ブリープ** Re: Enabling console using LPUART8 for imx93 こんにちは、 今は動作してよかったですが、画像互換性については無理だと思います。たとえプロセッサがほぼ他のプロセッサよりダウングレードであっても、i.MX91用のイメージを自分で作成する必要がありますが、変更したもののほとんどは再利用できます。 よろしくお願いいたします。 アルド。 Re: Enabling console using LPUART8 for imx93 @AldoG さん、ありがとうございます。 今は正常に動作しています。i.mx93 イメージは imx91 と互換性がありますか。 よろしくお願いします。 ロビー。 Re: Enabling console using LPUART8 for imx93 こんにちは、 変更はすべて正しいです。ペリフェラルでクロックを有効にする設定が見落とされています。起動時にはデフォルトで有効になっていないためです。 /arch/arm/mach-imx/imx9/native/clock.c にて mxc_get_clock(enum mxc_clock clk)関数では、次のように追加します: リターンccm_clk_root_get_rate(LPUART8_CLK_ROOT); In Void init_uart_clk(U32インデックス)関数加算: CASE LPUART8_CLK_ROOT: /* 24歳男性 */ ccm_lpcg_on(CCGR_URT8、偽); ccm_clk_root_cfg(LPUART8_CLK_ROOT、OSC_24M_CLK、1); ccm_lpcg_on(CCGR_URT8、真); 休憩; また、/board/freescale/imx93_evk/imx93_evk.c でもご覧ください。 関数 int board_early_init_f(void) 加算: init_uart_clk(LPUART8_CLK_ROOT); この変更は同僚によって行われ、EVKで正しく動作しています。 よろしくお願いいたします。 アルド。 Re: Enabling console using LPUART8 for imx93 @AldoG さん、ありがとうございます。 応答に関しては、i.MX93 EVK はデフォルトのコンソール ポートとして LPUART1 を使用しますが、私のカスタム ボードは LPUART8 に設定されています。コンソールをLPUART1からLPUART8に変更し、ヘッダーJ1001を確認する必要があります。そのため、私は以下の変更を行いました。 u-boot-imx: lpuart8ノードを追加し、lpuart1とiomuxを無効にしました。 /configs/imx93_evk.h 内の "console= ttyLP7 ,115200 earlycon\0" \ を "ttyLP0" に変更しました。ファイル。 追加した static iomux_v3_cfg_t const uart_pads[] = { // MX93_PAD_UART1_RXD__LPUART1_RX | MUX_PAD_CTRL(UART_PAD_CTRL), // MX93_PAD_UART1_TXD__LPUART1_TX | MUX_PAD_CTRL(UART_PAD_CTRL), MX93_PAD_GPIO_IO13__LPUART8_RX | MUX_PAD_CTRL(UART_PAD_CTRL) MX93_PAD_GPIO_IO12__LPUART8_TX | MUX_PAD_CTRL(UART_PAD_CTRL) }; /imx93_evk/imx93_evk.c 内ファイル。 Linux-IMX: lpuart8ノードを追加し、lpuart1とiomuxを無効にしました。 imx.atf: /include/platform_def.h ファイル内の IMX_LPUART_BASE U(0x426a0000) を U(0x44380000) に変更しました。 メタフレッシュスケール: /conf/machine/imx93-11x11-lpddr4x-evk.conf 内の SERIAL_CONSOLES = "115200;ttyLP7" を変更しました。このファイルには、ヘッダーファイル /conf/machine/include/imx93-evk.inc が含まれています。 optee-os: set(CFG_UART_BASE UART1_BASE) を set(CFG_UART_BASE UART8_BASE) に変更しました。 詳細情報については、変更内容の画像を含むzipフォルダを追加してください。内容を確認して、最新情報をお知らせください。 よろしくお願いします。 ロビー よろしくお願いします。 ロビー Re: Enabling console using LPUART8 for imx93 こんにちは、 変更点を教えてもらえますか?正しく行っているか確認したいので。 また、使っているLinuxバージョンも教えてください。 よろしくお願いいたします。 アルド。 Re: Enabling console using LPUART8 for imx93 この問題の解決にご協力ください。すべてのパスを変更しました。
查看全文
S32 Design Studio for ARM v2.2 License Expired Hello, The license for S32 Design Studio for ARM v2.2 has expired. Please help extend the expired license: 9D36-2407-A13E-C846. flower_wee_0-1784000004900.png Re: S32 Design Studio for ARM v2.2 License Expired Hi,  your S32DS license has been extended. 
查看全文
How to change memory configuration after creating sample from MUCXpresso SDK? I know that when creating the sample from MCUXpresso SDK, we can config memory. But I created the sample, I changed many files in this sample and now I want to change memory configuration for my sample (I could not create new the sample, set memory and change files again because the number of changed files is very large). Whether I can config memory configuration after creating the sample and how? Thank you. I found this method Right click to project => Properties → C/C++ Build → MCU settings. Is that correct? Re: How to change memory configuration after creating sample from MUCXpresso SDK? Hi @nnxxpp , Thanks for your interest in NXP MIMXRT series! Yes, the memory configuration can be changed after the SDK example has been created. There is no need to recreate the project. And you may refer to this post: https://community.nxp.com/t5/MCUXpresso-General/MCUXpresso-Memory-map/m-p/1062500   After updating the Memory Configuration, please clean and rebuild the project, and verify the generated linker script and map file. This applies when the project uses MCUXpresso managed linker scripts. If a custom .ld file is used, please modify that linker script directly.  In addition, I’d like to mention the image view window provided by the IDE, which allows you to easily check whether the layout of the generated image meets your requirements: Gavin_Jia_0-1784016903983.png Best regards, Gavin Re: How to change memory configuration after creating sample from MUCXpresso SDK? @Gavin_Jia  Yes. Thank you, now I could config memory without recreating project.
查看全文
Enabling console using LPUART8 for imx93 Hi team,                  I'm trying to boot a board which uses LPUART8 as console but LPUART1 default console in i.MX93 EVK kit. So I had done the changes in u-boot dts, linux-imx dts,imx93_evk.c and imx93_evk.h. But unable to watch serial logs and same I checked using EVK kit J1001 header pin32&33 which are ALT modes of LPUART8. This configuration also doesn't work. Please let me know the changes need to be applied and also let me know the path. Thanks  Robbi Re: Enabling console using LPUART8 for imx93 Hi @AldoG , We are also using LPUART8 the issue is when we enable optee debug board hangs does not bootup, CFG_TEE_CORE_LOG_LEVEL=3 U-Boot SPL 2024.04 (Mar 27 2026 - 04:41:39 +0000) SOC: 0xa1009300 LC: 0x2040010 PMIC: Over Drive Voltage Mode Vx read count(2728) is greater than Vx threshold(1763) continue booting DDR: 3733MTS M33 prepare ok Normal Boot Trying to boot from BOOTROM Boot Stage: Primary boot image offset 0x0, pagesize 0x200, ivt offset 0x0 Load image from 0x54000 by ROM_API Thanks & Regards, Rak**bleep**h Re: Enabling console using LPUART8 for imx93 Hello, Glad that it is working now, regarding image compatibility I would say no, since even if the processor is practically a downgrade of the other it would require to create your own image for the i.MX91 but you may reuse almost all of your changes. Best regards/Saludos, Aldo. Re: Enabling console using LPUART8 for imx93 Thanks @AldoG ,                           It is working now. Is i.mx93 Image compactible for imx91. Thanks Robbi. Re: Enabling console using LPUART8 for imx93 Hello, All your changes are correct, you're missing some configuration for the clock to be enabled on the peripheral, since at boot time this is not being on by default. at /arch/arm/mach-imx/imx9/native/clock.c  in mxc_get_clock(enum mxc_clock clk) function add: return ccm_clk_root_get_rate(LPUART8_CLK_ROOT); in void init_uart_clk(u32 index) function add: case LPUART8_CLK_ROOT:  /* 24M */  ccm_lpcg_on(CCGR_URT8, false);  ccm_clk_root_cfg(LPUART8_CLK_ROOT, OSC_24M_CLK, 1);  ccm_lpcg_on(CCGR_URT8, true);  break; Also at /board/freescale/imx93_evk/imx93_evk.c in function int board_early_init_f(void) add: init_uart_clk(LPUART8_CLK_ROOT); This changes have been made and tested by a colleague and are working correctly on the EVK. Best regards/Saludos, Aldo. Re: Enabling console using LPUART8 for imx93 Thanks @AldoG ,                           For the response, i.MX93 EVK uses LPUART1 as default console port, but as my custom board is configured for LPUART8. I need to change my console from LPUART1 to LPUART8 and check in Header J1001. For that the modifications I had done: u-boot-imx: Added lpuart8 node and disabled lpuart1 along with iomux. changed "console=ttyLP7,115200 earlycon\0" \ from ttyLP0" in /configs/imx93_evk.h file. Added  static iomux_v3_cfg_t const uart_pads[] = { // MX93_PAD_UART1_RXD__LPUART1_RX | MUX_PAD_CTRL(UART_PAD_CTRL), // MX93_PAD_UART1_TXD__LPUART1_TX | MUX_PAD_CTRL(UART_PAD_CTRL),     MX93_PAD_GPIO_IO13__LPUART8_RX | MUX_PAD_CTRL(UART_PAD_CTRL),     MX93_PAD_GPIO_IO12__LPUART8_TX | MUX_PAD_CTRL(UART_PAD_CTRL), }; in /imx93_evk/imx93_evk.c file. linux-imx: Added lpuart8 node and disabled lpuart1 along with iomux. imx-atf: changed IMX_LPUART_BASE  U(0x426a0000) from  U(0x44380000) in /include/platform_def.h file. meta-fresscale: changed SERIAL_CONSOLES = "115200;ttyLP7" in /conf/machine/imx93-11x11-lpddr4x-evk.conf which includes header /conf/machine/include/imx93-evk.inc file. optee-os: changed set(CFG_UART_BASE UART1_BASE) to set(CFG_UART_BASE UART8_BASE). For more info add zip folder which contains images of changes done. Please go through it and let me know update. Thanks Robbi Thanks  Robbi Re: Enabling console using LPUART8 for imx93 Hello, Could you share the changes you have made, so I could check those are made correctly? Also, please share the Linux version you are working with. Best regards/Saludos, Aldo. Re: Enabling console using LPUART8 for imx93 Please help on this issue modified all paths.
查看全文
为 imx93 启用使用 LPUART8 的控制台 大家好, 我正在尝试启动一块使用LPUART8作为控制台的板子,但 i.MX93 EVK 套件中的默认控制台是 LPUART1 。所以我修改了u-boot dts、linux-imx dts、imx93_evk.c 和 imx93_evk.h文件。 但是无法查看串口日志,我使用 EVK 套件J1001 接头引脚 32 和 33进行了检查,它们是 LPUART8 的 ALT 模式。这种配置也不行。请告知需要进行的更改以及更改路径。 谢谢  罗比 Re: Enabling console using LPUART8 for imx93 嗨@AldoG , 我们还使用了LPUART8 问题是,启用 Optee 调试后,开发板卡死,无法启动,CFG_TEE_CORE_LOG_LEVEL=3 U-Boot SPL 2024.04(2026 年 3 月 27 日 - 04:41:39 +0000) SOC:0xa1009300 LC:0x2040010 PMIC:过驱动电压模式 Vx读取计数(2728)大于Vx阈值(1763),继续启动 DDR:3733MTS M33 准备就绪 正常启动 尝试从 BOOTROM 启动 启动阶段:主启动 图像偏移量 0x0,页面大小 0x200,ivt 偏移量 0x0 通过 ROM_API 从 0x54000 加载镜像 谢谢,此致敬礼! Rak**bleep**h Re: Enabling console using LPUART8 for imx93 你好, 很高兴它现在可以正常工作了,至于图像兼容性,我认为不行,因为即使处理器实际上是另一个处理器的降级版,也需要为 i.MX91 创建自己的图像,但您可以重复使用几乎所有的更改。 此致敬礼/Saludos, 阿尔多。 Re: Enabling console using LPUART8 for imx93 谢谢@AldoG , 现在可以正常运行了。i.mx93 镜像是否可与 imx91 镜像兼容? 谢谢! 罗比。 Re: Enabling console using LPUART8 for imx93 你好, 你的所有更改都是正确的,你缺少一些配置,无法在外部设备上启用时钟,因为在启动时,默认情况下时钟是关闭的。 在 /arch/Arm/mach-imx/imx9/native/clock.c 在 mxc_get_clock(enum mxc_clock clk) 函数中添加: 返回 ccm_clk_root_get_rate(LPUART8_CLK_ROOT); 在 void init_uart_clk(u32 index) 函数中添加: case LPUART8_CLK_ROOT: /* 24M */ ccm_lpcg_on(CCGR_URT8, false); ccm_clk_root_cfg(LPUART8_CLK_ROOT, OSC_24M_CLK, 1); ccm_lpcg_on(CCGR_URT8, true); 休息; 另请参阅板 /freescale/imx93_evk/imx93_evk.c 在函数 int board_early_init_f(void) 中添加: init_uart_clk(LPUART8_CLK_ROOT); 这些更改已由同事完成并测试,在 EVK 上运行正常。 此致敬礼/Saludos, 阿尔多。 Re: Enabling console using LPUART8 for imx93 谢谢@AldoG , 对于响应,i.MX93 EVK 使用 LPUART1 作为默认控制台端口,但我的定制板配置为使用 LPUART8。我需要将控制台从 LPUART1 更改为 LPUART8,并在 J1001 头文件中进行检查。为此,我做了以下修改: u-boot-imx: 添加了 lpuart8 节点,并禁用了 lpuart1 和 iomux。 在 /configs/imx93_evk.h 中将“console= ttyLP7 ,115200 earlycon\0”从 ttyLP0 更改为“文件。 额外 static iomux_v3_cfg_t const uart_pads[] = { // MX93_PAD_UART1_RXD__LPUART1_RX | MUX_PAD_CTRL(UART_PAD_CTRL), // MX93_PAD_UART1_TXD__LPUART1_TX | MUX_PAD_CTRL(UART_PAD_CTRL), MX93_PAD_GPIO_IO13__LPUART8_RX | MUX_PAD_CTRL(UART_PAD_CTRL), MX93_PAD_GPIO_IO12__LPUART8_TX | MUX_PAD_CTRL(UART_PAD_CTRL), };在 /imx93_evk/imx93_evk.c文件。 linux-imx: 添加了 lpuart8 节点,并禁用了 lpuart1 和 iomux。 imx-atf: /include/platform_def.h 文件中的 IMX_LPUART_BASE 从 U(0x44380000) 更改为 U(0x426a0000)。 元尺度: 在 /conf/machine/imx93-11x11-lpddr4x-evk.conf 中更改 SERIAL_CONSOLES = "115200;ttyLP7",该文件包含头文件 /conf/machine/include/imx93-evk.inc。 optee-os: 将 set(CFG_UART_BASE UART1_BASE) 改为 set(CFG_UART_BASE UART8_BASE)。 如需更多信息,请添加包含更改图片的压缩文件夹。请仔细阅读并告知我最新情况。 谢谢! 罗比 谢谢  罗比 Re: Enabling console using LPUART8 for imx93 你好, 能否分享一下您所做的更改,以便我检查是否正确? 另外,请分享一下您正在使用的Linux版本。 此致敬礼/Saludos, 阿尔多。 Re: Enabling console using LPUART8 for imx93 请帮忙解决这个问题,我已经修改了所有路径。
查看全文
S32 Design Studio for ARM v2.2 ライセンスが切れました こんにちは、 S32 Design Studio for ARM v2.2のライセンスは期限切れです。 期限切れのライセンス(9D36-2407-A13E-C846)の延長にご協力ください。 flower_wee_0-1784000004900.png Re: S32 Design Studio for ARM v2.2 License Expired こんにちは、 お客様のS32DSライセンスが延長されました。
查看全文
如何通过 MUCXpresso SDK 创建示例后更改内存配置? 我知道在使用 MCUXpresso SDK 创建示例时,我们可以配置内存。但是我已经创建了示例,并且更改了该示例中的许多文件,现在我想更改示例的内存配置(由于更改的文件数量非常大,我无法创建新示例、设置内存并再次更改文件)。 创建示例后是否可以配置内存配置?如何配置?谢谢。 我找到了这个方法:右键单击项目=>属性 => C/C++ 版本 => MCU 设置。这样对吗? Re: How to change memory configuration after creating sample from MUCXpresso SDK? 嗨@nnxxpp , 感谢您对 NXP MIMXRT 系列产品的关注! 是的,SDK 示例创建完成后,可以更改内存配置。无需重新创建该项目。 您还可以参考这篇帖子: https://community.nxp.com/t5/MCUXpresso-General/MCUXpresso-Memory-map/mp/1062500   更新内存配置后,请清理并重新构建项目,并验证生成的链接器脚本和映射文件。 这适用于项目使用 MCUXpresso 管理的链接器脚本的情况。如果使用自定义 .ld 文件,请直接修改该链接器脚本。 此外,我还想提一下IDE提供的图像查看窗口,它可以让您轻松检查生成的图像布局是否符合您的要求: Gavin_Jia_0-1784016903983.png 此致, 加文 Re: How to change memory configuration after creating sample from MUCXpresso SDK? @Gavin_Jia 是的,谢谢,现在我不用重新创建项目就能配置内存了。
查看全文
S32 Design Studio for ARM v2.2 许可证已过期 你好, S32 Design Studio for ARM v2.2 的许可证已过期。 请帮忙延长已过期的许可证:9D36-2407-A13E-C846。 flower_wee_0-1784000004900.png Re: S32 Design Studio for ARM v2.2 License Expired 你好, 您的S32DS许可证已延期。
查看全文
S32K144シリアル通信で受信したデータは抽出できません。 DWINタッチスクリーンとS32Kマイクロコントローラ間のシリアル通信リンク機能を開発しています。タッチスクリーンがデータを送信し、マイクロコントローラがデータを受信して判定する際に、判定のためにデータの9ビット目を抽出し、それに応じて異なるCANデータを送信したいと考えています。しかし、データの抽出がうまくいきません。経験豊富な開発者の方々からのご助言をいただければ幸いです。 ffdsg_0-1784107803435.png Re: S32K144串口通信接收的数据提不出 こんにちは、 @ffdsg さん。 DWINのタッチスクリーンの経験はありませんが、ざっと調べたところ、フレーム構造はフレーム終了時に「\n」マーカーを使わず、最初の2つのヘッダー(5AとA5)を送り、その後にフレームの長さ(06)を送信しているようです。 Julin_AragnM_0-1784234811870.png ですので、おそらくUARTコールバックを編集して、3バイト目で受信を止めることができるでしょう。例えば: void LPUART1_RX_ISR(void *driverState, uart_event_t event, void *userData) { (void)driverState; (void)userData; if (event == UART_EVENT_RX_FULL) { bufferIdx++; if (bufferIdx >= 3) { uint8_t frameLen = buffer[2]; /* number of bytes after length byte */ uint8_t totalLen = 3 + frameLen; /* header(2) + length(1) + payload */ if (bufferIdx >= totalLen) { /* Full frame received */ memcpy(rxdata, buffer, totalLen); keyNum = rxdata[8]; /* 9th byte*/ memset(buffer, 0, sizeof(buffer)); bufferIdx = 0; trigger = 1; LPUART_DRV_ReceiveData(INST_LPUART1, buffer, 1); return; } } LPUART_DRV_SetRxBuffer(INST_LPUART1, &buffer[bufferIdx], 1U); } } これにより、常に9バイト目を読み取ることができるようになります。 また、ルーチン内で以下の行をコメントアウトしています。 //if (keyNum==0X01) { つまり、9バイト目が何を言ってもCANメッセージは常に同じです。 残念ながら、DWINのタッチスクリーンはサードパーティ製デバイスであり、当社のサポート範囲外であり、当ハードウェアのルーチンは提供していません。これらの変更は、ご自身のシステム環境で実装およびテストする必要があります。 よろしくお願いします、 ジュリアン
查看全文
Does NXP offer a simple TSSOP28 breakout/adapter board for MC33XS2410 prototyping Hi everyone, We are currently setting up a prototyping and test bench for a 12V automotive project. Following NXP's recommendation, we selected the MC33XS2410 (eFuse) for our protection circuit. However, since we are in an assembly workshop and cannot design or manufacture custom PCBs at this stage, handling the HTSSOP28 package (with its 0.65mm pitch and thermal pad) is physically challenging for hand-wiring. While we are aware of the full-featured FRDM-XS2410EVB evaluation board, it is too complex, too large, and too expensive for our immediate needs on this specific test bench. We only need a minimal way to access the pins. Before we purchase a generic third-party adapter (like the Aries Electronics LCQT-TSSOP28 breakout board), we wanted to ask the NXP community: Does NXP offer a low-cost, minimal breakout board or prototyping adapter specifically designed to convert the HTSSOP28 package of the MC33XS2410 into standard 2.54mm DIP pins? If not, does NXP officially recommend any specific third-party adapter or socket brand that has been proven to work well with this chip (considering the ground and thermal dissipation requirements of the exposed center pad)? Thank you very much for your time and help! Evaluation Board StarCore DSPs Re: Does NXP offer a simple TSSOP28 breakout/adapter board for MC33XS2410 prototyping Thank you Tomas for the clarification and the precautions , i think that's the solution that i will do for my cards Re: Does NXP offer a simple TSSOP28 breakout/adapter board for MC33XS2410 prototyping Hello Mohamed, Currently we do not offer a dedicated low-cost breakout or adapter board that converts the MC33XS2410 HTSSOP28 package directly to a standard 2.54 mm DIP-style footprint. You are right that we offer the FRDM-XS2410EVB, which is intended for full functional evaluation rather than simple package adaptation. One important consideration is the exposed thermal pad of the MC33XS2410 package which should be soldered to GND for both thermal and electrical performance. We also recommend connecting the exposed pad to a ground plane and, for production designs, using thermal vias to improve heat dissipation. Please also note that generic breakout boards are generally suitable for functional prototyping and low-power bench testing. However, they typically do not provide the thermal performance achievable with a properly designed PCB, which may limit the maximum continuous current that can be tested.  If your application requires operation near the device's current limits, I recommend evaluating the thermal performance carefully or using the official evaluation board. BRs, Tomas
查看全文
使用 J-link 调试 S32K322 双核处理器 您好,恩智浦支持团队、 目标: S32K322S32K322 调试器硬件/软件:J-link/J-trace。 目前,我的应用程序用上市并点击 cm7_0 main,运行时 IDE 会挂起。 我希望您的专家指导进行双核调试,其中 core0 和 core1 独立运行,RESET core1 不会 RESET core0,反之亦然。 如何在 core1 应用程序中设置断点? 目前我使用的是下面附带的应用程序。 我想做的是,core0 通过 UART 进行通信,而 core1 则切换 LED。代码并不完整,但您仍可参考。 此外,我还想知道,如果我从 core0 初始化 UART0,从 core1 初始化 UART1,会不会引起任何问题。 如果我为 core0 和 core1 使用不同的 GPIO 配置,它们会相互冲突吗? 谢谢  Re: S32K322 Dual Core debugging with J-link 你好@AbdNxp、 是的,我可以使用 S32DS IDE 的 J-trace 调试多核应用程序。 很遗憾,我现在没有 S32K322 HW。 在这里,你可以看到两个内核在不同的闪存块中工作,这与你发布的截图不同。 danielmartynek_0-1757078605716.png 我尝试在 S32K324 上加载您的应用程序,这应该是可行的,但我得到的错误与您的不同。 第二个核心的调试配置应禁用此功能: danielmartynek_1-1757078876713.png 但你在项目中已经做到了。 此致, 丹尼尔 Re: S32K322 Dual Core debugging with J-link 嗨,丹尼尔 那么您能用 J-link/J-trace Pro 运行应用程序吗? 我试了很多次,都无法让它运行。 Re: S32K322 Dual Core debugging with J-link 你好@AbdNxp、 我仍然无法重现这个问题。 但请注意,在 S32DS 集成开发环境中,该功能由 SEGGER 插件提供。 我建议您也联系世纪佳缘的支持人员。 谢谢 Re: S32K322 Dual Core debugging with J-link 嗨,丹尼尔 附上项目。 Re: S32K322 Dual Core debugging with J-link 你好@AbdNxp、 我无法重现这种行为。 看来 CM7_1 的第二个调试会话调试的代码与第一个调试会话调试的代码来自同一内存区域 (0x400000)。 能否分享一下测试项目? 谢谢 Re: S32K322 Dual Core debugging with J-link 我已经使用了群组调试,问题是 S32DS Ide 在调试过程中被挂起或无响应。 见下图 AbdNxp_1-1755583551737.png AbdNxp_0-1755583463815.png 此外,如果我在 CM7_1 中点的 While(1 ) 循环中的某个地方设置断点,断点也不会出现。 Re: S32K322 Dual Core debugging with J-link 你好@AbdNxp、 S32 Design Studio 中的 SEGGER 插件支持启动调试组,可同时对多个内核进行编程和调试。 https://community.nxp.com/t5/S32K/How-to-Use-Jlink-to-Debug-S32K324-Dual-Core-On-S32KDS3-5/td-p/1924460 ... RESET core1 不会 RESET core0,反之亦然。 尽管采用双核架构,但您无法在另一个内核继续运行的同时独立 RESET 一个内核。此限制是由于 S32K3xx 系列的共享 RESET 架构造成的。RESET事件会影响两个内核,因此在调试期间无法进行单独的内核RESET。 此外,我还想知道,如果我从 core0 初始化 UART0,从 core1 初始化 UART1,会不会引起任何问题。 如果我为 core0 和 core1 使用不同的 GPIO 配置,它们会相互冲突吗? 您可以放心地从 CM7_0 初始化 UART0,从 CM7_1 初始化 UART1。只要每个内核访问其指定外设时没有重叠,这种设置就有效。 要强制执行内核之间的访问控制,您可以配置 XRDC(扩展资源功能域控制器): 为 CM7_0 和 CM7_1 创建单独的功能域。 将 LPUART 模块和 GPIO 等外围设备分配给特定功能域。 这确保 CM7_0 无法访问 CM7_1 的资源,反之亦然。 此致, 丹尼尔 Re: S32K322 Dual Core debugging with J-link 这个问题解决了吗?我在使用 J-Link 对 S32K388 进行调试时也遇到了这个问题。即使我的单核链接文件设置为默认值 0x00800000,运行时程序计数器 (PC) 仍然显示 0x402624(这是零核的闪存地址)。#s32k388
查看全文
The S32K144 serial communication received data cannot be extracted. I'm working on a microcontroller serial communication linkage function between a DWIN touchscreen and an S32K microcontroller. When the touchscreen sends data and the microcontroller receives and judges the data, I want to extract the 9th bit of the data for judgment and to send different CAN data accordingly. However, I'm unable to successfully extract the data. I would appreciate any guidance from experienced developers. ffdsg_0-1784107803435.png Re: S32K144串口通信接收的数据提不出 Hello @ffdsg, I have no experience with DWIN touchscreens, however, from a quick search, it seems that the frame structure does not use the '\n' marker for end-of-frame, rather it sends the first two headers (5A & A5), followed by the length of the frame (06). Julin_AragnM_0-1784234811870.png So, most likely you can edit your UART callback to stop reception with the third byte, something like so: void LPUART1_RX_ISR(void *driverState, uart_event_t event, void *userData) { (void)driverState; (void)userData; if (event == UART_EVENT_RX_FULL) { bufferIdx++; if (bufferIdx >= 3) { uint8_t frameLen = buffer[2]; /* number of bytes after length byte */ uint8_t totalLen = 3 + frameLen; /* header(2) + length(1) + payload */ if (bufferIdx >= totalLen) { /* Full frame received */ memcpy(rxdata, buffer, totalLen); keyNum = rxdata[8]; /* 9th byte*/ memset(buffer, 0, sizeof(buffer)); bufferIdx = 0; trigger = 1; LPUART_DRV_ReceiveData(INST_LPUART1, buffer, 1); return; } } LPUART_DRV_SetRxBuffer(INST_LPUART1, &buffer[bufferIdx], 1U); } } This should make sure you are always reading the 9th byte. Also, inside your routine, you have commented out the following line: //if (keyNum==0X01) { Meaning that the CAN message is always the same, no matter what the 9th byte says. Unfortunately, DWIN touchscreens are third party devices, out of our support scope, and we do not provide any routines with said hardware. You will need to implement and test these changes with your setup. Best regards, Julián
查看全文
S32K144串口通信接收的数据提不出 在做一个迪文屏和s32k的单片机串口通信联动的功能,触摸屏发送数据单片机接收并进行判断时,想通过提取数据第9位进行判 断并实现不同的can数据发送,但无法成功提取数据,希望各位前辈们指点一下 ffdsg_0-1784107803435.png Re: S32K144串口通信接收的数据提不出 你好@ffdsg , 我没有使用 DWIN 触摸屏的经验,但是通过快速搜索,似乎帧结构不使用“\n”标记表示帧结束,而是发送前两个标头(5A 和 A5),然后是帧的长度(06)。 Julin_AragnM_0-1784234811870.png 所以,你很可能可以通过编辑 UART 回调函数,用第三个字节停止接收数据,就像这样: void LPUART1_RX_ISR(void *driverState, uart_event_t event, void *userData) { (void)driverState; (void)userData; if (event == UART_EVENT_RX_FULL) { bufferIdx++; if (bufferIdx >= 3) { uint8_t frameLen = buffer[2]; /* number of bytes after length byte */ uint8_t totalLen = 3 + frameLen; /* header(2) + length(1) + payload */ if (bufferIdx >= totalLen) { /* Full frame received */ memcpy(rxdata, buffer, totalLen); keyNum = rxdata[8]; /* 9th byte*/ memset(buffer, 0, sizeof(buffer)); bufferIdx = 0; trigger = 1; LPUART_DRV_ReceiveData(INST_LPUART1, buffer, 1); return; } } LPUART_DRV_SetRxBuffer(INST_LPUART1, &buffer[bufferIdx], 1U); } } 这样可以确保你始终读取第 9 个字节。 另外,在你的例程中,你注释掉了以下这行代码: //if (keyNum==0X01) { 这意味着无论第 9 个字节是什么,CAN 消息始终保持不变。 遗憾的是,DWIN 触摸屏是第三方设备,不在我们的支持范围内,我们不提供任何与该硬件相关的程序。您需要在自己的环境中实施并测试这些更改。 此致, 朱利安
查看全文
S32K322 デュアルコアの J-link によるデバッグ こんにちは、NXPサポートチームの皆様。 ターゲット: S32K322 デバッガー H/W: J-link/J-trace。 現在、アプリケーションが起動して cm7_0 main に到達し、実行すると IDE がハングします。 core0 と core1 が独立して実行され、core1 をリセットしても core0 はリセットされず、その逆も同様であるデュアル コアのデバッグを行うために専門家の指導が欲しかったです。 core1 アプリケーションにブレークポイントを設定する方法。 現在、下記に添付されているアプリケーションを使用しています。 私がやろうとしているのは、core1 が LED を切り替える間に core0 が UART で SO 通信を行うことです。コードはまだ完全ではありませんが、参照することは可能です。 さらに、UART0 を core0 から初期化し、UART1 を core1 から初期化すると、何か問題が発生するかどうかも知りたいです。 core0 と core1 に異なる GPIO 構成を使用した場合、競合が発生しますか? よろしくお願いします。 Re: S32K322 Dual Core debugging with J-link こんにちは@AbdNxpさん、 はい、S32DS IDE から J-trace を使用してマルチコア アプリケーションをデバッグできます。 残念ながら、現在 S32K322 HW を持っていません。 ここでは、投稿したスクリーンショットとは異なり、両方のコアが異なるフラッシュ ブロックで動作していることがわかります。 danielmartynek_0-1757078605716.png S32K324 にアプリケーションをロードしようとしましたが、可能なはずですが、異なるエラーが発生しました。 2 番目のコアのデバッグ構成では、これを無効にする必要があります。 danielmartynek_1-1757078876713.png しかし、プロジェクトにはそれがあります。 よろしくお願いいたします。 ダニエル Re: S32K322 Dual Core debugging with J-link こんにちは、ダニエル。 SO、J-link/J-trace Pro でアプリケーションを実行できるのですか? 何度か試してみましたが、実行できませんでした。 Re: S32K322 Dual Core debugging with J-link こんにちは@AbdNxpさん、 まだ問題を再現できません。 ただし、S32DS IDEs では、この機能は SEGGER プラグインによって提供されることに注意してください。 SEGGER サポートにも問い合わせることをお勧めします。 よろしくお願い申し上げます。 Re: S32K322 Dual Core debugging with J-link こんにちは、ダニエルさん プロジェクトを添付しました。 Re: S32K322 Dual Core debugging with J-link こんにちは@AbdNxpさん、 この動作を再現できません。 CM7_1 の 2 番目のデバッグ セッションでは、最初のデバッグ セッションと同じメモリ領域 (0x400000) からコードをデバッグするようです。 CANテストプロジェクトを共有していただけますか? よろしくお願い申し上げます。 Re: S32K322 Dual Core debugging with J-link 私はすでにグループデバッグを使用していますが、問題はデバッグセッション中に S32DS IDEs がハングしたり応答しなくなったりすることです。 下の画像をご覧ください AbdNxp_1-1755583551737.png AbdNxp_0-1755583463815.png また、CM7_1 のポイントの While(1) ループのどこかにブレークを配置しても、ブレーク ポイントはヒットしません。 Re: S32K322 Dual Core debugging with J-link こんにちは@AbdNxpさん、 S32 Design Studio の SEGGER プラグインはデバッグ グループの起動をサポートしており、複数のコアを同時にプログラムおよびデバッグできます。 https://community.nxp.com/t5/S32K/How-to-Use-Jlink-to-Debug-S32K324-Dual-Core-On-S32KDS3-5/td-p/1924460 ... core1 をリセットしても core0 はリセットされず、その逆も同様です。 デュアルコア アーキテクチャにもかかわらず、一方のコアが実行を継続している間にもう一方のコアを個別にリセットすることはできません。この制限は、S32K3xx ファミリの共有リセット アーキテクチャによるものです。リセットイベント情報 は両方のコアに影響するため、デバッグ中に個別のコア リセットを行うことは不可能になります。 さらに、UART0 を core0 から初期化し、UART1 を core1 から初期化すると、何か問題が発生するかどうかも知りたいです。 core0 と core1 に異なる GPIO 構成を使用した場合、競合が発生しますか? CM7_0 から UART0 を、CM7_1 から UART1 を安全に初期化CAN。この設定は、各コアが重複することなく指定されたペリフェラルにアクセスする限り有効です。 コア間のアクセス制御を強制するには、XRDC (eXtended Resource Domain Controller) を構成できます。 CM7_0 と CM7_1 に個別のドメインを作成します。 LPUART モジュールや GPIO などのペリフェラルを特定のドメインに割り当てます。 これにより、CM7_0 は CM7_1 のリソースにアクセスできなくなり、その逆も同様になります。 よろしくお願いいたします。 ダニエル Re: S32K322 Dual Core debugging with J-link この問題は解決しましたか?私もS32K388のデバッグにJ-Linkを使用していた際に、同様の現象に遭遇しました。1コアリンクファイルはデフォルト0x00800000に設定されていますが、PCは実行時に0x402624を表示します(これは0コアのフラッシュアドレスです)#s32k388
查看全文
NFC Reader Library Migration to FRDM-MCXN947 on VS code Introduction. This document provides a guide on how to use the NFC frontend PN5190 with the FRDM-MCXN947 and using the NFC Reader Library. The hardware required to follow this guide is: FRDM-MCXN947 development board as host MCU. PNEV5190BP (based on PN5190) as the NFC transceiver Software Setup. MCXN947 SDK version: 26.03.00 NFCReaderLibrary version: 07.14.00 PN5190 FW version: 0x20D Hardware connections. The PNEV5190 comes with a Kinetis K82F as a host MCU to drive the PN5190 Since the goal is to drive PN5190 from the MCXN947 via SPI, we need to prepare the PNEV5190 for it: Power up board correctly Enable external SPI pins Disable K82F interface with PN5190 Power up and jumper configuration To power up the board correctly: – Powering it up over USB does not provide enough current. It will be powered with an external power supply of 7.5V over connector J17. Put jumper on following pins: – J9 2-3: External power supply – J8: VBATPWR supplied with VBAT=3.3 V – J12: VBAT supplied with 3.3 V Remove jumpers on following pins: – J22, J23: open SDA signals for K82F – J19: RTS push-button bypass for K82F – J3, J4, J5, J6: pull down jumpers for NFC module signals   Set GPIO and SPI voltage to 3.3 V: supplying 3.3 V to VDDIO and the μC supply: – Remove short circuit on R19 – Place short circuit on R20 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.png Routing NFC module communication pins to JP1 To enable the pins on JP1 for communication, we must enable bus switch U10 and disable bus switch U12 in the NFC Host Interface. These switches enable or disable the connections from K82 to PN5190 SPI pins, and expose the SPI interface to an external host. Remove short on R5 to disable communication routing to K82F. Place short on R7 to enable communication routing to JP1 pins. Habib_MS_1-1782499777420.png For FRDM-MCXN947 side, no modifications are necessary.  The pins used are available in Header J1 and J2. Which are shown in the following table.     Name MCXN947 PN5190 SCK J2.12 JP1.1 MOSI J2.8 JP1.2 MISO J2.10 JP1.3 SSEL J2.6 JP1.4 IRQ J1.16 JP1.5 RESET J2.2 JP6.1 GND J2.14 JP1.10 SUCCESS J2.17* FAIL J2.15* DWL J2.13* * Pins that need to be configured for library compatibility but are not used and do not need to be connected. Software Changes This section describes the software changes required to run the “NfcrdlibEx1_DiscoveryLoop” example from the NFC Reader Library which consists in a detection loop that displays in a terminal information (like UID, SAK, and Product Type for MIFARE product-based cards) about any tag detected by the PN5190. Please download the NFC Reader Library for PN5190 from NFC Reader Library | NXP Semiconductors To begin with the integration, we first need to import a “hello_world” project from the FRDM MCXN 947 SDK (v26.03.00) into the MCUXpresso IDE for VS code, for this purpose download and install the FRDM-MCXA156 repository (version 26.03) from the extension in quickstart panel-> import repository. For more information about this process, you can consult this guide. Importing NFC Reader library. Download the “NFC Reader Library” zip from the product page and extract in a known folder. This will be useful for later use.  Importing base project 1. In the Quick Start panel click on “Import Example from Repository” in VS code. Habib_MS_0-1782500337538.png 2. Select “FRDM-MCXN947” in board setting. Habib_MS_1-1782500355284.png 3. In the template will search for the “freertos_hello_cm33_core0” example, select Freestanding Application, chose the location and click on “import”. Habib_MS_2-1782500369308.png Importing SDK drivers Once the project is added to the workspace we will need to add the required drivers, which are SPI, CTIMER and CMSIS drivers. For this we need to add the following code in the prj.cfg file. Habib_MS_3-1782500385724.png Spoiler (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.14.00_PUB” extracted, find and drag and drop the following files on in the project files folder: NfcrdlibEx1_EmvcoProfile.c, phApp_Helper.c, phApp_Init.c, phApp_PN5190_Init.c. You can find these files in the following path: {NxpNfcRdLibRoot} \Examples\NfcrdlibEx1_DiscoveryLoop\src Habib_MS_2-1782504550792.png When you drag and drop a file into VS code a window will appear asking whether you want to link the file or copy it. Please select “Copy files.” Habib_MS_3-1782504569947.png After dragging and dropping any file, the CMakeLists.txt file is automatically updated to include all the copied .c files. If you selected all these files, the generated code will appear as follows: Habib_MS_4-1782504588274.png Additionally, we need to add the file “NfcrdlibEx1_DiscoveryLoop.c” which is the main source file of the project, to achieve this also please drag and drop in the project files folder. Habib_MS_5-1782504604217.png At this point, the project should look like this:        Habib_MS_6-1782504632756.png Add the example source code to the newly created MCXN947 project From the “NxpNfcRdLib_PN5190_v07.14.00_PUB” extracted just drag and drop in the project files folder the following folders. Habib_MS_0-1782504704260.png Habib_MS_1-1782504734285.png Habib_MS_2-1782504750818.png Habib_MS_3-1782504795659.png Once these folders are added the project should look like this: Habib_MS_0-1782506609973.png Define FRDM-MCXN947 SDK preprocessor symbol We need to make some changes to the compiler preprocessor configuration related to the NFC reader library, to do this we need to modify the Cmakelist.txt PH_OSAL_FREERTOS PHDRIVER_FRDMMCXN947_PN5190_BOARD NXPBUILD_CUSTOMER_HEADER_INCLUDED PHDRIVER_MCXN947_SPI_POLLING Habib_MS_0-1782505699286.png Spoiler (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.png 2. Write the file’s name as follows (Board_FRDM_MCXN947_PN5190.h) and click enter: Habib_MS_2-1782505345384.png A window like the one shown in the following figure will appear. However, it can be discarded. This window is intended to add the newly created file to the CMakeLists.txt file, but we will instead include the entire folder later. Habib_MS_3-1782505364793.png Inside this file, some important macros related to the SPI peripheral and the important pins to be handled (IRQ, Chip Select, Reset) are defined. Habib_MS_4-1782505388079.png Spoiler (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.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.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.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.png   2. A window as the following figure will appear, please click on “Move to Recycle Bin”: Habib_MS_2-1782505893781.png 3. In the same folder please right-click and click on “New folder…”: Habib_MS_3-1782505917835.png 4. Write the folder’s name as follows (MCXN947) and click enter: Habib_MS_4-1782505943176.png 5. Add both files following the same steps mentioned in the section Board_FRDM_MCXN947_PN5190.h but with those files (phbalReg_Mcxn947Spi.c and phDriver_Mcxn947SDK.c). We will add these source files in the CMake_List.txt on the next step. Once these files are added the src folder should look like this: Habib_MS_5-1782505974388.png 6. Finally, we will add both files to the CMakeLists.txt file so they are included in the compilation process. Please add the following code in the CMake_list.txt file: Habib_MS_6-1782505996170.png Spoiler (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. Inside these source files we will modify the functions from the source files of other board hosts with the specific configurations of MCXN947 peripheral drivers, such as SPI, timers, GPIOs and interrupt handlers. This is done based on SDK examples such as “ctimer_match_interrupt_example_cm33_core0” and “lpspi_polling_b2b_transfer_master_cm33_core0”. phbalReg_Mcxn947Spi.c: In this file we first need to include the necessary files and include the headers and callbacks to ensure the correct functionality: Habib_MS_1-1782506156720.png Spoiler (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.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.png   Habib_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.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.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.png Habib_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.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_5-1782506864713.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_6-1782506901116.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_7-1782506942143.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.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.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.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.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.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.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.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.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.png Habib_MS_8-1782508012260.png Habib_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-1782508183634.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 CMake_List.txt As mentioned previously, the CMake_List.txt is automatically updated when you copy a .c file. However, .h files are not automatically linked, so they must be added manually. Please copy and paste the following includes into the CMakeLists.txt file: Habib_MS_0-1782508446885.png Spoiler (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.png Testing Final Project with FreeRTOS After making all the previous changes and modifications, the migration is now complete, and we can proceed to compile and flash the example to MCXN947. Please “clean” the project before building by right clicking on the project as follows: Habib_MS_3-1782508554465.png To run the project, we will need a serial terminal like Tera Term with the following settings: - 115200 baud rate. - 8 data bits. - No parity. - One stop bit, - No flow control. Once the program is flashed and the serial terminal configured, we can reset the board and power the PNEV5190BP. You should see an output similar to the following: Habib_MS_4-1782508585568.png Now if any NFC tag is close to the PNEV5190BP’s antenna, you should see the information displayed as shown in the image below: Habib_MS_5-1782508604979.png Changing OS preprocessor macro This section presents the steps to follow to add the possibility of easily choosing whether to have OS support or not.  This guide is based as default with FREERTOS, but the NFC reader library offers the possibility to run without OS, firstly, we need to change the preprocessor macro PH_OSAL_FREERTOS to PH_OSAL_NULLOS in the CMakeList.txt, as shown the following image: Habib_MS_6-1782508642319.png Finally, to avoid multiple definition issues when we change between NULLOS and FREERTOS, we will discard the SysTickHandler for FREERTOS side located in port.c when the NULLOS macro is defined, to achieve this we need to add a replacement of the file port.c since the included FreeRTOS is shared with all projects of the repository, and if we modify this file, it will be modified in all projects. 1. Go to the explorer window, right-click on the project and click on “New File…”. Habib_MS_7-1782508678537.png 2. Write the file’s name as follows (port.c) and click enter: Habib_MS_8-1782508703600.png 3. Add this file into the CMakeList.txt file to include port.c into the compilation process: Habib_MS_9-1782508775980.png Spoiler (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: {PrjRootDirPath}\mcuxsdk\mcuxsdk\rtos\freertos\freertos-kernel\portable\GCC\ARM_CM33_NTZ\non_secure Habib_MS_10-1782508828714.png 5. Replace the SysTick_Handler() of the port.c we created to the following function: Habib_MS_11-1782508854714.png Spoiler (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_12-1782508890989.png Spoiler (Highlight to read) mcux_project_remove_source( BASE_PATH ${SdkRootDirPath}/rtos/freertos/freertos-kernel/portable/GCC/ARM_CM33_NTZ/non_secure SOURCES port.c ) mcux_project_remove_source( BASE_PATH ${SdkRootDirPath}/rtos/freertos/freertos-kernel/portable/GCC/ARM_CM33_NTZ/non_secure SOURCES port.c ) Please rebuild and test as the steps mentioned in the section Testing Final Project with FreeRTOS. NFC Reader Library
查看全文
Software & Hardware Enablement for the Dual-Motor EV Control System 1 Introduction Turning a motor control concept into a running dual-motor traction real system requires more than a control algorithm. It requires a connected software and hardware environment that can take the design from simulation to generated code, from target deployment to real-time calibration, and finally to validation on physical motors. This article continues the Motor Control System series by moving from the system-level overview to the enablement layer behind the application. It highlights the MathWorks and NXP tools, software components, MCU resources, and power-stage building blocks that make the Dual-Motor EV traction system possible. At the core of the workflow is Model-Based Design. MathWorks tools are used to model the field-oriented control algorithms, define the CAN communication interfaces, and support validation across simulation stages. NXP tools then bring those models onto the S32K396 target platform, connecting the generated application to real-time peripherals, gate-driver hardware, and motor feedback signals. Together, these elements form the development backbone of the dual-motor application: a path that starts with definition of the control strategy and ends with validation on real hardware. 2 Table of Contents • Software • Hardware • References • Conclusion 3 Software The software environment provides the modeling, simulation, communication, code generation, and deployment capabilities required by the Motor Control System. Each tool contributes a specific part of the development flow. 3.1. Motor Control Blockset mcb.png Motor Control Blockset is the control-algorithm engine behind the traction application. It provides a ready-to-use environment for designing, simulating, and deploying motor control algorithms, while also supporting optimized C code generation from Simulink. In this Motor Control System, the MCB models the Field-Oriented Control strategy for Permanent Magnet Synchronous Motors. It supports the main control-loop blocks. These include Clarke and Park transforms, current and speed regulation, Space Vector Modulation, and position or speed feedback processing. The same model can run across desktop simulation and real-time validation. This keeps the controller consistent from early algorithm work to target execution. It also aligns the design across Model-in-the-Loop, Software-in-the-Loop, Processor-in-the-Loop, and hardware deployment stages. For more information, see the Motor Control Blockset documentation in the References chapter. 3.2. Vehicle Network Toolbox vnt.png Vehicle Network Toolbox brings CAN communication into the model-based workflow. It provides MATLAB functions and Simulink blocks for sending, receiving, encoding, and decoding CAN messages. This makes network behavior visible and testable before deployment. In the Motor Control System, CAN exchanges commands, feedback, and status information. It links the ECU with the surrounding vehicle architecture. The toolbox helps define the signal interface, pack and unpack CAN frames, simulate bus traffic, and validate communication behavior before target execution. Communication is not treated as a late integration step. CAN interaction can be simulated and verified together with the control model. This reduces integration risk and makes ECU behavior easier to validate end to end. For more information, see the Vehicle Network Toolbox documentation in the References chapter. 3.3. NXP Model-Based Design Toolbox for S32K3 mbdt.png NXP Model-Based Design Toolbox for S32K3 connects the Simulink model to the NXP S32K3 target environment. It provides the embedded target support required to generate, build, download, and run applications on NXP microcontrollers. The toolbox provides peripheral blocks for hardware access. These include interfaces for ADC, PWM, CAN, SPI, UART, timers, interrupts, and other target resources used by motor control applications. For the Motor Control System, the toolbox enables the generated application to run on top of the S32K3 software stack. It also supports configuration flows based on NXP tools, real-time data visualization with FreeMASTER, and integration with optimized libraries such as AMMCLib. NXP Model-Based Design Toolbox for S32K3 is used as part of the enablement environment for the S32K3 complex applications. It provides the bridge between the model and the production-oriented embedded implementation. 4 Hardware The hardware environment provides the real-time execution platform and the power stage interface required to control the motors. The key hardware components are the NXP S32K396 microcontroller and the NXP MC33937 three-phase FET pre-driver. 4.1. The NXP S32K396 Microcontroller The NXP S32K396 is the main processing device used by the Motor Control System. It belongs to the S32K39 family of electrification microcontrollers and is optimized for traction inverter, torque vectoring, and smart actuation applications. The device combines real-time compute, motor control acceleration, advanced analog acquisition, high-resolution actuation, safety mechanisms, security services, and automotive networking in a single MCU platform. At the compute level, the S32K396 provides Arm Cortex-M7 processing resources running up to 320 MHz. The architecture supports safety-oriented execution through lockstep and split-lock configurations. This enables separation between safety-critical motor control tasks and additional monitoring or communication functions. For motor control, the device includes a dedicated motor control coprocessor called eTPU (Enhanced Time Processing Unit) and a programmable CoolFlux DSP. These resources can offload timing-critical functions from the main CPU. They support fast current-loop execution, resolver processing, PWM generation, analog sensing, and other functions required by high-performance FOC applications. The smart timer and I/O subsystem is also important for traction control. The S32K396 includes eFlexPWM modules with NanoEdge capability, eMIOS channels, Logic Control Units, and Body Cross-Triggering Units. These blocks help synchronize PWM generation, ADC triggering, fault handling, and real-time control events. The analog subsystem supports the feedback path of the inverter. It includes multiple SAR ADCs, Sigma-Delta ADCs, analog comparators, and sine wave generators. These resources are used to acquire phase currents, DC bus voltage, phase voltages, temperature signals, and position-related feedback. The communication subsystem enables integration with the vehicle network and external devices. The S32K396 provides CAN FD, Ethernet with TSN support, LIN/UART, SPI, I2C, QSPI, FlexIO, and Zipwire interfaces. In this Motor Control System, CAN is used for vehicle-level command and status exchange. s32k396_block_diagram.png Figure 4-1. S32K396 Block Diagram In the Motor Control System, the S32K396 executes the real-time control loops, reads current and voltage feedback, processes rotor position or speed information, generates PWM signals, and exchanges data with the vehicle network over CAN. The same platform can support one six-phase motor or two three-phase motors. This makes it suitable for the dual rear-motor architecture used throughout this article series. 4.2. The NXP MC33937 Three-Phase FET Pre-Driver The NXP MC33937 is the three-phase Field Effect Transistor pre-driver used between the microcontroller and the inverter power switches. It is designed for three-phase motor control and similar automotive actuation applications. The device contains three high-side FET pre-drivers and three low-side FET pre-drivers. Together, these six gate-drive channels control the external MOSFET bridge used by the three-phase inverter. The MC33937 interfaces with the S32K396 through six direct input control signals. These signals provide the fast phase control path from the PWM outputs of the microcontroller to the gate-driver stage. The device also includes an SPI interface. SPI is used for device setup, configuration, diagnostics, and safe control features. Reset, enable, and interrupt pins provide additional control and fault signaling between the pre-driver and the MCU. The MC33937 supports an extended operating range from 6 V to 58 V and is fully specified from 8 V to 40 V. This makes it suitable for 12 V and 24 V automotive systems, as well as higher-voltage transient operating conditions. The MC33937 also provides protection and monitoring features needed in motor control applications. These include undervoltage detection, overcurrent comparison, desaturation comparison, temperature limitation, phase voltage comparison, and protection against reverse charge injection from the external FETs. The device accepts both 3.3 V and 5 V logic-level inputs and provides 5 V logic-level outputs. This simplifies the connection with automotive microcontrollers and allows the pre-driver to fit into different control board designs. mc33937_block_diagram.png Figure 4-2. MC33937 Block Diagram In the Motor Control System, the MC33937 forms the actuation bridge between the PWM signals generated by the S32K396 and the three-phase inverter that drives each PMSM. It converts logic-level control commands into the gate-drive signals required by the external power stage. 4.3. NXP Evaluation Boards The Motor Control System hardware is built from modular NXP evaluation boards. This allows the same S32K396 control platform to be connected to one or two low-voltage three-phase inverter stages. s32k396_bga_dc1.png Figure 4-3. NXP S32K396-BGA-DC1 The S32K396-BGA-DC1 evaluation board is the main controller board. It contains the S32K396 microcontroller in MAPBGA 289 package, an onboard debugger, communication interfaces, and the connectors required to access the real-time control signals. It is optimized for electrification applications such as traction drive and torque vectoring. The S32X-MB board is used as an I/O extension board. It is not a standalone development board. It must be used together with a compatible S32K39/37 evaluation board. In this setup, it expands the number of accessible peripherals and provides an additional motor control connector. s32x_mb.png Figure 4-4. S32X-MB Board The MCSPTR2AK396 kit provides the low-voltage motor control power stage used in the demo. From this kit, the demo uses the three-phase low-voltage pre-driver board and the PMSM motor. The power stage is based on the MC33937A pre-driver and is designed for BLDC or PMSM control. mcsptre2ak396.png Figure 4-5. 3-Phase Low Voltage Motor Control Kit The kit also provides useful motor control interfaces. These include the three-phase motor output, Hall or encoder interface, resolver interface, DC bus sensing, phase voltage sensing, and protection feedback. These signals are required to close the control loop on the target hardware. 4.4. Dual-Motor Hardware Connections For the dual-motor hardware set-up, the S32K396-BGA-DC1 board provides the main MCU resources. The first three-phase motor control channel is connected through the primary motor control connector. The second channel is routed through the S32X-MB extension board. Each motor channel uses one low-voltage three-phase pre-driver and one PMSM motor. The PWM signals generated by the S32K396 are routed to the MC33937A gate-driver stage. The pre-driver then controls the external MOSFET bridge of the inverter. The feedback path is routed back from each power stage to the MCU. This includes phase current feedback, DC bus voltage, phase voltage, and position or speed feedback from the selected sensor interface. These signals are sampled and synchronized with the PWM events. The S32K396 therefore controls two independent three-phase inverter stages. Each motor has its own PWM outputs, sensing path, position feedback, and protection signals. The control software coordinates both channels and exchanges the resulting status information over CAN. overall_system_diagram.png This hardware arrangement can also be viewed as a scalable topology. The same MCU platform can be used for two independent three-phase motors or for one six-phase motor, depending on how the PWM outputs, sensing resources, and power stages are mapped. By connecting the software workflow with the hardware execution path, this enablement layer shows how a model-based motor control concept can be taken from algorithm design to a running dual-motor traction demonstrator on NXP silicon.   5 References Motor Control Blockset Documentation Vehicle Network Toolbox Documentation NXP Model-Based Design Toolbox for S32K3 S32K39-37-36 Microcontrollers for Electrification Applications MC33937: 3-Phase Field Effect Transistor Pre-Driver S32K396-BGA-DC1 Evaluation Board MCSPTR2AK396 BLDC/PMSM Motor Control Development Kit S32X-MB I/O Extension Evaluation Board 6 Conclusion This article described the software and hardware enablement required for the Motor Control System. The software environment combines MathWorks motor control and vehicle network capabilities with NXP target support. The hardware environment combines the S32K396 microcontroller with the MC33937 pre-driver and the inverter stage. Together, these elements provide the foundation for modeling, simulation, communication, code generation, deployment, and validation of the dual-motor control application. The next article will focus on the architecture and model description of the Motor Control System, including the main control layers, signal interfaces, and application structure.
查看全文
初心者が色選別カメラの製作に挑戦 私はより大きなプロジェクトのために色分け装置を作ろうとしていますが、この分野に関しては全くの初心者です。私はESP32-S3R8マイクロプロセッサを持っていて、互換性のあるカメラに接続して、最終的には特定の色の物体が視界に入っているかどうかを検出したいと考えています。 主にどのカメラがこの用途に最適かを知りたいのですが、このプロジェクトに必要なことを学ぶためのヒントがあれば、ぜひ教えていただけると大変ありがたいです。 Re: Novice Trying to Make a Colour Sorting Camera こんにちは、 NXPポートフォリオを活用すれば、MCUとカメラインターフェースの使い方を指針として得られます。カメラインターフェースの導入を始めるための参考になります。 私が提示した選択肢の中で、OV7670カメラモジュール/カメラインターフェースを使っています。これは非常に頻繁に使われるカメラです。カメラインターフェースは色認識にも使えます。この情報は入門の導入として役立ちます。 このドキュメントでは、カメラソリューションの使い方、インターフェース、API設定、そしてデモを紹介しています。 MCX-N オプション: SmartDMAを用いてカメラインターフェースをMCXN236実装 LPC55 オプション: AN12868:LPC55(S)xxのカメラインターフェース |NXPセミコンダクターズ さらに、カメラの例に興味があれば、 Application Code Hubにカメラを使ったさまざまな検出例があります。 敬具、ルイス
查看全文
カーネル6.6.92ではPN7160が応答しません 当チームはPN7160をカーネル6.6.92に移植しました。 しかし現在、NFCタグを 読み取ることができません 。 以下は、当社の被試験デバイス(DUT)に関する情報です。 カーネルバージョン: 6.6.92 OS: ヨクト・スカースギャップ PN7160 ドライバーパッチファイル: 0003-nfc-nxpnfc-add-NXP-PN7160-i2c-spi-kernel-driver.patch(NFCのGitHubリポジトリからクローンし、カーネル6.6に対応するように修正しました) nfcDemoApp レシピ: recipes-nfc.7z (NFC GitHub からクローンし、ビルドエラーを修正するために変更しました) カーネルログ: nfc-log.txt この問題を解決するためのアドバイスをいただけますか? 回复: PN7160 no response with kernel 6.6.92 libnfc-nxp.conf ファイルで LOGLEVEL を 0x03 に設定してください。次に、nfcDemoAppを実行したときのログを送ってください。確認のため、libnfc-nci.confとlibnfc-nxp.confも送ってください。 回复: PN7160 no response with kernel 6.6.92 ご返信よろしくお願いします。 ログファイルと設定ファイル(libnfc-nci.confとlibnfc-nfc.conf)添付されています。 何かアドバイスをいただけますか?
查看全文
MRF13750H Schematic Hello! Where can I find the electrical schematic of the MRF13750H - 915MHz narrowband reference circuit? 
查看全文
FRDM-i.MX95 Board Not Booting from SD Card or Entering USB Serial Downloader Mode Issue Summary Flashed the provided base image to the microSD card using Win32DiskImager. Set SW1 = 11 for SD card boot. Connected the board to the PC using one USB-C cable, first through J1 (Debug UART) and later through J3 (USB Device) for USB download testing. The board is powered through J25. The board powers on successfully (power LED is ON). SD Boot Mode Connected J1 to the PC. Opened PuTTY at 115200, 8N1, No Flow Control. Tried all detected COM ports (COM3, COM4, COM5, COM6). Pressed RESET and power-cycled the board multiple times. No boot logs or serial output are displayed. USB Serial Downloader Mode Changed SW1 = 01 for USB Serial Downloader mode. Disconnected J1 and connected J3 to the PC. Windows detects an Unknown USB Device (Device Descriptor Request Failed) with Code 43. uuu.exe -lsusb does not detect the board. Can anyone please help. FRDM-IMX95 #NXP iMX95  Re: FRDM-i.MX95 Board Not Booting from SD Card or Entering USB Serial Downloader Mode Hi @shuru_2604  Your computer does not appear to have successfully updated its USB driver automatically. You can click the following link to download the CH344 driver and install it yourself. https://file.wch.cn/download/file?id=312https://www.wch.cn/downloads/CH343CDC_ZIP.html B.R
查看全文