Multi Source Translation Content

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

Multi Source Translation Content

ディスカッション

ソート順:
S32G3におけるRCCU、FCCU、およびLockstep診断データフロー 親愛なるNXPへ、 私の理解では、RCCUはLockstepのミスマッチを検出し、FCCUにエラーを報告します。FCCUは故障マネジメントを担当し、Linuxカーネルログ(dmesg)を通じて診断情報を提供することがあります。しかし、BSPのドキュメントではこのプロセスが大まかに説明されているに過ぎません。 Linux BSP 48.0.0のS32G378Aに関するより具体的な実装ガイダンスを教えていただけますか? 利用可能な診断データ:RCCUおよびFCCUから収集可能なデータの種類には、エラーの状態、故障の発生源、エラータイプ、故障のコンテキストなどがありますか?ハードウェアで実際に利用可能な情報と、Linux dmesgを通じて報告できる情報は何でしょうか? エンドツーエンドのデータフロー:RCCUによるロックステップ不一致の検出から、FCCUの故障処理、Linuxカーネル報告までの正確な流れはどのようなものなのでしょうか?どのレジスタ、割り込み、ドライバ、またはソフトウェアコンポーネントが関与しているのでしょうか? ソースコードと実装:BSP 48.0.0でこれらの情報を収集・報告するために、どのソースファイル、デバイスドライバ、デバイスツリーエントリ、または設定ファイルを変更する必要があるのか?NXPは、完全なフローを示す既存のGitHubリポジトリ、リファレンス実装、またはサンプルコードを提供していますか? ロックステップの入出力:ロックステップ機構は、入力として実際に何を比較するのでしょうか?入力は冗長なA53実行パスによって内部的に生成されるのか、それとも入力データをソフトウェアで設定または読み込む必要があるのか?関連する構成はどこで行われ、不一致が発生した場合にソフトウェアが取得できる診断出力は何でしょうか? 関連するリファレンスマニュアルのセクション、ソースコード参照、具体的な実装ワークフローをご提供ください。現在のBSPドキュメントではこれらの詳細が十分に説明されていません。 Re: RCCU, FCCU, and Lockstep Diagnostic Data Flow on S32G3 お返事ありがとうございます。もう一つ質問させてください。 Linux BSP 48.0.0ユーザーマニュアルでは、デバイスツリーのプロパティ(例えば「nxp,ncf_fault_list」や「nxp,ncf_actions)」を用いてFCCUの設定を説明しています。 この設定を適用するためにどのソースファイルを修正すべきか、教えていただけますか?変更を保存した後、デバイスツリーを通じて有効になりますか?それともFCCUドライバも修正する必要がありますか? 可能であれば、S32G378A-EVB3の簡単な例を示してください。 よろしくお願いします、 トアン Re: RCCU, FCCU, and Lockstep Diagnostic Data Flow on S32G3 こんにちは、 @Toan 投稿ありがとうございます 1.FCCUは、デバイスで故障が検出された際に故障を収集するためのハードウェアインターフェースを提供しています。これはハードウェアの挙動であり、異なる故障番号は異なる故障を反映します。S32G3 RMに添付された故障マップファイルを参照してください。BSP48のLinux FCCUドライバは、FCCUで処理された非重大障害の選択リストを更新し、デバイスツリーを使ってサポートされるNCFアクションのいずれかを選択できます。反応セットがアラームの場合、アラーム情報は 対応する障害が発生した場合、カーネルのログに印刷されました。 2. RCCUが問題を検出すると、FCCUはそれを記録し、ユーザーが設定したアクションを実行します。例えば、アラームがアクションに設定されている場合、その情報はカーネルログに記載されており、Linux FCCUドライバ、DTS、FCCUアラーム割り込みハンドラが関与します。 3. 対応する情報はBSP48 UM第6章から入手可能。 4. ロックステップモードでは、1つのクラスタがメインクラスタ、2つ目のクラスタがチェッカークラスタとみなされます。ソフトウェアの観点からは、2つのクラスタはロックステップモードで単一のクラスタとして動作します。Cortex-A53 Cluster0はメインの実行クラスタであり、Cortex-A53 Cluster1はCortex-A53 Cluster0の実行後に続きます。複製されたリソースの同等な動作は、クラスタから出るすべての機能信号に対してコンパレータ(RCCU)によって監督され、残りのMCUに送られます。監督信号間の運用上の逸脱があれば、FCCUに不一致が通知されます。 S32G3 A53ロックステップモードでは、ソフトウェアはロックステップ比較のために入力データを提供または読み込む必要がありません。比較は通常のA53実行中にハードウェア内部で行われ、アプリケーションソフトウェアには透過的です。 ソフトウェアは主に比較データではなく、ロックステップの動作モードを設定します。ソフトウェアは故障に対応するアクションを設定できます。不一致が検出された場合、それはRCCU/FCCUのセーフティ故障メカニズムを通じて報告され、関連する対応が実行されます。 BR チェイン
記事全体を表示
S32G3上的RCCU、FCCU和锁步诊断数据流 尊敬的恩智浦: 据我了解,RCCU 会检测锁步不匹配并将错误报告给 FCCU,FCCU 会处理故障管理,并可能通过 Linux 内核日志 (dmesg) 提供诊断信息。然而,电路板支持包文档仅从宏观层面描述了这一过程。 能否提供针对 Linux 电路板支持包。 48.0.0 的 S32G378A 的更具体的实施指导? 可用的诊断数据:可以从 RCCU 和 FCCU 收集哪些类型的数据,例如错误状态、故障源、错误类型或故障上下文?硬件中实际有哪些信息可用,Linux dmesg 可以报告哪些信息? 端到端数据流:从 RCCU 检测到锁步不匹配,到 FCCU 故障处理,再到 Linux 内核报告,整个流程是怎样的?涉及哪些寄存器、中断、驱动程序或软件组件? 源代码和实现:在电路板支持包 48.0.0 中需要修改或启用哪些源文件、设备驱动程序、设备树条目或配置文件才能收集和报告此信息?NXP 是否提供现有的 GitHub 代码库、参考实现或示例代码来演示完整的流程? 锁步输入和输出:锁步机制的输入实际上比较的是什么?输入是由冗余的 A53 执行路径内部生成的,还是必须由软件配置或加载任何输入数据?相关配置在哪里执行?当出现不匹配情况时,软件可以检索到哪些诊断输出? 请提供相关的参考手册章节、源代码参考以及具体的实现流程,因为当前的电路板支持包文档对这些细节的解释不够充分。 Re: RCCU, FCCU, and Lockstep Diagnostic Data Flow on S32G3 感谢你的回复。我还想问最后一个问题。 Linux 电路板支持包。 48.0.0 用户手册描述了使用设备树属性(例如 `nxp,ncf_fault_list` 和 `nxp,ncf_actions`)配置 FCCU。 请问我们需要修改哪个源文件才能应用此配置?保存更改后,更改会通过设备树生效吗?还是我们还需要修改 FCCU 驱动程序? 如果可以,请提供 S32G378A-EVB3 的简单示例。 此致, 托安 Re: RCCU, FCCU, and Lockstep Diagnostic Data Flow on S32G3 你好, @Toan 谢谢你的帖子 1.FCCU 提供硬件接口来收集设备中检测到的故障信息,这是硬件行为,不同的故障编号反映不同的故障,您可以参考 S32G3 RM 中附加的故障映射文件。BSP48 中的 Linux FCCU 驱动程序允许更新 FCCU 中处理的非关键故障的选定列表,并使用设备树选择支持的 NCF 操作之一。如果响应集是警报,则警报信息为: 如果发生相应的故障,则将其打印在内核日志中。 2. 当 RCCU 检测到问题时,FCCU 将记录该问题,然后执行用户设置的操作,例如,如果将报警设置为操作,则可以在内核日志中找到相关信息,Linux FCCU 驱动程序、DTS、FCCU 报警中断处理程序将参与其中。 3. 相关信息可从 BSP48 UM 第 6 章中获得。 4.在锁步模式下,一个集群被视为主集群,另一个集群被视为校验集群。从软件角度来看,这两个集群在锁步模式下作为一个集群运行。Cortex-A53 Cluster0 是主执行集群,Cortex-A53 Cluster1 紧随其后执行。所有离开集群并发送到 MCU 其他部分的功能信号都由比较器 (RCCU) 进行监控,以确保复制资源的等效操作。任何被监控信号之间的操作偏差都会触发 FCCU 收到差异通知。 在 S32G3 A53 锁步模式下,软件不需要提供或加载锁步比较的输入数据。该比较由硬件在 A53 正常执行期间内部执行,对应用程序软件是透明的。 软件主要配置 Lockstep 操作模式,而不是对比数据。软件可以针对故障设置相应的操作。如果检测到不匹配,则会通过 RCCU/FCCU 功能安全故障机制报告,并执行相关操作。 BR 陈银
記事全体を表示
[MCX A153] ADC模块基础知识及使用方法(日语博客) 本文介绍了MCX A153中安装的ADC(模数转换器)模块的基本用法。首先通过ADC的应用示例,总结了其主要功能、模块结构和使用注意事项,然后介绍了如何使用SDK示例代码进行设备初始化,以及如何使用DMA传输ADC转换结果。 本文旨在帮助您了解在应用中使用 MCX A153 ADC 所需的基本原理,使您能够实现从 ADC 转换的初始设置到利用 DMA 进行高效数据传输的一切操作。   目录 1. 应用中的常见用例 1.1 主要用途 1.2 使用示例 2. MCX A153 ADC模块的主要功能和框图 2.1 概述 2.2 主要特点 2.3 方框图 3. 注意事项和限制 4. ADC 示例代码(设备初始化) 4.1 示例代码概述 4.2 打开 SDK 示例项目 4.3 宏观定义 4.4 设备初始化 5. 使用MCX A153 DMA传输AD转换值 5.1 与ADC相关的代码 5.2 DMA相关代码 总结 1. 应用中的常见用例 ADC 将来自传感器、电位器等的模拟信号(连续变化的电压)转换为微控制器可用于计算的数字值(数值)。 1.1 主要用途 将电位器输入的模拟电压值转换为数字值。 电位器安装在伺服电机(例如无线电遥控车辆中使用的伺服电机)的轴上,通过输出的变化来检测电机的旋转角度。 将来自各种传感器的模拟信号转换为数字值。 它通过转换来自加速度计的模拟信号来检测物体的倾斜度。例如,这可以用于检测智能手机的方向。 环境温度是通过转换温度传感器的模拟信号来测量的。   1.2 使用示例(以下示例旨在说明一般概念,因此省略了细节。) 电位器应用示例:         2. 主要功能和框图   2.1 概述 MCX A153 配备了一个 16 位模数转换器 (ADC)。ADC 是一种将模拟电压转换为数字值的电路。   2.2 主要特点 配备一个逐次逼近型AD转换器单元。 支持 16 位或 12 位分辨率和单端输入(更高的分辨率可以更精细地表示输入电压)。 已安装频道数量(因套餐而异): 64 引脚 LQFP 封装:24 通道,48 引脚 LQFP 封装:16 通道,48 引脚 HVQFN 封装:18 通道,32 引脚 HVQFN 封装:9 通道 采样率(每秒数据转换次数) 16 位模式:最高 3.2 Msps,12 位模式:最高 4 Msps 可以设置采样时间。 可在微控制器的低功耗模式下运行。 支持四种触发源(软件或硬件触发)。 七个命令缓冲区可以扫描连续通道。 支持比较功能(自动比较较小、较大、在范围内、超出范围,保存为匹配项等) 配备八个用于存储转换结果数据的FIFO,具有水印和溢出检测功能。 支持中断、DMA 和轮询。 校准功能 内置温度传感器,带专用输入通道   2.3 方框图 MCX A153 参考手册(MCXAP64M96FS3RM) 图 165。ADC框图摘录   SDK示例代码使用示例(连接电位器)     3. MCX A153 ADC 模块 本节解释了在使用 MCX A153 的 ADC 之前需要考虑的重要事项和限制。 16 位模式下的速度降低 MCX A153 的 ADC 支持两种模式:16 位(ENOB16:16 位有效分辨率)和 12 位(ENOB12:12 位有效分辨率)。但是,16 位模式的采样率低于 12 位模式。 (摘自MCX A153 数据手册表 34) 校准执行时间 校准请求和执行必须在复位或上电期间进行。此外,必须先配置时钟源和频率才能执行校准。 转化率结果的平均值 ADC模块可以在保存转换结果之前,对同一通道的多个结果进行平均。当CMDHa[AVGS]位域设置为非零值时,硬件平均功能启用。该功能可用于任何转换模式,并减轻软件计算平均值的负担。 4. AD转换示例代码 4.1 示例代码概述 主序列执行时,将进行设备初始化。设备初始化首先设置时钟、配置外部接口,并选择要连接到接口的外设。之后,初始化外设(ADC、UART)并启用中断。初始化过程完成后,循环内会设置一个软件触发信号以启动ADC转换,并在控制台上显示ADC转换值和转换次数。 硬件方面,我们将使用MCX A153开发板“FRDM-MCXA153”。   4.2 在 VS Code 中打开 ADC 示例项目的步骤 4.2.1 准备 VS Code 和扩展程序 安装 VS Code。 在扩展视图(Ctrl+Shift+X)中搜索“MCUXpresso for VS Code”并安装。 MCUXpresso 图标将出现在左侧的活动栏中。点击该图标即可打开快速入门面板。   4.2.2 安装依赖工具 在快速启动面板中运行“打开 MCUXpresso 安装程序”。 请选择并安装以下工具。 Arm GNU 工具链 CMake / Ninja Python / 西方 Git LinkServer(MCU-Link 的调试探针) SDK相关工具 完成后,重启 VS Code。   4.2.3整合 SDK 存储库 在快速入门面板中单击“导入存储库”。 选择“远程”作为数据导入源。   指定目标文件夹。路径应简短,且不得包含日文字符或空格。 您可以通过勾选“我同意”并按下“导入”按钮来导入存储库。   4.2.4 导入样品 在“快速入门面板”中,单击“从存储库导入示例”。 设置方法如下:   您可以点击“导入”按钮导入项目。 项目 设置值 存储库 步骤 3 中导入的 SDK (frdm_mcxa153) 工具链 Arm GNU 工具链 木板 frdmmcxa153 (FRDM-MCXA153) 模板 driver_examples → lpadc → interrupt(lpadc_interrupt) 地点 项目保存位置 姓名 可选(默认值为 lpadc_interrupt) 4.3 宏观定义 这是 ADC 功能的宏定义代码(摘自 lpadc\interrupt\app.h)。 请调整输入通道、分辨率设置和参考电压源,以匹配您的实际电路设计和预期用途。 定义 //(lpadc\interrupt\app.hから抜粋) /******************************************************************************/ #define DEMO_LPADC_BASE ADC0 //ADCのinstance、ベースアドレス、MCX A153は1個 ADCしかない #define DEMO_LPADC_IRQn ADC0_IRQn #define DEMO_LPADC_IRQ_HANDLER_FUNC ADC0_IRQHandler #define DEMO_LPADC_USER_CHANNEL 0U //チャンネル番号 #define DEMO_LPADC_USER_CMDID 1U //コマンドID #define DEMO_LPADC_VREF_SOURCE kLPADC_ReferenceVoltageAlt3 //参考電圧ソース #define DEMO_LPADC_DO_OFFSET_CALIBRATION true //オフセットキャリブレーションの利用可否 #define DEMO_LPADC_USE_HIGH_RESOLUTION true //高分解能の利用可否 与ADC相关的变量 变量 //(lpadc\interrupt\lpadc_interrupt.cから抜粋) volatile bool g_LpadcConversionCompletedFlag = false; volatile uint32_t g_LpadcInterruptCounter = 0U; lpadc_conv_result_t g_LpadcResultConfigStruct; #if (defined(DEMO_LPADC_USE_HIGH_RESOLUTION) && DEMO_LPADC_USE_HIGH_RESOLUTION) //高分解能 const uint32_t g_LpadcFullRange = 65536U; const uint32_t g_LpadcResultShift = 0U; #else //低分解能 const uint32_t g_LpadcFullRange = 4096U; const uint32_t g_LpadcResultShift = 3U; #endif /* DEMO_LPADC_USE_HIGH_RESOLUTION */ ADC 配置结构的默认值(详情请参见 fsl_lpadc.c),转换结果的平均值。 //(lpadc\interrupt\lpadc_interrupt.cから抜粋) LPADC_GetDefaultConfig(&mLpadcConfigStruct); mLpadcConfigStruct.enableAnalogPreliminary = true; //ADCアナログ回路は事前に有効化され、起動遅延なしで変換を実行する準備 #if defined(DEMO_LPADC_VREF_SOURCE) mLpadcConfigStruct.referenceVoltageSource = DEMO_LPADC_VREF_SOURCE; //参考電圧ソース #endif /* DEMO_LPADC_VREF_SOURCE */ #if defined(FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS) && FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS mLpadcConfigStruct.conversionAverageMode = kLPADC_ConversionAverage; //変換結果平均化設定、平均しない/2回の平均/4回の平均/8回の平均/16回の平均....1024回の平均化選択可能 #endif     4.4 设备初始化     时钟分频比初始化 CLOCK_SetClockDiv 函数处理 ADC 外设使用的时钟分频设置。 //(lpadc\interrupt\hardware_init.cから抜粋) /* Attach peripheral clock */ CLOCK_SetClockDiv(kCLOCK_DivADC0, 1u); div_name:选择枚举定义的分频器。 值:除法比率 *以下代码是从 fsl_clock.c 开始的驱动程序部分,不建议用户修改。 //(fsl_clock.cから抜粋) void CLOCK_SetClockDiv(clock_div_name_t div_name, uint32_t value) { volatile uint32_t *pDivCtrl = (volatile uint32_t *)(MRCC0_BASE + (uint32_t)div_name); assert(div_name <= kCLOCK_DivMax); /* Unlock clock configuration */ SYSCON->CLKUNLOCK &= ~SYSCON_CLKUNLOCK_UNLOCK_MASK; /* halt and reset clock dividers */ *pDivCtrl = 0x3UL << 29U; if (value == 0U) /*!< halt */ { *pDivCtrl |= (1UL << 30U); } else { *pDivCtrl = (value - 1U); } /* Freeze clock configuration */ SYSCON->CLKUNLOCK |= SYSCON_CLKUNLOCK_UNLOCK_MASK; }   时钟选择 CLOCK_AttachClk 选择 ADC 外设要使用的四个时钟源之一。 驱动程序通过将 `clock_attach_id_t` 结构中定义的值作为参数传递给 `void CLOCK_AttachClk(clock_attach_id_t connection)` 函数来配置连接。 //(fsl_clock.hから抜粋) kFRO12M_to_ADC0 = CLK_ATTACH_MUX(kCLOCK_SelADC0, 0U), /* Attach FRO12M to ADC0. */ kFRO_HF_to_ADC0 = CLK_ATTACH_MUX(kCLOCK_SelADC0, 1U), /* Attach FRO_HF to ADC0. */ kCLK_IN_to_ADC0 = CLK_ATTACH_MUX(kCLOCK_SelADC0, 3U), /* Attach CLK_IN to ADC0. */ kCLK_1M_to_ADC0 = CLK_ATTACH_MUX(kCLOCK_SelADC0, 5U), /* Attach CLK_1M to ADC0. */ kNONE_to_ADC0 = CLK_ATTACH_MUX(kCLOCK_SelADC0, 7U), /* Attach NONE to ADC0. */ //(lpadc\interrupt\hardware_init.cから抜粋) CLOCK_AttachClk(kFRO12M_to_ADC0); 以下函数是 SDK 提供的驱动程序部分的一部分,从 fsl_clock.c 开始,不建议用户修改它们。 //(fsl_clock.hから抜粋) void CLOCK_AttachClk(clock_attach_id_t connection) { const uint32_t reg_offset = CLK_ATTACH_REG_OFFSET(connection); const uint32_t clk_sel = CLK_ATTACH_CLK_SEL(connection); if (kNONE_to_NONE != connection) { CLOCK_SetClockSelect((clock_select_name_t)reg_offset, clk_sel); } } //(fsl_clock.hから抜粋) void CLOCK_SetClockSelect(clock_select_name_t sel_name, uint32_t value) { volatile uint32_t *pClkCtrl = (volatile uint32_t *)(MRCC0_BASE + (uint32_t)sel_name); assert(sel_name <= kCLOCK_SelMax); if (sel_name == kCLOCK_SelSCGSCS) { SCG0->RCCR = (SCG0->RCCR & ~(SCG_RCCR_SCS_MASK)) | SCG_RCCR_SCS(value); while ((SCG0->CSR & SCG_CSR_SCS_MASK) != SCG_CSR_SCS(value)) { } } else { /* Unlock clock configuration */ SYSCON->CLKUNLOCK &= ~SYSCON_CLKUNLOCK_UNLOCK_MASK; *pClkCtrl = value; /* Freeze clock configuration */ SYSCON->CLKUNLOCK |= SYSCON_CLKUNLOCK_UNLOCK_MASK; } } 关于电路板初始化功能 时钟将被初始化。   引脚初始化 调用 InitPins() 函数,并处理 pin_mux.c 文件。pin_mux.c 文件由 NXP 的 MCUXPresso 使用。可以使用集成到 IDE 中的引脚配置工具来覆盖此设置。 //(lpadc\interrupt\hardware_init.cから抜粋) BOARD_InitPins(); BOARD_InitPins() 函数执行四个操作。 启用外围时钟 禁用外围设备复位 外部引脚对引脚和外设连接(MUX 配置)-> 结构体参数设置 在登记簿中写入 3   初始化启动时钟 MCX A153 支持中等驱动模式和标准驱动模式。这两种模式分别对应 1.0 V 和 1.1 V 的 VDD_CORE 电压,以及 48 MHz 或 96 MHz 的 rfo_hf 时钟频率。切换模式需要外部电源,并且需要配置与电压相关的寄存器,例如 LDO。 //(lpadc\interrupt\hardware_init.cから抜粋) BOARD_InitBootClocks(); 时钟是通过与工作频率相对应的寄存器设置功能来设置的。 //(fsl_clock.cから抜粋) void BOARD_InitBootClocks(void) { BOARD_BootClockFRO96M(); }     初始化调试端口 //(lpadc\interrupt\hardware_init.cから抜粋) BOARD_InitDebugConsole();   //(board.cから抜粋) void BOARD_InitDebugConsole(void) { /* attach 12 MHz clock to LPUART0 (debug console) */ CLOCK_SetClockDiv(kCLOCK_DivLPUART0, 1u); CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH); RESET_PeripheralReset(BOARD_DEBUG_UART_RST); DbgConsole_Init(BOARD_DEBUG_UART_INSTANCE, BOARD_DEBUG_UART_BAUDRATE, BOARD_DEBUG_UART_TYPE, BOARD_DEBUG_UART_CLK_FREQ); }   应用程序初始化 ADC 初始化在 LPADC_Init(DEMO_LPADC_BASE, &mLpadcConfigStruct) 函数中处理。LPADC_Init() 函数位于 fsl_lpadc.c 的驱动程序部分。 DEMO_LPADC_BASE:0x400A_F000 -> ADC 的起始地址 定义结构表并配置ADC。 typedef struct {} lpadc_config_t 姓名 属性 说明 lpadc_config_t 类型 LPADC配置参数信息 启用休眠模式 布尔值 ADC转换期间的操作设置基于模式 转换平均模式 lpadc_conversion_average_mode_t 与自动校准相关的设置 启用模拟初步 布尔值 ADC启动前设置 上电延迟 uint32_t ADC电路的稳定时间 参考电压源 lpadc_reference_voltage_source_t 参考电压源 功率级别模式 lpadc_power_level_mode_t 电源配置选择 触发优先级策略 lpadc_trigger_priority_policy_t 如何处理高利润触发因素 启用会话暂停 布尔值 设置 AD 转换执行间隔。 对话暂停延迟 uint32_t 命令序列期间的暂停时间 先进先出水印 uint32_t FIFO 中数据点数量的阈值设置。 //(lpadc\interrupt\lpadc_interrupt.cから抜粋) LPADC_Init(DEMO_LPADC_BASE, &mLpadcConfigStruct); //(fsl_lpadc.cから抜粋) void LPADC_Init(ADC_Type *base, const lpadc_config_t *config) { /* 省略 */ base->CTRL |= ADC_CTRL_CAL_AVGS(config->conversionAverageMode); /* 省略 */ }   关于ADC校准   在使用模数转换器 (ADC) 之前,需要进行校准以校正转换结果中包含的偏移误差和其他因素,从而提高模数转换的精度。 校准过程大致可分为以下两个阶段: 设置校准模式和条件。 执行校准并将校正值应用于ADC。   在默认示例中,ADC 校准在执行完 LPADC_Init() 之后、AD 转换开始之前进行。首先,使用 LPADC_SetOffsetCalibrationMode() 在相应的器件上设置偏移校准模式。然后,如果启用了 DEMO_LPADC_DO_OFFSET_CALIBRATION,则执行 LPADC_DoOffsetCalibration();否则,使用预先通过 LPADC_SetOffsetValue() 设置的偏移值。 此外,如果启用了相应的函数宏,则在延迟 1 µs 或更长时间后执行 LPADC_DoAutoCalibration() 函数。该函数用于校准增益误差和线性误差。仅当器件支持的功能宏启用时,才会编译相应的进程。 以下是LPADC校准模式的设置。 //(lpadc\interrupt\lpadc_interrupt.cから抜粋) /* Request LPADC calibration. */ #if defined(FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE) && FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE LPADC_SetOffsetCalibrationMode(DEMO_LPADC_BASE, DEMO_LPADC_OFFSET_CALIBRATION_MODE); #endif /* FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE */     执行偏移校准 //(lpadc\interrupt\lpadc_interrupt.cから抜粋) #if defined(FSL_FEATURE_LPADC_HAS_CTRL_CALOFS) && \ FSL_FEATURE_LPADC_HAS_CTRL_CALOFS #if defined(DEMO_LPADC_DO_OFFSET_CALIBRATION) && \ DEMO_LPADC_DO_OFFSET_CALIBRATION L PADC_DoOffsetCalibration(DEMO_LPADC_BASE); //キャリブレーションを実行しない場合 #else /* Update OFSTRIM register manually. */   5. MCX A153 DMA 为什么ADC转换要使用DMA传输? 当仅通过软件处理ADC采集的数据时,CPU需要监控ADC转换的完成情况,读取转换结果并将其写入内存。对于单次ADC转换而言,这并非主要问题;但当以固定间隔连续采样或处理多个输入通道时,此过程会反复发生。因此,CPU的处理负载会增加,从而可能减少可用于其他应用程序处理的时间。 解决此问题的一种方法是使用 DMA(直接内存访问)传输 ADC 转换结果。使用 DMA,ADC 转换完成后,转换结果可以自动传输到内存。换句话说,由于从获取 ADC 转换结果到将其存储到内存的过程可以由硬件处理,因此可以减少 CPU 执行的数据传输处理量,从而降低软件的处理负载。 鉴于以上原因,ADC和DMA的组合配置常用于需要连续模数转换和高速数据采集的应用中。本文将首先介绍ADC的基本初始化方法,然后介绍如何使用MCX A153通过DMA将ADC转换结果传输到存储器。 使用DMA进行AD转换值传输概述 AD转换后的数据存储在ADC外设的缓冲区中。ADC无需每次都手动读取数据,而是可以通过DMA传输数据。例如,程序可以修改为连续执行五次AD转换,然后通过DMA将数据保存到RAM缓冲区,并在控制台上显示平均值、最小值和最大值。 使用DMA传输AD转换值的步骤 我们将修改ADC示例代码,添加DMA处理功能。 DMA 激活是通过来自 ADC 的 DMA 请求信号执行的。 使用 DMA,将 ADC FIFO 值(5 次转换)复制到 RAM,并向 CPU 发出中断通知。 CPU 在 DMA 传输完成后,在主循环中取平均值,并将最小值、最大值和平均值显示在控制台上。     防范措施 要添加 DMA 代码,您需要将 DMA 驱动程序头文件和源代码添加到您的项目中。最简单的方法是从 MCUXpresso IDE 创建一个示例 DMA 代码 (frdmmcxa153_edma3_memory_to_memory_transfer) 并复制它。只需从 drivers 目录复制以下文件即可。 fsl_edma_core.h fsl_edma_soc.c fsl_edma_soc.h fsl_edma.c fsl_edma.h   5.1 与ADC相关的代码修改和新增   代码修改步骤 ADC转换完成后发生的中断已被禁用。 添加了ADC配置。 设置为连续执行 5 次 AD 转换。 启用DMA请求 将先进先出 (FIFO) 水印设置为 4。 增加了处理功能,以获取 DMA 传输值的平均值、最小值和最大值,并将它们输出到控制台。     1. 当ADC转换完成后,禁用中断。 由于中断使能寄存器 (IE) 是通过 LPADC_EnableInterrupts() 函数和 kLPADC_FIFOWatermarkInterruptEnable 启用的,因此我们将注释掉这一行。 // LPADC_EnableInterrupts(DEMO_LPADC_BASE, kLPADC_FIFOWatermarkInterruptEnable);   2. 添加ADC配置 ADC 配置为循环 5 次(= 5 次 AD 转换)。 mLpadcCommandConfigStruct.loopCount = 4 //loopCount +1回の変換 启用DMA请求 //178行目 LPADC_EnableFIFOWatermarkDMA(DEMO_LPADC_BASE, 1); // 1でDMA Requestがイネーブル     3. 将先进先出 (FIFO) 中的水印级别数设置为 4。 // 33行目 /* ++ ADCのマクロ */ #define FIFO0WatermarkLEVEL (4) //108行目 mLpadcConfigStruct.FIFOWatermark = FIFO0WatermarkLEVEL;   4. 增加了处理,以获取 DMA 传输的值和控制台输出的平均值、最小值和最大值。 uint32_t adc_values[5] = {0}; PRINTF("Please press any key to get user channel's ADC value.\r\n"); while(1) { GETCHAR(); EXAMPLE_DMA_BASEADDR->CH[0].CH_CSR = DMA_CH_CSR_ERQ(1); EXAMPLE_DMA_BASEADDR->CH[0].TCD_DLAST_SGA = -0x14; LPADC_DoSoftwareTrigger(DEMO_LPADC_BASE, 1U); /* 1U is trigger0 mask. */ while (!g_Transfer_Done) { /* DMA転送終了割り込み待ち */ } g_Transfer_Done = false; uint16_t min=adc_values[0]; uint16_t max=adc_values[0]; uint32_t sum=0; for(uint32_t i=0; i<5; i++) { if(max < (0x0000FFFF & adc_values[i])) max = adc_values[i]; if(min > (0x0000FFFF & adc_values[i])) min = adc_values[i]; sum += 0x0000FFFF & adc_values[i]; } PRINTF("ADC Min: %d, Max: %d, ave: %d\r\n", min, max, sum/5); for(size_t i=0; i<5; i++) { adc_values[i] = 0; } sum = 0; }   5.2 添加DMA相关代码   代码添加政策 包含头文件 添加了与DMA相关的宏。 DMA配置和初始化 DMA传输配置 DMA传输完成中断处理   1. 包含标题 // 10行目 #include "fsl_debug_console.h" #include "pin_mux.h" #include "clock_config.h" #include "board.h" #include "fsl_lpadc.h" /* ++ */ #include "fsl_edma.h" // DMAドライバヘッダファイルの追加 #include "fsl_clock.h" #include "fsl_reset.h"   2. 添加与 DMA 相关的宏。 // 32行目 #define EXAMPLE_DMA_BASEADDR DMA0 #define DEMO_DMA_CHANNEL_0 0U #define APP_DMA_IRQ DMA_CH0_IRQn #define APP_DMA_IRQ_HANDLER DMA_CH0_IRQHandler     3. DMA配置 // 197行目 edma_transfer_config_t transferConfig; edma_config_t userConfig; // 203行目 RESET_PeripheralReset(kDMA_RST_SHIFT_RSTn); /* Configure EDMA channel for one shot transfer */ EDMA_GetDefaultConfig(&userConfig); EDMA_Init(EXAMPLE_DMA_BASEADDR, &userConfig);     4. DMA传输配置 // 209行目 EDMA_PrepareTransfer(&transferConfig, (void *)0x400AF300, // eDMA transfer source address. sizeof(uint32_t), // eDMA transfer source address width(bytes) (void *)adc_values, // eDMA transfer destination address sizeof(&adc_values), // eDMA transfer destination address width(bytes) sizeof(adc_values), // eDMA transfer bytes per channel request sizeof(adc_values), // eDMA transfer bytes to be transferred kEDMA_PeripheralToMemory // eDMA transfer type ); EDMA_SetTransferConfig(EXAMPLE_DMA_BASEADDR, DEMO_DMA_CHANNEL_0, &transferConfig, NULL); EDMA_SetChannelMux(EXAMPLE_DMA_BASEADDR, DEMO_DMA_CHANNEL_0, kDma0RequestMuxAdc0FifoRequest); EnableIRQ(APP_DMA_IRQ); EDMA_EnableChannelInterrupts(EXAMPLE_DMA_BASEADDR, DEMO_DMA_CHANNEL_0, kEDMA_MajorInterruptEnable); 在用软件触发启动软件 ADC 之前,添加 EDMA_TriggerChannelStart() 以在 DMA 通道 0 上触发中断。当 DMA 中断标志被清除时,DMA 触发的中断将被禁用,因此该处理是在 ADC 的软件触发之前添加的。 // 242行目 while(1) { GETCHAR(); EDMA_TriggerChannelStart(EXAMPLE_DMA_BASEADDR, DEMO_DMA_CHANNEL_0); EXAMPLE_DMA_BASEADDR->CH[0].TCD_DLAST_SGA = -0x14; LPADC_DoSoftwareTrigger(DEMO_LPADC_BASE, 1U); /* 1U is trigger0 mask. */ while (!g_Transfer_Done) { /* DMA転送終了割り込み待ち */ } g_Transfer_Done = false;   5. DMA传输完成中断处理 void APP_DMA_IRQ_HANDLER(void) { if ((EDMA_GetChannelStatusFlags(EXAMPLE_DMA_BASEADDR, DEMO_DMA_CHANNEL_0) & kEDMA_InterruptFlag) != 0U) { EDMA_ClearChannelStatusFlags(EXAMPLE_DMA_BASEADDR, DEMO_DMA_CHANNEL_0, kEDMA_InterruptFlag); g_Transfer_Done = true; } } 概括: 本文介绍了MCX A153 ADC的基本功能和注意事项,以及如何使用VS Code SDK的ADC示例项目进行初始化和转换。阅读本文后半部分,您将看到一些配置示例和代码流程,这些内容在实际开发中非常有用,涵盖了从使用ADC示例进行初始化和转换,到使用DMA自动传输转换结果等各个环节。(建议您先运行ADC示例并确认其运行正常,然后再添加DMA,这样更容易排查问题。) =========================​ 我们目前无法 回复 此帖子“ 评论”部分留下的评论。 对于由此造成的不便,我们深表歉意,但在进行咨询时,请参考“ NXP技术问题-如何联系我们(日语博客) ”。 (如果您已经是 恩智浦的 分销商或 与 恩智浦 有合作关系 ,您可以直接咨询您的代表。 ) 本文全面讲解了MCX A153中ADC(模数转换器)的基础知识,包括如何使用MCUXpresso SDK进行初始化,以及如何使用DMA自动传输转换结果。如果您是第一次使用ADC或DMA,建议您先阅读第1章和第2章,了解整体概念,然后再阅读第4章的示例代码和第5章的DMA设置,以便更好地理解。 ADC:一种将模拟信号(例如来自传感器的信号)转换为微控制器可以处理的数字值的功能。 DMA:一种无需经过 CPU 即可在外围设备和内存之间传输数据的功能。 SDK:包含软件开发所需的驱动程序和示例代码的开发工具包。 (阅读时间:30分钟) 通用微控制器 介绍 MCUXpresso IDE MCUXpresso SDK 日本博客
記事全体を表示
[MCX A153] Basics and Usage of the ADC Module (Japanese Blog) This article explains the basic usage of the ADC (Analog-to-Digital Converter) module installed in the MCX A153 . Starting with application examples using the ADC, it summarizes the main functions, block structure, and points to note when using it, and then introduces device initialization using SDK sample code and how to transfer ADC conversion results using DMA. This article aims to help you understand the fundamentals required when using the MCX A153 ADC in your applications, enabling you to implement everything from initial setup for ADC conversion to efficient data transfer utilizing DMA.   table of contents 1. Common use cases in applications 1.1 Main Uses 1.2 Usage example 2. Main functions and block diagram of the MCX A153 ADC module 2.1 Overview 2.2 Main Features 2.3 Block Diagram 3. Points to note and restrictions 4. ADC Sample Code (Device Initialization) 4.1 Overview of Sample Code 4.2 Opening the SDK Sample Project 4.3 Macro Definitions 4.4 Device Initialization 5. Transfer of AD conversion values using MCX A153 DMA 5.1 Code related to ADC 5.2 DMA-related code summary 1. Common use cases in applications An ADC converts analog signals (continuously changing voltages) input from sensors, potentiometers, etc., into digital values (numerical values) that a microcontroller can use for calculations. 1.1 Main Uses Converts the analog voltage value input from the potentiometer to a digital value. A potentiometer is attached to the shaft of a servo motor, such as those used in radio-controlled vehicles, to detect the angle of rotation of the motor from the change in output. Convert analog signals from various sensors into digital values. It detects the tilt of an object by converting analog signals from an accelerometer. This can be applied to detecting the orientation of a smartphone, for example. The ambient temperature is measured by converting the analog signal from the temperature sensor.   1.2 Usage Examples (These are examples illustrating the general concept, so details are omitted.) Examples of potentiometer usage:         2. Main Functions and Block Diagram   2.1 Overview The MCX A153 is equipped with a 16-bit analog-to-digital converter (ADC). An ADC is a circuit that converts analog voltages into digital values.   2.2 Main Features Equipped with one successive approximation AD converter unit. Supports 16-bit or 12-bit resolution and single-ended input (higher resolution allows for finer representation of input voltage). Number of channels installed (varies depending on the package): 64-pin LQFP: 24 channels, 48-pin LQFP: 16 channels, 48-pin HVQFN: 18 channels, 32-pin HVQFN: 9 channels Sampling rate (how many times per second the data can be converted) 16-bit mode: up to 3.2 Msps, 12-bit mode: up to 4 Msps Sample time can be set. Can operate in low-power mode of the microcontroller. Supports four trigger sources (software or hardware triggers). Seven command buffers enable scanning of consecutive channels. Supports compare function (automatically compares smaller, larger, within range, outside range, save as match, etc.) Equipped with eight FIFOs for conversion result data, featuring watermark and overflow detection functions. Supports interrupts, DMA, and polling. Calibration function Built-in temperature sensor with dedicated input channel   2.3 Block Diagram MCX A153 Reference Manual (MCXAP64M96FS3RM) Figure 165. Excerpt from ADC block diagram   Example of using SDK sample code (connecting a potentiometer)     3. MCX A153 ADC Module This section explains important points and limitations to consider before using the MCX A153's ADC. Speed reduction in 16-bit mode The MCX A153's ADC supports two modes: 16-bit (ENOB16: 16-bit effective resolution) and 12-bit (ENOB12: 12-bit effective resolution). However, the 16-bit mode has a lower sampling rate than the 12-bit mode. (Excerpt from MCX A153 DataSheet Table.34) Timing of calibration execution Calibration requests and execution must be performed during reset or power-on. Furthermore, the clock source and frequency must be configured before calibration can be performed. Averaging of conversion results The ADC module can average multiple results for the same channel before saving the conversion result. The hardware averaging function is enabled when the CMDHa[AVGS] bit field is set to a non-zero value. It can be used in any conversion mode and reduces the burden of calculating the average in software. 4. Sample code for AD conversion 4.1 Overview of Sample Code When the main sequence is executed, device initialization is performed. Device initialization begins with setting the clock, configuring the external terminals, and selecting the peripherals to connect to the terminals. After that, the peripherals (ADC, UART) are initialized and interrupts are enabled. After the initialization process, a software trigger is set within the loop to start ADC conversion, and the AD conversion value and the number of conversions are displayed on the console. For hardware, we will use the MCX A153 development board "FRDM-MCXA153".   4.2 Steps to open the ADC sample project in VS Code 4.2.1 Preparing VS Code and Extensions Install VS Code. Search for "MCUXpresso for VS Code" in the Extensions view (Ctrl+Shift+X) and install it. The MCUXpresso icon will appear in the activity bar on the left. Click it to open the QUICKSTART PANEL.   4.2.2 Installing Dependent Tools Run "Open MCUXpresso Installer" in the QUICKSTART PANEL. Select and install the following tool. Arm GNU Toolchain CMake / Ninja Python / West Git LinkServer (Debug probe for MCU-Link) SDK-related tools After completion, restart VS Code.   4.2.3Incorporating the SDK repository Click "Import Repository" in the QUICKSTART PANEL. Select "Remote" as the source for importing data.   Specify the destination folder. The path should be short and should not contain Japanese characters or spaces. You can import the repository by checking "I agree" and pressing the Import button.   4.2.4 Importing Samples In the QUICKSTART PANEL, click "Import Example from Repository". Set it as follows:   You can import the project by clicking the Import button. item Set value Repository The SDK (frdm_mcxa153) imported in step 3 Toolchain Arm GNU Toolchain Board frdmmcxa153 (FRDM-MCXA153) Template driver_examples → lpadc → interrupt(lpadc_interrupt) Location Project save location Name Optional (default is lpadc_interrupt) 4.3 Macro Definitions This is the macro definition code for the ADC's functions (excerpted from lpadc\interrupt\app.h). Please adjust the input channels, resolution settings, and reference voltage sources to match your actual circuit design and intended use. Definitions //(lpadc\interrupt\app.hから抜粋) /******************************************************************************/ #define DEMO_LPADC_BASE ADC0 //ADCのinstance、ベースアドレス、MCX A153は1個 ADCしかない #define DEMO_LPADC_IRQn ADC0_IRQn #define DEMO_LPADC_IRQ_HANDLER_FUNC ADC0_IRQHandler #define DEMO_LPADC_USER_CHANNEL 0U //チャンネル番号 #define DEMO_LPADC_USER_CMDID 1U //コマンドID #define DEMO_LPADC_VREF_SOURCE kLPADC_ReferenceVoltageAlt3 //参考電圧ソース #define DEMO_LPADC_DO_OFFSET_CALIBRATION true //オフセットキャリブレーションの利用可否 #define DEMO_LPADC_USE_HIGH_RESOLUTION true //高分解能の利用可否 Variables related to ADC Variables //(lpadc\interrupt\lpadc_interrupt.cから抜粋) volatile bool g_LpadcConversionCompletedFlag = false; volatile uint32_t g_LpadcInterruptCounter = 0U; lpadc_conv_result_t g_LpadcResultConfigStruct; #if (defined(DEMO_LPADC_USE_HIGH_RESOLUTION) && DEMO_LPADC_USE_HIGH_RESOLUTION) //高分解能 const uint32_t g_LpadcFullRange = 65536U; const uint32_t g_LpadcResultShift = 0U; #else //低分解能 const uint32_t g_LpadcFullRange = 4096U; const uint32_t g_LpadcResultShift = 3U; #endif /* DEMO_LPADC_USE_HIGH_RESOLUTION */ Defaulting of the ADC configuration structure (details can be found in fsl_lpadc.c), averaging of conversion results. //(lpadc\interrupt\lpadc_interrupt.cから抜粋) LPADC_GetDefaultConfig(&mLpadcConfigStruct); mLpadcConfigStruct.enableAnalogPreliminary = true; //ADCアナログ回路は事前に有効化され、起動遅延なしで変換を実行する準備 #if defined(DEMO_LPADC_VREF_SOURCE) mLpadcConfigStruct.referenceVoltageSource = DEMO_LPADC_VREF_SOURCE; //参考電圧ソース #endif /* DEMO_LPADC_VREF_SOURCE */ #if defined(FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS) && FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS mLpadcConfigStruct.conversionAverageMode = kLPADC_ConversionAverage; //変換結果平均化設定、平均しない/2回の平均/4回の平均/8回の平均/16回の平均....1024回の平均化選択可能 #endif     4.4 Device Initialization     Initialization of clock division ratio The CLOCK_SetClockDiv function handles the clock division settings used by the ADC peripheral. //(lpadc\interrupt\hardware_init.cから抜粋) /* Attach peripheral clock */ CLOCK_SetClockDiv(kCLOCK_DivADC0, 1u); div_name: Select a frequency divider defined by the enumeration. value: division ratio *The following code is the driver section starting with fsl_clock.c, and user modification is not recommended. //(fsl_clock.cから抜粋) void CLOCK_SetClockDiv(clock_div_name_t div_name, uint32_t value) { volatile uint32_t *pDivCtrl = (volatile uint32_t *)(MRCC0_BASE + (uint32_t)div_name); assert(div_name <= kCLOCK_DivMax); /* Unlock clock configuration */ SYSCON->CLKUNLOCK &= ~SYSCON_CLKUNLOCK_UNLOCK_MASK; /* halt and reset clock dividers */ *pDivCtrl = 0x3UL << 29U; if (value == 0U) /*!< halt */ { *pDivCtrl |= (1UL << 30U); } else { *pDivCtrl = (value - 1U); } /* Freeze clock configuration */ SYSCON->CLKUNLOCK |= SYSCON_CLKUNLOCK_UNLOCK_MASK; }   Clock selection CLOCK_AttachClk selects one of four clock sources to be used by the ADC peripheral. The driver configures the connection by passing a value defined in the `clock_attach_id_t` structure as an argument to the `void CLOCK_AttachClk(clock_attach_id_t connection)` function. //(fsl_clock.hから抜粋) kFRO12M_to_ADC0 = CLK_ATTACH_MUX(kCLOCK_SelADC0, 0U), /* Attach FRO12M to ADC0. */ kFRO_HF_to_ADC0 = CLK_ATTACH_MUX(kCLOCK_SelADC0, 1U), /* Attach FRO_HF to ADC0. */ kCLK_IN_to_ADC0 = CLK_ATTACH_MUX(kCLOCK_SelADC0, 3U), /* Attach CLK_IN to ADC0. */ kCLK_1M_to_ADC0 = CLK_ATTACH_MUX(kCLOCK_SelADC0, 5U), /* Attach CLK_1M to ADC0. */ kNONE_to_ADC0 = CLK_ATTACH_MUX(kCLOCK_SelADC0, 7U), /* Attach NONE to ADC0. */ //(lpadc\interrupt\hardware_init.cから抜粋) CLOCK_AttachClk(kFRO12M_to_ADC0); The following functions are part of the driver section provided by the SDK, starting with fsl_clock.c, and it is not recommended that users modify them. //(fsl_clock.hから抜粋) void CLOCK_AttachClk(clock_attach_id_t connection) { const uint32_t reg_offset = CLK_ATTACH_REG_OFFSET(connection); const uint32_t clk_sel = CLK_ATTACH_CLK_SEL(connection); if (kNONE_to_NONE != connection) { CLOCK_SetClockSelect((clock_select_name_t)reg_offset, clk_sel); } } //(fsl_clock.hから抜粋) void CLOCK_SetClockSelect(clock_select_name_t sel_name, uint32_t value) { volatile uint32_t *pClkCtrl = (volatile uint32_t *)(MRCC0_BASE + (uint32_t)sel_name); assert(sel_name <= kCLOCK_SelMax); if (sel_name == kCLOCK_SelSCGSCS) { SCG0->RCCR = (SCG0->RCCR & ~(SCG_RCCR_SCS_MASK)) | SCG_RCCR_SCS(value); while ((SCG0->CSR & SCG_CSR_SCS_MASK) != SCG_CSR_SCS(value)) { } } else { /* Unlock clock configuration */ SYSCON->CLKUNLOCK &= ~SYSCON_CLKUNLOCK_UNLOCK_MASK; *pClkCtrl = value; /* Freeze clock configuration */ SYSCON->CLKUNLOCK |= SYSCON_CLKUNLOCK_UNLOCK_MASK; } } Regarding the board initialization function The clock will be initialized.   Pin initialization The InitPins() function is called, and the pin_mux.c file is processed. The pin_mux.c file is used by NXP's MCUXPressoThis can be overridden using the Pin Config tool integrated into the IDE. //(lpadc\interrupt\hardware_init.cから抜粋) BOARD_InitPins(); The BOARD_InitPins() function performs four operations. Enable peripheral clock Disable peripheral reset External pin-to-pin and peripheral connection (MUX configuration) -> Parameter setting for the structure Write 3 to the register   Initializing the boot clock The MCX A153 supports Mid Drive Mode and Standard Drive Mode. These modes operate with VDD_CORE voltage levels of 1.0 V and 1.1 V, respectively, and with an rfo_hf clock of 48 MHz or 96 MHz. Switching modes requires external power supply and configuration of voltage-related registers such as the LDO. //(lpadc\interrupt\hardware_init.cから抜粋) BOARD_InitBootClocks(); The clock is set using a register setting function that corresponds to the operating frequency. //(fsl_clock.cから抜粋) void BOARD_InitBootClocks(void) { BOARD_BootClockFRO96M(); }     Initializing the debug port //(lpadc\interrupt\hardware_init.cから抜粋) BOARD_InitDebugConsole();   //(board.cから抜粋) void BOARD_InitDebugConsole(void) { /* attach 12 MHz clock to LPUART0 (debug console) */ CLOCK_SetClockDiv(kCLOCK_DivLPUART0, 1u); CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH); RESET_PeripheralReset(BOARD_DEBUG_UART_RST); DbgConsole_Init(BOARD_DEBUG_UART_INSTANCE, BOARD_DEBUG_UART_BAUDRATE, BOARD_DEBUG_UART_TYPE, BOARD_DEBUG_UART_CLK_FREQ); }   Application initialization ADC initialization is handled within the LPADC_Init(DEMO_LPADC_BASE, &mLpadcConfigStruct); function. The LPADC_Init() function is a function in the driver section of fsl_lpadc.c. DEMO_LPADC_BASE: 0x400A_F000 -> Starting address of the ADC Define the structure table and configure the ADC. typedef struct {} lpadc_config_t name attribute explanation lpadc_config_t type LPADC Configuration Parameter Information enableInDozeMode bool Operation settings based on mode during ADC conversion conversionAverageMode lpadc_conversion_average_mode_t Settings related to Auto Calibration enableAnalogPreliminary bool ADC pre-startup settings PowerUpDelay uint32_t Stabilization time of ADC circuit referenceVoltageSource lpadc_reference_voltage_source_t Source of reference voltage powerLevelMode lpadc_power_level_mode_t Power supply configuration selection triggerPriorityPolicy lpadc_trigger_priority_policy_t How to process high-profitability triggers EnableConvPause bool Setting the AD conversion execution interval. convPauseDelay uint32_t Pause time during command sequence FIFOWatermark uint32_t Threshold setting for the number of data points in FIFO //(lpadc\interrupt\lpadc_interrupt.cから抜粋) LPADC_Init(DEMO_LPADC_BASE, &mLpadcConfigStruct); //(fsl_lpadc.cから抜粋) void LPADC_Init(ADC_Type *base, const lpadc_config_t *config) { /* 省略 */ base->CTRL |= ADC_CTRL_CAL_AVGS(config->conversionAverageMode); /* 省略 */ }   About ADC calibration   Before using an ADC, calibration is performed to correct for offset errors and other factors included in the conversion result, thereby improving the accuracy of the AD conversion. The calibration process can be broadly divided into the following two stages: Set the calibration mode and conditions. Perform calibration and apply the correction values to the ADC.   In the default sample, ADC calibration is performed after LPADC_Init() is executed and before AD conversion begins. First, the offset calibration mode is set with LPADC_SetOffsetCalibrationMode() on the corresponding device. Then, if DEMO_LPADC_DO_OFFSET_CALIBRATION is enabled, LPADC_DoOffsetCalibration() is executed; otherwise, the offset value set in advance with LPADC_SetOffsetValue() is used. Furthermore, if the corresponding function macro is enabled, LPADC_DoAutoCalibration() is executed after a delay of 1 µs or more. This performs calibration of gain errors and linearity errors. Each process is compiled only if the function macro supported by the device is enabled. The following are the settings for the LPADC calibration mode. //(lpadc\interrupt\lpadc_interrupt.cから抜粋) /* Request LPADC calibration. */ #if defined(FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE) && FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE LPADC_SetOffsetCalibrationMode(DEMO_LPADC_BASE, DEMO_LPADC_OFFSET_CALIBRATION_MODE); #endif /* FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE */     Performing offset calibration //(lpadc\interrupt\lpadc_interrupt.cから抜粋) #if defined(FSL_FEATURE_LPADC_HAS_CTRL_CALOFS) && \ FSL_FEATURE_LPADC_HAS_CTRL_CALOFS #if defined(DEMO_LPADC_DO_OFFSET_CALIBRATION) && \ DEMO_LPADC_DO_OFFSET_CALIBRATION L PADC_DoOffsetCalibration(DEMO_LPADC_BASE); //キャリブレーションを実行しない場合 #else /* Update OFSTRIM register manually. */   5. MCX A153 DMA Why use DMA transfer for ADC conversion? When processing data acquired by an ADC solely in software, the CPU needs to monitor the completion of the ADC conversion, read the conversion results, and write them to memory. This is not a major problem for a single AD conversion, but when sampling continuously at regular intervals or when handling multiple input channels, this process occurs repeatedly. As a result, the CPU processing load increases, potentially reducing the time available for other application processing. One way to solve this problem is to transfer the ADC conversion results using DMA (Direct Memory Access). Using DMA, the ADC conversion results can be automatically transferred to memory as soon as the ADC conversion is complete. In other words, since the process from acquiring the ADC conversion results to storing them in memory can be handled by hardware, the amount of data transfer processing performed by the CPU can be reduced, and the processing load on the software can be lowered. For these reasons, configurations combining ADC and DMA are often used in applications requiring continuous AD conversion and high-speed data acquisition. This article will first explain the basic initialization method of the ADC, and then introduce how to transfer the ADC conversion result to memory using DMA with the MCX A153. Overview of AD conversion value transfer using DMA The data after AD conversion is stored in a buffer within the ADC peripheral. Instead of reading the data manually each time, the ADC may trigger DMA to transfer the data. For example, the program will be modified to perform AD conversion five times consecutively, then save the data to a RAM buffer via DMA, and display the average, minimum, and maximum values on the console. Procedure for transferring AD conversion values using DMA We will modify the ADC sample code to add DMA processing. DMA activation is performed using a DMA Request signal from the ADC. Using DMA, the ADC FIFO values (for 5 conversions) are copied to RAM, and an interrupt is notified to the CPU. The CPU takes the average value within the main loop after the DMA transfer is complete and displays the min, max, and ave values to the console.     Precautions To add DMA code, you need to add the DMA driver header file and source code to your project. The easiest way to do this is to create a sample DMA code (frdmmcxa153_edma3_memory_to_memory_transfer) from the MCUXpresso IDE and copy it. Simply copy the following files from the drivers directory. fsl_edma_core.h fsl_edma_soc.c fsl_edma_soc.h fsl_edma.c fsl_edma.h   5.1 Code modifications and additions related to ADC   Code modification steps The interrupt that occurs when ADC conversion is complete has been disabled. Added ADC configuration. Setting to perform AD conversion 5 times consecutively. Enable DMA requests Set the FIFO watermark to 4. Added processing to obtain the average, minimum, and maximum values of the values transferred by DMA, and to output them to the console.     1. Disable interrupts when ADC conversion is complete. Since the Interrupt Enable Register (IE) is enabled using the LPADC_EnableInterrupts() function and kLPADC_FIFOWatermarkInterruptEnable, we will comment out this line. // LPADC_EnableInterrupts(DEMO_LPADC_BASE, kLPADC_FIFOWatermarkInterruptEnable);   2. Add ADC configuration The ADC is configured to loop 5 times (= 5 AD conversions). mLpadcCommandConfigStruct.loopCount = 4 //loopCount +1回の変換 Enable DMA requests //178行目 LPADC_EnableFIFOWatermarkDMA(DEMO_LPADC_BASE, 1); // 1でDMA Requestがイネーブル     3. Set the number of Watermark levels in the FIFO to 4. // 33行目 /* ++ ADCのマクロ */ #define FIFO0WatermarkLEVEL (4) //108行目 mLpadcConfigStruct.FIFOWatermark = FIFO0WatermarkLEVEL;   4. Added processing to obtain the average, minimum, and maximum values of the values transferred by DMA, and console output. uint32_t adc_values[5] = {0}; PRINTF("Please press any key to get user channel's ADC value.\r\n"); while(1) { GETCHAR(); EXAMPLE_DMA_BASEADDR->CH[0].CH_CSR = DMA_CH_CSR_ERQ(1); EXAMPLE_DMA_BASEADDR->CH[0].TCD_DLAST_SGA = -0x14; LPADC_DoSoftwareTrigger(DEMO_LPADC_BASE, 1U); /* 1U is trigger0 mask. */ while (!g_Transfer_Done) { /* DMA転送終了割り込み待ち */ } g_Transfer_Done = false; uint16_t min=adc_values[0]; uint16_t max=adc_values[0]; uint32_t sum=0; for(uint32_t i=0; i<5; i++) { if(max < (0x0000FFFF & adc_values[i])) max = adc_values[i]; if(min > (0x0000FFFF & adc_values[i])) min = adc_values[i]; sum += 0x0000FFFF & adc_values[i]; } PRINTF("ADC Min: %d, Max: %d, ave: %d\r\n", min, max, sum/5); for(size_t i=0; i<5; i++) { adc_values[i] = 0; } sum = 0; }   5.2 Adding DMA-related code   Code Addition Policy Include header files Added DMA-related macros. DMA configuration and initialization DMA transfer configuration DMA transfer completion interrupt handling   1. Include headers // 10行目 #include "fsl_debug_console.h" #include "pin_mux.h" #include "clock_config.h" #include "board.h" #include "fsl_lpadc.h" /* ++ */ #include "fsl_edma.h" // DMAドライバヘッダファイルの追加 #include "fsl_clock.h" #include "fsl_reset.h"   2. Add DMA-related macros. // 32行目 #define EXAMPLE_DMA_BASEADDR DMA0 #define DEMO_DMA_CHANNEL_0 0U #define APP_DMA_IRQ DMA_CH0_IRQn #define APP_DMA_IRQ_HANDLER DMA_CH0_IRQHandler     3. DMA Configuration // 197行目 edma_transfer_config_t transferConfig; edma_config_t userConfig; // 203行目 RESET_PeripheralReset(kDMA_RST_SHIFT_RSTn); /* Configure EDMA channel for one shot transfer */ EDMA_GetDefaultConfig(&userConfig); EDMA_Init(EXAMPLE_DMA_BASEADDR, &userConfig);     4. DMA transfer configuration // 209行目 EDMA_PrepareTransfer(&transferConfig, (void *)0x400AF300, // eDMA transfer source address. sizeof(uint32_t), // eDMA transfer source address width(bytes) (void *)adc_values, // eDMA transfer destination address sizeof(&adc_values), // eDMA transfer destination address width(bytes) sizeof(adc_values), // eDMA transfer bytes per channel request sizeof(adc_values), // eDMA transfer bytes to be transferred kEDMA_PeripheralToMemory // eDMA transfer type ); EDMA_SetTransferConfig(EXAMPLE_DMA_BASEADDR, DEMO_DMA_CHANNEL_0, &transferConfig, NULL); EDMA_SetChannelMux(EXAMPLE_DMA_BASEADDR, DEMO_DMA_CHANNEL_0, kDma0RequestMuxAdc0FifoRequest); EnableIRQ(APP_DMA_IRQ); EDMA_EnableChannelInterrupts(EXAMPLE_DMA_BASEADDR, DEMO_DMA_CHANNEL_0, kEDMA_MajorInterruptEnable); Before starting the software ADC with a software trigger, add EDMA_TriggerChannelStart() to trigger an interrupt on DMA channel 0. When the DMA interrupt flag is cleared, DMA-triggered interrupts are disabled, so this processing is added before the ADC's software trigger. // 242行目 while(1) { GETCHAR(); EDMA_TriggerChannelStart(EXAMPLE_DMA_BASEADDR, DEMO_DMA_CHANNEL_0); EXAMPLE_DMA_BASEADDR->CH[0].TCD_DLAST_SGA = -0x14; LPADC_DoSoftwareTrigger(DEMO_LPADC_BASE, 1U); /* 1U is trigger0 mask. */ while (!g_Transfer_Done) { /* DMA転送終了割り込み待ち */ } g_Transfer_Done = false;   5. DMA transfer completion interrupt handling void APP_DMA_IRQ_HANDLER(void) { if ((EDMA_GetChannelStatusFlags(EXAMPLE_DMA_BASEADDR, DEMO_DMA_CHANNEL_0) & kEDMA_InterruptFlag) != 0U) { EDMA_ClearChannelStatusFlags(EXAMPLE_DMA_BASEADDR, DEMO_DMA_CHANNEL_0, kEDMA_InterruptFlag); g_Transfer_Done = true; } } summary: This article explained the basic functions and points to note about the MCX A153 ADC, as well as the initialization and conversion process using the VS Code SDK's ADC sample project . Following the latter part of this article, you should be able to see configuration examples and code flows that will be useful in actual development, from initialization and conversion using the ADC sample to automatic transfer of conversion results using DMA. (It's easier to isolate problems if you first run the ADC sample and confirm its operation before adding DMA.) =========================​ We are currently unable to respond to comments left in the " Comment " section of this post . We apologize for the inconvenience, but please refer to " Technical Questions to NXP - How to Contact Us( Japanese Blog) " when making inquiries. (If you are already an NXP distributor or have a relationship with NXP, you may ask your representative directly.) This article explains everything from the basics of the ADC (analog-to-digital converter) in the MCX A153 , to initialization using the MCUXpresso SDK, and even automatic transfer of conversion results using DMA. If you are using ADC or DMA for the first time, it is recommended to first review the overall picture in Chapters 1 and 2, and then proceed to the sample code in Chapter 4 and the DMA settings in Chapter 5 for easier understanding. ADC: A function that converts analog signals, such as those from sensors, into digital values that can be handled by a microcontroller. DMA: A function that transfers data between peripherals and memory without going through the CPU. SDK: A development kit containing drivers and sample code necessary for software development. (Reading time: 30 minutes) General Purpose Microcontrollers Introduction MCUXpresso IDE MCUXpresso SDK Japanese Blog
記事全体を表示
[MCX A153] ADCモジュールの基本と使い方 (日本語ブログ)    この記事はMCX A153に搭載されたADC(Analog-to-Digital Converter)モジュールの基本的な使い方を説明します。ADCを利用したアプリケーション例から始め、主な機能、ブロック構成、使用時の注意点を整理したうえで、SDKサンプルコードを使ったデバイス初期化と、DMAによるADC変換結果の転送方法を紹介します。 この記事を読むことで、MCX A153のADCをアプリケーションで使用する際に必要となる基本事項を理解し、ADC変換を行うための初期設定から、DMAを活用した効率的なデータ転送までを実装できるようになることを目指します。   目次 1. アプリケーション上のよくある使用例        1.1 主な用途        1.2 使用例 2. MCX A153 ADCモジュールの主な機能とブロック図               2.1 概要               2.2 主な機能               2.3 ブロック図 3. 注意点、制限事項 4. ADCサンプルコード(デバイスの初期化)             4.1 サンプルコードの概要             4.2 SDKサンプルプロジェクトを開くまで             4.3 マクロ定義             4.4 デバイスの初期化 5. MCX A153 DMAを用いたAD変換値の転送           5.1 ADCに関するコード           5.2 DMAに関するコード まとめ 1. アプリケーション上のよくある使用例 ADCは、センサやポテンショメータなどから入力されたアナログ信号(連続的に変化する電圧)を、マイコンが計算に使えるデジタル値(数値)へ変換します。 1.1 主な用途 ポテンショメータから入力されたアナログの電圧値をデジタル値に変換 ポテンショメータをラジコンなどのサーボモータの軸に取り付けて、出力の変化からモータが回転した角度を検出する。 各種センサからのアナログ信号をデジタル値に変換 加速度センサからのアナログ信号を変換して物体の傾きを検出する。スマホの縦横の向きの検知などに応用できる。 温度センサからのアナログ信号を変換して周囲温度を測定する。   1.2 使用例 (概要を説明している例なので詳細は割愛しています) ポテンショメータの使用例:         2. 主な機能とブロック図   2.1 概要   MCX A153には、16ビットのADコンバータ(ADC)が搭載されています。ADコンバータは、アナログ電圧をデジタル値に変換する回路です。   2.2 主な機能 逐次比較型ADコンバータを1ユニット搭載 16ビットまたは12ビットの分解能で、シングルエンド入力に対応(分解能が高いほど、入力電圧を細かく表現できます) 搭載チャネル数 (パッケージにより異なる): 64ピンLQFP:24ch、48ピンLQFP:16ch、48ピンHVQFN:18ch、32ピンHVQFN:9ch サンプリング速度 (1秒間に何回変換できるか) 16ビットモード:最大3.2Msps、12ビットモード:最大4Msps サンプル時間が設定可能 マイコンの低電力モードで動作可能 4つのトリガーソースに対応 (ソフトウェアまたはハードウェアトリガーに対応) 7つのコマンドバッファにより連続したチャネルのスキャンが可能 コンペア機能をサポート (より小さい、より大きい、範囲内、範囲外、一致で保存、などを自動比較) ウォーターマークとオーバーフロー検出機能を持つ8つ変換結果データFIFOを搭載 割り込み、DMA、ポーリングに対応 キャリブレーション機能 専用入力チャネルを持つ温度センサを内蔵   2.3 ブロック図 MCX A153リファレンスマニュアル(MCXAP64M96FS3RM) Figure 165. ADC block diagramから抜粋   SDKサンプルコードの使用例 (ポテンショメータを接続)     3. MCX A153 ADCモジュール <注意点、制限事項> ここでは、MCX A153のADCを使う前に確認しておきたい注意点と制限事項を説明します。 16bitモードの速度低下 MCX A153のADCは、16ビット(ENOB16:実効分解能16ビット)と12ビット(ENOB12:実効分解能12ビット)の2つのモードに対応しています。ただし、16ビットモードは12ビットモードよりも、サンプリング速度が低下します。 (MCX A153 DataSheet Table.34から抜粋) キャリブレーションの実行タイミング キャリブレーションへのリクエスト&実行は、リセットまたは電源投入時に行わなければなりません。そして、キャリブレーション実行する前に、クロックソースと周波数をコンフィグする必要があります。 変換結果の平均化 ADCモジュールは、変換結果を保存する前に、同じチャネルの複数の結果を平均化できます。ハードウェア平均機能は、CMDHa[AVGS]ビットフィールドを0以外に設定すると有効になります。どの変換モードでも使用でき、ソフトウェアで平均値を計算する負担を減らせます。 4. AD変換のサンプルコード 4.1 サンプルコードの概要 mainシーケンスが実行されると、デバイスの初期化が実行されます。 デバイスの初期化は、クロックの設定に始まり、外部端子の構成と端子に接続するペリフェ ラルの選択をします。その後、ペリフェラル(ADC、UART)の初期化と、割り込みを有効に します。 初期化処理後、ループ処理内でADC変換開始のソフトウェアトリガをかけて、コンソールに AD変換の値と変換回数を表示します。 ハードウェアとしては、MCX A153の開発ボード「FRDM-MCXA153」を使用します。   4.2 VS codeでADCのサンプルプロジェクトを開くまでの手順 4.2.1 VS Codeと拡張機能の準備 VS Codeをインストールします。 拡張機能ビュー(Ctrl+Shift+X)で 「MCUXpresso for VS Code」 を検索してインストールします。 左のアクティビティバーにMCUXpressoアイコンが出ます。それをクリックして QUICKSTART PANEL を開きます。   4.2.2 依存ツールのインストール QUICKSTART PANELで 「Open MCUXpresso Installer」 を実行します。 次のツールを選んでインストールします。 Arm GNU Toolchain CMake / Ninja Python / West Git LinkServer(MCU-Link用デバッグプローブ) SDK 関連ツール 完了後、VS Codeを再起動します。   4.2.3 SDKリポジトリの取り込み QUICKSTART PANELで 「Import Repository」 をクリックします。 取り込み元として、リモートを選びます   保存先フォルダを指定します。パスは短く、日本語やスペースを含まないものにします  "I agree"をチェックして、Importボタンを押すことでレポジトリをインポートできます。   4.2.4 サンプルのインポート QUICKSTART PANELで 「Import Example from Repository」 をクリックします。 次のように設定します。   Importボタンを押すことで、プロジェクトをimportできます。 項目 設定値 Repository 手順3で取り込んだSDK(frdm_mcxa153) Toolchain Arm GNU Toolchain Board frdmmcxa153(FRDM-MCXA153) Template driver_examples → lpadc → interrupt(lpadc_interrupt) Location プロジェクト保存先 Name 任意(既定はlpadc_interrupt) 4.3 マクロ定義 ADCの機能に関するマクロ定義のコードです(lpadc\interrupt\app.hから抜粋)。 実際の回路設計と使用目的に合わせて、入力チャンネル、分解能設定、参考電圧ソースを修正してください。 Definitions //(lpadc\interrupt\app.hから抜粋) /******************************************************************************/ #define DEMO_LPADC_BASE ADC0 //ADCのinstance、ベースアドレス、MCX A153は1個 ADCしかない #define DEMO_LPADC_IRQn ADC0_IRQn #define DEMO_LPADC_IRQ_HANDLER_FUNC ADC0_IRQHandler #define DEMO_LPADC_USER_CHANNEL 0U //チャンネル番号 #define DEMO_LPADC_USER_CMDID 1U //コマンドID #define DEMO_LPADC_VREF_SOURCE kLPADC_ReferenceVoltageAlt3 //参考電圧ソース #define DEMO_LPADC_DO_OFFSET_CALIBRATION true //オフセットキャリブレーションの利用可否 #define DEMO_LPADC_USE_HIGH_RESOLUTION true //高分解能の利用可否 ADCに関する変数 Variables //(lpadc\interrupt\lpadc_interrupt.cから抜粋) volatile bool g_LpadcConversionCompletedFlag = false; volatile uint32_t g_LpadcInterruptCounter = 0U; lpadc_conv_result_t g_LpadcResultConfigStruct; #if (defined(DEMO_LPADC_USE_HIGH_RESOLUTION) && DEMO_LPADC_USE_HIGH_RESOLUTION) //高分解能 const uint32_t g_LpadcFullRange = 65536U; const uint32_t g_LpadcResultShift = 0U; #else //低分解能 const uint32_t g_LpadcFullRange = 4096U; const uint32_t g_LpadcResultShift = 3U; #endif /* DEMO_LPADC_USE_HIGH_RESOLUTION */ ADCに関する設定の構造体のデフォルト化(詳細はfsl_lpadc.cにある)、変換結果の平均化設定 //(lpadc\interrupt\lpadc_interrupt.cから抜粋) LPADC_GetDefaultConfig(&mLpadcConfigStruct); mLpadcConfigStruct.enableAnalogPreliminary = true; //ADCアナログ回路は事前に有効化され、起動遅延なしで変換を実行する準備 #if defined(DEMO_LPADC_VREF_SOURCE) mLpadcConfigStruct.referenceVoltageSource = DEMO_LPADC_VREF_SOURCE; //参考電圧ソース #endif /* DEMO_LPADC_VREF_SOURCE */ #if defined(FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS) && FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS mLpadcConfigStruct.conversionAverageMode = kLPADC_ConversionAverage; //変換結果平均化設定、平均しない/2回の平均/4回の平均/8回の平均/16回の平均....1024回の平均化選択可能 #endif     4.4 デバイスの初期化     クロック分周比の初期化 CLOCK_SetClockDiv関数では、ADCペリフェラルで使用するクロック分周設定を処理します。 //(lpadc\interrupt\hardware_init.cから抜粋) /* Attach peripheral clock */ CLOCK_SetClockDiv(kCLOCK_DivADC0, 1u); div_name: 列挙体で定義された分周器を選択 value: 分周比 ※以下のコードは、fsl_clock.cで始まるドライバ部となり、ユーザによる変更はオススメしません。 //(fsl_clock.cから抜粋) void CLOCK_SetClockDiv(clock_div_name_t div_name, uint32_t value) { volatile uint32_t *pDivCtrl = (volatile uint32_t *)(MRCC0_BASE + (uint32_t)div_name); assert(div_name <= kCLOCK_DivMax); /* Unlock clock configuration */ SYSCON->CLKUNLOCK &= ~SYSCON_CLKUNLOCK_UNLOCK_MASK; /* halt and reset clock dividers */ *pDivCtrl = 0x3UL << 29U; if (value == 0U) /*!< halt */ { *pDivCtrl |= (1UL << 30U); } else { *pDivCtrl = (value - 1U); } /* Freeze clock configuration */ SYSCON->CLKUNLOCK |= SYSCON_CLKUNLOCK_UNLOCK_MASK; }   クロック選択 CLOCK_AttachClkでは、ADCペリフェラルで用いるクロックソースを4つから選択します。 void CLOCK_AttachClk(clock_attach_id_t connection)関数の引数に 構造体clock_attach_id_tで定義された値を入れることで、ドライバにより設定が行われます。 //(fsl_clock.hから抜粋) kFRO12M_to_ADC0 = CLK_ATTACH_MUX(kCLOCK_SelADC0, 0U), /* Attach FRO12M to ADC0. */ kFRO_HF_to_ADC0 = CLK_ATTACH_MUX(kCLOCK_SelADC0, 1U), /* Attach FRO_HF to ADC0. */ kCLK_IN_to_ADC0 = CLK_ATTACH_MUX(kCLOCK_SelADC0, 3U), /* Attach CLK_IN to ADC0. */ kCLK_1M_to_ADC0 = CLK_ATTACH_MUX(kCLOCK_SelADC0, 5U), /* Attach CLK_1M to ADC0. */ kNONE_to_ADC0 = CLK_ATTACH_MUX(kCLOCK_SelADC0, 7U), /* Attach NONE to ADC0. */ //(lpadc\interrupt\hardware_init.cから抜粋) CLOCK_AttachClk(kFRO12M_to_ADC0); 以下の関数は、fsl_clock.cで始まるSDKで提供されているドライバ部の関数になり、ユーザーにより変更することはオススメしません。 //(fsl_clock.hから抜粋) void CLOCK_AttachClk(clock_attach_id_t connection) { const uint32_t reg_offset = CLK_ATTACH_REG_OFFSET(connection); const uint32_t clk_sel = CLK_ATTACH_CLK_SEL(connection); if (kNONE_to_NONE != connection) { CLOCK_SetClockSelect((clock_select_name_t)reg_offset, clk_sel); } } //(fsl_clock.hから抜粋) void CLOCK_SetClockSelect(clock_select_name_t sel_name, uint32_t value) { volatile uint32_t *pClkCtrl = (volatile uint32_t *)(MRCC0_BASE + (uint32_t)sel_name); assert(sel_name <= kCLOCK_SelMax); if (sel_name == kCLOCK_SelSCGSCS) { SCG0->RCCR = (SCG0->RCCR & ~(SCG_RCCR_SCS_MASK)) | SCG_RCCR_SCS(value); while ((SCG0->CSR & SCG_CSR_SCS_MASK) != SCG_CSR_SCS(value)) { } } else { /* Unlock clock configuration */ SYSCON->CLKUNLOCK &= ~SYSCON_CLKUNLOCK_UNLOCK_MASK; *pClkCtrl = value; /* Freeze clock configuration */ SYSCON->CLKUNLOCK |= SYSCON_CLKUNLOCK_UNLOCK_MASK; } } ボードの初期化関数について クロックの初期化を行います。   ピンの初期化 InitPins()を読み出し、pin_mux.cファイルの処理を行います。 pin_mux.cファイルは、NXPのMCUXPresso IDEに統合されているPin Configツールを用いて上書き可能です。 //(lpadc\interrupt\hardware_init.cから抜粋) BOARD_InitPins(); BOARD_InitPins()関数では、4つの処理を行います。 ペリフェラルのクロックの有効化 ペリフェラルのリセット解除 外部ピンとピンとペリフェラルの接続(MUXの設定)構成 -> 構造体へのパラメータ設定 3をレジスタへ書き込み   ブートクロックの初期化 MCX A153では、Mid Drive ModeとStandard Drive Modeをサポートしています。 それぞれ、VDD_COREの電圧レベルが、1.0 Vと1.1 Vで、rfo_hfクロックが48MHzもしくは96MHzで動作します。 モードを切り換えるには、外部からの電源供給に加えて、LDO等の電圧関連のレジスタ設定が必要です。 //(lpadc\interrupt\hardware_init.cから抜粋) BOARD_InitBootClocks(); 動作周波数に応じたレジスタ設定用の関数を用いて、クロックを設定します。 //(fsl_clock.cから抜粋) void BOARD_InitBootClocks(void) { BOARD_BootClockFRO96M(); }     デバッグポートの初期化 //(lpadc\interrupt\hardware_init.cから抜粋) BOARD_InitDebugConsole();   //(board.cから抜粋) void BOARD_InitDebugConsole(void) { /* attach 12 MHz clock to LPUART0 (debug console) */ CLOCK_SetClockDiv(kCLOCK_DivLPUART0, 1u); CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH); RESET_PeripheralReset(BOARD_DEBUG_UART_RST); DbgConsole_Init(BOARD_DEBUG_UART_INSTANCE, BOARD_DEBUG_UART_BAUDRATE, BOARD_DEBUG_UART_TYPE, BOARD_DEBUG_UART_CLK_FREQ); }   アプリケーションの初期化 ADCの初期化は、LPADC_Init(DEMO_LPADC_BASE, &mLpadcConfigStruct);関数内で処理されます。 LPADC_Init()の関数は、fsl_lpadc.cのドライバ部分の関数になります。 DEMO_LPADC_BASE: 0x400A_F000 -> ADCの先頭アドレス 構造体テーブルを定義して、ADCのコンフィギュレーションを行います。 typedef struct {} lpadc_config_t 名称 属性 説明 lpadc_config_t 型 LPADCコンフィグパラメータ情報 enableInDozeMode bool ADC変換中のモードによる動作設定 conversionAverageMode lpadc_conversion_average_mode_t Auto Calibrationに関する設定 enableAnalogPreliminary bool ADC事前起動設定 powerUpDelay uint32_t ADC回路の安定時間 referenceVoltageSource lpadc_reference_voltage_source_t 基準電圧のソース powerLevelMode lpadc_power_level_mode_t 電源構成の選択 triggerPriorityPolicy lpadc_trigger_priority_policy_t 高プロイオリティトリガの処理方法 enableConvPause bool AD変換実行間隔の設定 convPauseDelay uint32_t コマンドシーケンス中のポーズ時間 FIFOWatermark uint32_t FIFO内データ数の閾値設定 //(lpadc\interrupt\lpadc_interrupt.cから抜粋) LPADC_Init(DEMO_LPADC_BASE, &mLpadcConfigStruct); //(fsl_lpadc.cから抜粋) void LPADC_Init(ADC_Type *base, const lpadc_config_t *config) { /* 省略 */ base->CTRL |= ADC_CTRL_CAL_AVGS(config->conversionAverageMode); /* 省略 */ }   ADCのキャリブレーションについて   ADCでは、変換結果に含まれるオフセット誤差などを補正し、AD変換の精度を向上させるために、ADCの使用開始前にキャリブレーションを実行します。 キャリブレーション処理は、主に次の2段階に分けて考えることができます。 キャリブレーションのモードや条件を設定する キャリブレーションを実行し、補正値をADCへ反映する   デフォルトサンプルでは、LPADC_Init()の実行後、AD変換を開始する前にADCキャリブレーションを実行します。まず、対応するデバイスではLPADC_SetOffsetCalibrationMode()でオフセットキャリブレーションのモードを設定します。その後、DEMO_LPADC_DO_OFFSET_CALIBRATIONが有効な場合はLPADC_DoOffsetCalibration()を実行し、無効な場合はLPADC_SetOffsetValue()であらかじめ設定したオフセット値を使用します。 さらに、対応する機能マクロが有効な場合は、1 µs以上の待ち時間を置いてLPADC_DoAutoCalibration()を実行します。これにより、ゲイン誤差や直線性誤差のキャリブレーションを行います。各処理は、デバイスがサポートする機能マクロが有効な場合にのみコンパイルされます。   下記はLPADCのキャリブレーションモードの設定です。 //(lpadc\interrupt\lpadc_interrupt.cから抜粋) /* Request LPADC calibration. */ #if defined(FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE) && FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE LPADC_SetOffsetCalibrationMode(DEMO_LPADC_BASE, DEMO_LPADC_OFFSET_CALIBRATION_MODE); #endif /* FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE */     オフセットキャリブレーションの実行 //(lpadc\interrupt\lpadc_interrupt.cから抜粋) #if defined(FSL_FEATURE_LPADC_HAS_CTRL_CALOFS) && \ FSL_FEATURE_LPADC_HAS_CTRL_CALOFS #if defined(DEMO_LPADC_DO_OFFSET_CALIBRATION) && \ DEMO_LPADC_DO_OFFSET_CALIBRATION L PADC_DoOffsetCalibration(DEMO_LPADC_BASE); //キャリブレーションを実行しない場合 #else /* Update OFSTRIM register manually. */   5. MCX A153 DMA ADC変換にDMA転送を用いる理由 ADCで取得したデータをソフトウェアだけで処理する場合、ADC変換の完了をCPUが監視し、変換結果を読み出してメモリへ書き込む処理が必要になります。単発のAD変換であれば大きな問題にはなりませんが、一定周期で連続的にサンプリングする場合や、複数の入力チャネルを扱う場合には、この処理が繰り返し発生します。その結果、CPUの処理負荷が増加し、他のアプリケーション処理に割り当てられる時間が少なくなる可能性があります。 この課題を解決する方法の一つが、DMA(Direct Memory Access)を用いたADC変換結果の転送です。DMAを使用すると、ADC変換の完了をきっかけに、ADCの変換結果をメモリへ自動的に転送できます。つまり、AD変換結果の取得からメモリへの格納までをハードウェアで処理できるため、CPUによるデータ転送処理を減らし、ソフトウェアの処理負荷を低減できます。 このような理由から、連続的なAD変換や高速なデータ取得が必要なアプリケーションでは、ADCとDMAを組み合わせた構成がよく利用されます。本記事では、まずADCの基本的な初期化方法を説明した後、MCX A153でDMAを使用してADC変換結果をメモリへ転送する方法を紹介します。 DMAを用いたAD変換値の転送 概要 AD変換後のデータはADCペリフェラル内のバッファに格納されます。都度、ソフトウェアで読み出さずに、ADCのトリガによりDMA を起動し、データを転送することがあります。1例として、AD変換を連続で5回おこなった後、DMAにてRAM上のバッファに保存し、コンソールに平均値と最小、最大を表示するプログラムに変更します。 DMAを用いたAD変換値の転送手順 ADCのサンプルコードを変更し、DMAの処理を追加していきます。 DMA起動は、ADCからのDMA Request信号を用います。 DMAを用いて、ADC FIFOの値(5回変換分)をRAMへコピーし、CPUへ割り込みを通知します。 CPUは、DMA転送完了後にmainループ内で平均値をとり、min, max, aveをコンソールに表示させます。     注意事項 DMAのコードを追加するにあたり、DMAドライバのヘッダファイルとソースコードをプロジェクトに追加してください。 一番簡単と思われる方法は、MCUXpresso IDEからDMAのサンプルコード(frdmmcxa153_edma3_memory_to_memory_transfer)を作成し、コピーする方法です。 driversディレクトリから、以下のファイルをコピーすればOKです。 fsl_edma_core.h fsl_edma_soc.c fsl_edma_soc.h fsl_edma.c fsl_edma.h   5.1  ADCに関するコードの修正と追加   コードの修正手順 ADC変換完了時の割り込みをディスエーブルに修正 ADCのコンフィグレーションを追加 AD変換を連続5回実行する設定 DMAリクエストをイネーブル設定 FIFOのWatermarkを4に設定 DMAが転送した値の平均、最小、最大値取得処理とコンソール出力を追加     1. ADC変換完了時の割り込みを無効 LPADC_EnableInterrupts()関数とkLPADC_FIFOWatermarkInterruptEnableを用いて、Interrupt Enable Register (IE)を有効にしているため、この行をコメントアウトします。 // LPADC_EnableInterrupts(DEMO_LPADC_BASE, kLPADC_FIFOWatermarkInterruptEnable);   2. ADCのコンフィグレーションを追加 ADCを5回ループ設定(=5回のAD変換) mLpadcCommandConfigStruct.loopCount = 4 //loopCount +1回の変換 DMAリクエストをイネーブルに設定 //178行目 LPADC_EnableFIFOWatermarkDMA(DEMO_LPADC_BASE, 1); // 1でDMA Requestがイネーブル     3. FIFOのWaterMarkの段数を4に設定 // 33行目 /* ++ ADCのマクロ */ #define FIFO0WatermarkLEVEL (4) //108行目 mLpadcConfigStruct.FIFOWatermark = FIFO0WatermarkLEVEL;   4. DMAが転送した値の平均、最小、最大値取得処理とコンソール出力を追加 uint32_t adc_values[5] = {0}; PRINTF("Please press any key to get user channel's ADC value.\r\n"); while(1) { GETCHAR(); EXAMPLE_DMA_BASEADDR->CH[0].CH_CSR = DMA_CH_CSR_ERQ(1); EXAMPLE_DMA_BASEADDR->CH[0].TCD_DLAST_SGA = -0x14; LPADC_DoSoftwareTrigger(DEMO_LPADC_BASE, 1U); /* 1U is trigger0 mask. */ while (!g_Transfer_Done) { /* DMA転送終了割り込み待ち */ } g_Transfer_Done = false; uint16_t min=adc_values[0]; uint16_t max=adc_values[0]; uint32_t sum=0; for(uint32_t i=0; i<5; i++) { if(max < (0x0000FFFF & adc_values[i])) max = adc_values[i]; if(min > (0x0000FFFF & adc_values[i])) min = adc_values[i]; sum += 0x0000FFFF & adc_values[i]; } PRINTF("ADC Min: %d, Max: %d, ave: %d\r\n", min, max, sum/5); for(size_t i=0; i<5; i++) { adc_values[i] = 0; } sum = 0; }   5.2 DMAに関するコードの追加   コードの追加方針 ヘッダファイルのインクルード DMA関連のマクロを追加 DMAのコンフィグレションと初期化 DMA転送のコンフィグレーション DMA転送完了割り込み処理   1. ヘッダのインクルード // 10行目 #include "fsl_debug_console.h" #include "pin_mux.h" #include "clock_config.h" #include "board.h" #include "fsl_lpadc.h" /* ++ */ #include "fsl_edma.h" // DMAドライバヘッダファイルの追加 #include "fsl_clock.h" #include "fsl_reset.h"   2. DMA関連のマクロを追加 // 32行目 #define EXAMPLE_DMA_BASEADDR DMA0 #define DEMO_DMA_CHANNEL_0 0U #define APP_DMA_IRQ DMA_CH0_IRQn #define APP_DMA_IRQ_HANDLER DMA_CH0_IRQHandler     3. DMAのコンフィグレーション // 197行目 edma_transfer_config_t transferConfig; edma_config_t userConfig; // 203行目 RESET_PeripheralReset(kDMA_RST_SHIFT_RSTn); /* Configure EDMA channel for one shot transfer */ EDMA_GetDefaultConfig(&userConfig); EDMA_Init(EXAMPLE_DMA_BASEADDR, &userConfig);     4. DMA転送のコンフィグレーション // 209行目 EDMA_PrepareTransfer(&transferConfig, (void *)0x400AF300, // eDMA transfer source address. sizeof(uint32_t), // eDMA transfer source address width(bytes) (void *)adc_values, // eDMA transfer destination address sizeof(&adc_values), // eDMA transfer destination address width(bytes) sizeof(adc_values), // eDMA transfer bytes per channel request sizeof(adc_values), // eDMA transfer bytes to be transferred kEDMA_PeripheralToMemory // eDMA transfer type ); EDMA_SetTransferConfig(EXAMPLE_DMA_BASEADDR, DEMO_DMA_CHANNEL_0, &transferConfig, NULL); EDMA_SetChannelMux(EXAMPLE_DMA_BASEADDR, DEMO_DMA_CHANNEL_0, kDma0RequestMuxAdc0FifoRequest); EnableIRQ(APP_DMA_IRQ); EDMA_EnableChannelInterrupts(EXAMPLE_DMA_BASEADDR, DEMO_DMA_CHANNEL_0, kEDMA_MajorInterruptEnable); ソフトウェアADCをソフトウェアトリガで起動する前に、DMAのチャネル0に割込みのトリガが掛るようにEDMA_TriggerChannelStart()を追加します。 DMAの割込みフラグをクリアした際、DMAトリガによる割込みがディスエーブルになるため、ADCのソフトウェアトリガの前に処理をついかします。 // 242行目 while(1) { GETCHAR(); EDMA_TriggerChannelStart(EXAMPLE_DMA_BASEADDR, DEMO_DMA_CHANNEL_0); EXAMPLE_DMA_BASEADDR->CH[0].TCD_DLAST_SGA = -0x14; LPADC_DoSoftwareTrigger(DEMO_LPADC_BASE, 1U); /* 1U is trigger0 mask. */ while (!g_Transfer_Done) { /* DMA転送終了割り込み待ち */ } g_Transfer_Done = false;   5. DMA転送完了割り込み処理 void APP_DMA_IRQ_HANDLER(void) { if ((EDMA_GetChannelStatusFlags(EXAMPLE_DMA_BASEADDR, DEMO_DMA_CHANNEL_0) & kEDMA_InterruptFlag) != 0U) { EDMA_ClearChannelStatusFlags(EXAMPLE_DMA_BASEADDR, DEMO_DMA_CHANNEL_0, kEDMA_InterruptFlag); g_Transfer_Done = true; } } まとめ: 本記事では、MCX A153 ADCの基本機能、注意点、vscode sdkのADCサンプルプロジェクトを使った初期化と変換処理を説明しました。そして、後半の記事従い、ADCサンプルを使った初期化・変換処理から、DMAによる変換結果の自動転送まで、実際の開発に役立つ設定例とコードの流れを確認できると思います。(まずはADC単体のサンプルを動かし、動作を確認してからDMAを追加すると、問題を切り分けやすくなります。) =========================​ 本投稿の「Comment」欄にコメントをいただいても、現在返信に対応しておりません。​ お手数をおかけしますが、お問い合わせの際には「NXPへの技術質問 - 問い合わせ方法 (日本語ブログ)」をご参照ください。​ (既に弊社NXP代理店、もしくはNXPとお付き合いのある方は、直接担当者へご質問いただいてもかまいません。)​ この記事では、MCX A153に搭載されているADC(アナログ信号をデジタル値に変換する回路)の基本から、MCUXpresso SDKを使った初期化、さらにDMAを使った変換結果の自動転送までを説明します。ADCやDMAを初めて使う場合は、まず1章と2章で全体像を確認し、その後に4章のサンプルコード、5章のDMA設定へ進むと理解しやすくなります。 ADC:センサなどのアナログ信号を、マイコンで扱えるデジタル値に変換する機能 DMA:CPUを介さずに、ペリフェラルとメモリの間でデータを転送する機能 SDK:ソフトウェア開発に必要なドライバやサンプルコードをまとめた開発キット (読了:30分) General Purpose Microcontrollers introduction MCUXpresso IDE MCUXpresso SDK 日本語ブログ
記事全体を表示
S32K312 BCTU – FIFO Watermark Callback Working, but Last Conversion Callback Not Triggered Hello NXP Community, I am working with the S32K312 MCU using S32 Design Studio and S32K3 RTD 7.0.1. I have configured the BCTU to trigger a list of ADC conversions using a software trigger. I am testing both the BCTU FIFO1 watermark callback and the BCTU last-conversion callback. Current Configuration: MCU: S32K312 Driver: S32K3 RTD 7.0.1 ADC instance: ADC0 BCTU conversion list: 4 ADC channels (0, 2, 4, 3) Trigger source: BCTU software trigger Interrupt: BCTU_IRQn enabled Notifications: FIFO1 watermark and last-conversion callbacks Observed Behavior: When I enable the FIFO1 watermark notification, the watermark callback is triggered successfully, and I can read the ADC conversion results from FIFO1. However, when I enable the BCTU last-conversion notification, the corresponding callback is not triggered. During debugging, I observed: Execution enters Bctu_0_Isr(). The driver checks the enabled BCTU interrupt sources. The condition if((*Reg & Mask) != 0U) evaluates to false for the last-conversion notification. The LIST0_Last bit in the BCTU MSR register remains 0 when inspected during interrupt handling. As a result, the last-conversion callback is not executed. Questions: Why does the FIFO1 watermark callback work correctly while the BCTU last-conversion callback is not triggered? What exact hardware condition causes MSR.LIST0_Last to become 1? Does the last-conversion interrupt require additional configuration in the BCTU conversion list, trigger configuration, or interrupt enable settings? Can both the FIFO1 watermark callback and the BCTU last-conversion callback be used for the same conversion list? Is the LIST0_Last status flag automatically cleared by hardware or by the RTD interrupt handler? If so, at what point? Which BCTU registers should I monitor to verify that the last-conversion event is generated correctly? Could you please help me understand why the FIFO watermark interrupt is functioning correctly while the BCTU last-conversion interrupt is not being generated or handled as expected? I can provide screenshots of my BCTU configuration, register values, and ISR debugging observations if required. Thank you for your support. #s32k312 #adcbctu #bctuswconv #listlastconv Re: S32K312 BCTU – FIFO Watermark Callback Working, but Last Conversion Callback Not Triggered Hi, if remember well, Last Conversion Notification can be generated only when the ADC conversion result destination is set to ADCnDR. The Reference Manual also states it in the LIST_IEN description.   BR, Petr  
記事全体を表示
Multicore Project setup of an additional MPU region I've been working on making a project that is essentially a combination of 2 SDK examples. I've been using the RT1170-EVKB SDK, version 26.09.00. The idea of the project is to take a multicore example and an LVGL example to have the M7 core run the graphics then communicate with the M4 core running the program. To do this I have taken the SDK examples: freertos_message_buffers (both primary and secondary) as my base project. I then slowly add in the graphics by copying and pasting the code and driver files from the lvgl_guider_cm7 project. I keep lvgl_guider_cm7 mcux_config.h file the same so that it does use PXP and VGLite. In order to do this, framebuffers need to placed in non-cache. The shared memory used in the SDK example also needs to be placed in non-cache. When this happens, I get artifacts on the display (little lines through objects that shouldn't be there). I can fix this by removing the __USE_SHMEM preprocessor, obviously this causes the multicore communication to fail. I believe it is because of the BOARD_EarlyConfigMPU function. Inside the function there is a section that goes like: #elif defined(__MCUXPRESSO) #if defined(__USE_SHMEM) extern uint32_t __base_rpmsg_sh_mem; extern uint32_t __top_rpmsg_sh_mem; uint32_t nonCacheStart = (uint32_t)(&__base_rpmsg_sh_mem); uint32_t size = (uint32_t)(&__top_rpmsg_sh_mem) - nonCacheStart; #else extern uint32_t __base_NCACHE_REGION; extern uint32_t __top_NCACHE_REGION; uint32_t nonCacheStart = (uint32_t)(&__base_NCACHE_REGION); uint32_t size = (uint32_t)(&__top_NCACHE_REGION) - nonCacheStart; #endif In this section it defines non-cache for either the shared memory or regular non-cache based on the __USE_SHMEM preprocessor. Further down in the function it declares the MPU region like so: volatile uint32_t i = 0; ... while ((size >> i) > 0x1U) { i++; } if (i != 0) { /* The MPU region size should be 2^N, 5<=N<=32, region base should be multiples of size. */ BOARD_EARLY_ASSERT(!(nonCacheStart % size)); BOARD_EARLY_ASSERT(size == (uint32_t)(1 << i)); BOARD_EARLY_ASSERT(i >= 5); /* Region 10 setting: Memory with Normal type, not shareable, non-cacheable */ MPU->RBAR = ARM_MPU_RBAR(BOARD_MPU_REGION_NONCACHE, nonCacheStart); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 0, 0, 0, 0, i - 1); } Now I want to be able to define both regions in the MPU to have both LVGL working without artifacts and the rpmsg message buffers be able to communicate. My memory regions can be found below: What I tried to do was modify the code above to perform both MPU region definitions, like so: #elif defined(__MCUXPRESSO) extern uint32_t __base_NCACHE_REGION; extern uint32_t __top_NCACHE_REGION; uint32_t nonCacheStart = (uint32_t)(&__base_NCACHE_REGION); uint32_t nonCacheSize = (uint32_t)(&__top_NCACHE_REGION) - nonCacheStart; #if defined(__USE_SHMEM) extern uint32_t __base_rpmsg_sh_mem; extern uint32_t __top_rpmsg_sh_mem; uint32_t rpmsgShmemStart = (uint32_t)(&__base_rpmsg_sh_mem); uint32_t rpmsgShmemSize = (uint32_t)(&__top_rpmsg_sh_mem) - rpmsgShmemStart; #endif This way the regular non-cache region is always defined and the shared memory region is only defined if used. I modified the MPU region definition like so: volatile uint32_t i = 0; ... while ((nonCacheSize >> i) > 0x1U) { i++; } if (i != 0) { /* The MPU region size should be 2^N, 5<=N<=32, region base should be multiples of size. */ BOARD_EARLY_ASSERT(!(nonCacheStart % nonCacheSize)); BOARD_EARLY_ASSERT(nonCacheSize == (uint32_t)(1 << i)); BOARD_EARLY_ASSERT(i >= 5); /* Region 10 setting: Memory with Normal type, not shareable, non-cacheable */ MPU->RBAR = ARM_MPU_RBAR(BOARD_MPU_REGION_NONCACHE, nonCacheStart); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 0, 0, 0, 0, i - 1); } #if (__USE_SHMEM) i = 0; while ((rpmsgShmemSize >> i) > 0x1U) { i++; } if (i != 0) { /* The MPU region size should be 2^N, 5<=N<=32, region base should be multiples of size. */ BOARD_EARLY_ASSERT(!(rpmsgShmemStart % rpmsgShmemSize)); BOARD_EARLY_ASSERT(rpmsgShmemSize == (uint32_t)(1 << i)); BOARD_EARLY_ASSERT(i >= 5); /* Region 16 setting: Memory with Normal type, not shareable, non-cacheable */ MPU->RBAR = ARM_MPU_RBAR(BOARD_MPU_REGION_SHMEM, rpmsgShmemStart); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 0, 0, 0, 0, i - 1); } #endif In doing this I created a macro for the additional MPU region inside board.h like so: #define BOARD_MPU_REGION_SHMEM (16) /* rpmsg shared memory */ Performing the modifications allowed LVGL to draw without artifacts but the multicore communication still fails. I put a breakpoint in the M4 thread running the multicore communication. Sometimes it'll trigger at the start, notifying that it received a message, but the message data is incorrect so it will not execute the code associated with the message's data. After a couple triggers of the breakpoint it will never trigger again. Is there anything I'm missing to be able to get this project running, the MPU region defines, etc...? Re: Multicore Project setup of an additional MPU region The changes were only applied to the primary core, as the primary core runs BOARD_EarlyConfigMPU and the secondary core runs BOARD_ConfigMPU, in the secondary core's function it already has the behaviour that I changed the primary core to have. Below are snippets from the what the secondary core runs on hardware init. #elif __CORTEX_M == 4 void BOARD_ConfigMPU(void) { #if defined(__CC_ARM) || defined(__ARMCC_VERSION) ... #elif defined(__MCUXPRESSO) extern uint32_t __base_NCACHE_REGION; extern uint32_t __top_NCACHE_REGION; uint32_t nonCacheStart = (uint32_t)(&__base_NCACHE_REGION); uint32_t nonCacheSize = (uint32_t)(&__top_NCACHE_REGION) - nonCacheStart; #elif defined(__ICCARM__) || defined(__GNUC__) ... #endif #if defined(__USE_SHMEM) #if defined(__CC_ARM) || defined(__ARMCC_VERSION) ... #elif defined(__MCUXPRESSO) extern uint32_t __base_rpmsg_sh_mem; extern uint32_t __top_rpmsg_sh_mem; uint32_t rpmsgShmemStart = (uint32_t)(&__base_rpmsg_sh_mem); uint32_t rpmsgShmemSize = (uint32_t)(&__top_rpmsg_sh_mem) - rpmsgShmemStart; #elif defined(__ICCARM__) || defined(__GNUC__) ... #endif #endif And then later in the function: uint32_t i = 0; /* Only config non-cacheable region on system bus */ assert(nonCacheStart >= 0x20000000); ... while ((nonCacheSize >> i) > 0x1U) { i++; } if (i != 0) { /* The MPU region size should be 2^N, 5<=N<=32, region base should be multiples of size. */ assert(!(nonCacheStart % nonCacheSize)); assert(nonCacheSize == (uint32_t)(1 << i)); assert(i >= 5); /* Region 0 setting: Memory with device type, not shareable, non-cacheable */ MPU->RBAR = ARM_MPU_RBAR(BOARD_MPU_REGION_NONCACHE, nonCacheStart); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, i - 1); } #if defined(__USE_SHMEM) i = 0; while ((rpmsgShmemSize >> i) > 0x1U) { i++; } if (i != 0) { /* The MPU region size should be 2^N, 5<=N<=32, region base should be multiples of size. */ assert(!(rpmsgShmemStart % rpmsgShmemSize)); assert(rpmsgShmemSize == (uint32_t)(1 << i)); assert(i >= 5); /* Region 1 setting: Memory with device type, not shareable, non-cacheable */ MPU->RBAR = ARM_MPU_RBAR(BOARD_MPU_REGION_RPMSG_SHMEM, rpmsgShmemStart); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, i - 1); } #endif Both projects have __USE_SHMEM defined in the preprocessor. Below is the memory config for the secondary core: Am I missing something else, or perhaps are my modifications wrong? Do I need to add something extra to the "Manage Linker Script" section of the primary project's settings? When I get the chance I'll upload a .zip of the projects that run on the EVK-B board so that you may see/replicate the issue. Re: Multicore Project setup of an additional MPU region Hi @CMoran, Your understanding makes sense, but it wasn't clear if that changed you mention were applied to both CM7 and CM4 cores. Each core has a definition of board.h, where they use their respective configuration of the MPU to setup during the initial hardware initialization. If the changes you mention were only made for the primary core, it's likely that the cores don't treat the memory regions equally, resulting in these unexpected behaviors. Please verify that the changes are applied to both cores to ensure they coincide on MPU setup, as well as ensuring that __USE_SHMEM was setup for both project's preprocessor definitions. Re: Multicore Project setup of an additional MPU region Here's the .zip with the m7 and m4 projects within. I've left it to be before my modifications, as the modifications didn't work anyway. In this example if you open a terminal and push the button in the center, both the m7 and m4 cores will print a message. The settings icon moving around the screen has a bunch of artifacts in it as described. Removing the __USE_SHMEM preprocessor from the m7 project will fix the artifacts in the settings icon, but the multicore communication will fail. Adding the modifications I've applied above will also fix the settings icon, but the multicore communication will fail. Screen used in this demo is the RK055HDMIPI4MA0. Re: Multicore Project setup of an additional MPU region Hi @CMoran, Got it. Going back on your first reply though: You mentioned that you created a new definition for a memory region: #define BOARD_MPU_REGION_SHMEM (16) /* rpmsg shared memory */ But the definition of ARM_MPU_RBAR() uses MPU_RBAR_REGION_Msk, which is defined as 15: #define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/)  The CM7 defines the number of regions as 16, numbered 0-15. Therefore, you are actually setting region 0 by doing so. Re: Multicore Project setup of an additional MPU region Unfortunately before creating the new memory region definition: #define BOARD_MPU_REGION_SHMEM (16) /* rpmsg shared memory */ I was just reusing the predefined memory region for non-cache: #define BOARD_MPU_REGION_NONCACHE (10) /* Noncacheable space in application */ And I had the same result. I've changed my new memory region definition to be 10 now to match the non-cache. With no luck on the cores being able to communicate. I've checked the start location and the size of the rpmsg shared memory on both cores with breakpoints, both have the correct start (0x20340000) and size (0x10000). I've changed the 4th parameter of the ARM_MPU_RASR() function on both cores to 1 to indicate that the region is "shareable". No luck there still. When you or a member of the team gets a chance, I posted my project's code in another reply. I'm running out of ideas of what to try. Re: Multicore Project setup of an additional MPU region Hi again @CMoran, After building your project and analyzing the memory regions on the resulting .ld files, I see that the regions where the LVGL framebuffers and the multicore message buffers are located at separate memory regions in a way that can't be merged as they are non-contiguous physical memories: NCACHE_REGION at 0x81000000 (16 MB, in SDRAM) for the LVGL framebuffers rpmsg_sh_mem at 0x20340000 (64 KB, in OCRAM) for the multicore message buffers That said, MPU region 7 currently covers 0x20300000–0x2037FFFF (512 KB) as cacheable Normal memory, a range that includes the rpmsg_sh_mem region, which could mean that the shared memory ends up being cacheable, resulting in the inter-core communication errors that you are seeing. Reducing the size of Region 7 to ensure rpmsg_sh_mem falls through to region 3, which is already non-cacheable might be a straightforward fix to ensure the proper functionality of the message buffers, without MPU driver level changes on the existing drivers. Re: Multicore Project setup of an additional MPU region Hi @EdwinHz  I've taken a second to test your suggestion. I changed the MPU Region 7 (OCRAM2) to be 256 KB instead of 512 KB like so: /* Region 7 setting: Memory with Normal type, not shareable, outer/inner write back */ MPU->RBAR = ARM_MPU_RBAR(BOARD_MPU_REGION_OCRAM_B, 0x20300000U); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_256KB); After I removed the __USE_SHMEM preprocessor as the rpmsg_sh_mem will fall through to MPU Region 3, which is already defined as non-cacheable. The demo I created is now working as intended.
記事全体を表示
RW612: 同時デュアルPHY(1M + コード化)スキャン中にLEコード化PHYが深刻な飢餓状態に陥る こんにちは、NXPコミュニティの皆さん、 私たちは RW612上で、#SDKs 26.09のもとでコントローラファームウェア18.99.8.p141のASTM F3411リモートIDレシーバを開発しています。デュアルPHYスキャンが有効な場合、LEコードPHYに深刻なコントローラ側の飢餓問題が発生していることを特定しました。 同時に1Mと符号スキャンをコントローラに委任(60ms間隔で15%1M、85%符号化作業)すると、符号化PHY受信率は7%に崩壊し、Wi-Fi TX/RXが同時接続しているフルシステム負荷時には5%に低下します。 アイソレーションテストの結果、この問題はコントローラのスキャンパラメータに両方のPHYを組み合わせたことで厳密に引き起こされることが示されました。 ソロコード化スキャン(85%デューティ、ウィンドウ処理):受信率98% (47/48パケット) 。 デュアルPHYスキャン(1M 15% + コード化85%):受信率7% (29/391パケット) 。 ホストの逐次タイムスライシング(符号化2000ms/1Mあたり300ms): 単独で符号受信を 98% まで回復し、完全な並行性(2パック/秒の生Wi-Fi注入、Wi-Fiモニター、ローカルBT4/BT5広告)では 54% を維持し、基準値の5%から増加します。 ホストのバッファとキューは完全に正常な状態を維持しており、データ損失や破損は一切発生していません。この問題は、マルチPHYスキャンパラメータを処理する際のCPU2無線ファームウェアスケジューラに限定されています。 これはCPU2コントローラのファームウェア(rw61x_sb_ble_a2.bin)の既知のスケジューリングバグでしょうか? ホスト管理型のシーケンシャルシングルPHYタイムスライシングは、RW612上で1M PHYとCoded PHYの両方を監視するための公式に推奨されている回避策ですか? 製品: WiFi RW6XX プロトコル:Bluetooth Re: RW612: Severe LE Coded PHY Starvation During Concurrent Dual-PHY (1M + Coded) Scanning こんにちは@ecg3 Dual-PHYスキャンの設定やテストステップを教えていただけますか?また、レビューのためにhciログとOTAログを共有してください。 よろしくお願いいたします。 ショーン Re: RW612: Severe LE Coded PHY Starvation During Concurrent Dual-PHY (1M + Coded) Scanning こんにちは、 @shaun_wu さん。 ご連絡ありがとうございます。私はRW612(MCUXpresso SDKs 26.09、EdgeFastオープンホスト、FW 18。99.8。p141、アイドルWi-Fi)を、1メートル離れた広告主に対してLEコードの拡張広告(ASTM F3411リモートID、500ms間隔、8ビットペイロードカウンターで追跡)とnRF52840のOTAスニッファーを同時にテストしました。 私はデュアルPHYスキャン(Scanning_PHYs 0x05、60ms間隔、8。75ms、1Mのウィンドウ、50ms。6msの符号付きウィンドウ)と、符号のみの参照スキャン(Scanning_PHYs 0x04、同一の50ms。6ms符号化ウィンドウ)を比較しました。 符号化のみのスキャンはオンエアパケットの94%(112パケット中105パケット)を正常に受信しましたが、デュアルPHYを有効にすると符号受信は急激に13%に低下しました(報告されたパケットは94パケット中12パケットのみ)。RW612コントローラは通常通りレガシー1Mパケットを報告し続け、配布された数少ない符号化パケットは完全に無傷(データステータス0)で、欠損パケットはコントローラによって単純にドロップまたはスキップされたことを示しています。 両方の実行の完全なログ(生のUART、パケット損失のないHCI_Resetからの完全なHCI btsnoop 、および同期されたOTA pcapngキャプチャ)を添付しました。RW612とPCのクロックにはわずかなオフセット(約0.4~0.9秒)があるため、タイムスタンプではなくペイロードカウンタを使用してHCIとスニファのトレースを相関させてください(たとえば、デュアルPHYキャプチャでは、 btsnoopフレーム531がカウンタ157のスニファフレーム2998と一致します。BDアドレス58:ce:2a:6b:d5:8bでフィルタリングすると、両方のストリームが分離されます)。 よろしくお願いいたします。
記事全体を表示
PN7642EV/C100とPN7642EV/C102の比較 最初の質問です。新しいデザインでPN7642EV/C102を使う予定です。PN7642EV/C100は主流の代理店に在庫があるので代替部品として追加したいと考えており、長期的なサプライチェーンの問題を軽減したいと考えています。これらのPNの違いは出荷時のFWバージョンだけのように見えます。もしそうなら、PN7642EV/C100を入力して最新のFWに更新することは、PN7642EV/C102で同じことをするのと同じことになります。この推測は正しいでしょうか? 2つ目の質問ですが、このアプリケーションでは基本的なNFCタグ、Google Wallet、Apple Walletを読みます。GoogleウォレットやAppleウォレットを読み取るには多くの認証や許可が必要なことは理解していますが、ハードウェアの観点から見て、C100およびC102のバリアントはこれに対応できるのでしょうか? Re: PN7642EV/C100 vs PN7642EV/C102 こんにちは、 @adamdoyle15 あなたの調子が良いといいのですが。 PN7642はECPに対応しているはずです。また、ご指摘のとおり、これらのバリアントの主な違いは、C102は出荷時にファームウェアv3.00が搭載されている点です。 よろしくお願いいたします。 エドゥアルド。 Re: PN7642EV/C100 vs PN7642EV/C102 こんにちは、 ECPサポートは主にソフトウェアで行われており、ハードウェアのバリアント間で区別はないはずです。 よろしくお願いいたします。 エドゥアルド。 Re: PN7642EV/C100 vs PN7642EV/C102 迅速なご対応ありがとうございます。 ECP機能については、データシートを見る限りPN7642はECP対応であることがわかりますが、ハードウェアの観点からこれでApple Walletとの互換性が十分かどうかが疑問です。
記事全体を表示
PN7642EV/C100 与 PN7642EV/C102 第一个问题,我计划在新设计中使用PN7642EV/C102。我想添加PN7642EV/C100作为备选方案,因为它在主流代理商处有现货,可以减少潜在的长期供应链问题。在我看来,这两个PN7642EV/C100之间的唯一区别在于它们出厂时预装的固件版本。如果真是这样,那么安装PN7642EV/C100并更新到最新固件就相当于安装PN7642EV/C102并更新到最新固件。我的理解是否正确? 第二个问题,对于此应用,我们将读取基本的 NFC 标签、Google 钱包和 Apple 钱包。我知道读取 Google 和 Apple 钱包需要很多认证和权限,但就硬件而言,C100 和 C102 型号是否能够做到这一点? Re: PN7642EV/C100 vs PN7642EV/C102 你好@adamdoyle15 希望你一切都好。 PN7642 应具备 ECP 功能。另外,正如您所提到的,这些版本之间的主要区别在于C102出厂时预装了固件版本3.00。 问候, 爱德华多。 Re: PN7642EV/C100 vs PN7642EV/C102 您好, ECP 支持主要通过软件实现;硬件版本之间不应有区别。 问候, 爱德华多。 Re: PN7642EV/C100 vs PN7642EV/C102 感谢您的快速回复。 关于 ECP 功能,我从数据表中看到 PN7642 具备 ECP 功能,但我的问题是,从硬件角度来看,这是否足以兼容苹果钱包。
記事全体を表示
Code Warrior バージョン 8 Palm 開発ツール (Metrowerks製) 私が持っている古いCode Warriorバージョン8(metrowerks製)の開発ツールを有効活用できる方はいらっしゃいますか?Windows版とMac版の両方に、対応するマニュアルが付属しています。Palmデバイス本体と、他にも数冊のPalm開発関連の書籍を保管しています。良いホームを見つける必要があります。 Re: Code Warrior ver 8 Palm dev tools by metrowerks CodeWarriorへの関心ありがとうございます。古いバージョンを見つけたり共有したりすることは可能ですが、CodeWarrior 8はレガシー製品であり、現在はサポートされていません。過去のバージョンのページやコンテンツは歴史的な参照のみで提供されており、v11.1以前のCodeWarriorバージョンのサポートは非常に限定的です。ご迷惑をおかけして申し訳ございません。 現在メンテナンスされているバージョンはCodeWarrior v11.1で、幅広い8ビットデバイスをサポートし、Windows 10/11で動作します。 今後はv11.1の使用を推奨します。こちらからダウンロードできます: CodeWarrior for MCUS (Eclipse IDE) v11.1 よろしくお願いいたします。 Re: Code Warrior ver 8 Palm dev tools by metrowerks   ルイス様、 ご回答ありがとうございます。 私はラファエレ・マッツァレッリ、イタリアのインダストリアル電子機器修理、特に太陽光インバーターを専門とする企業AQSの技術修理部門マネージャーです。 現在、2つのデジタル・シグナル・プロセッサを含むサンテルノES821制御基板に影響する技術的問題を調査しています。 モトローラ/フリースケールDSP56F807PY80E テキサス・インスツルメンツTMS320VC33PGE 主な問題は、ボードのライフタイムオペレーティングタイマーに関するもので、このタイマーは運転時間情報を正しく保持していません。 この問題の診断にはすでにかなりの時間とリソースを投じており、ハードウェア調査、メモリ解析、両プロセッサを対象としたテストも行っています。 残念ながら、ライフタイムタイマーがMotorola DSP56F807、Texas Instruments TMS320VC33、あるいは両プロセッサ間の連携によるものかはまだ判明していません。 特に以下の技術サポートをご希望です: DSP56F807の内部非揮発性記憶組織。 ファームウェアや動作パラメータへのアクセスと解析の可能性。 DSC 8.3 用の CodeWarrior Development Studio および互換性のあるデバッグツールが利用可能であること。 Motorolaプロセッサがライフタイムタイマーの保存や管理を担当しているかどうかを判断するのに役立つ技術情報があれば教えてください。 また、NXPや有資格の技術パートナーがこのサービスを提供できるなら、ES821制御基板を物理的に技術検査のために送付することも承知していることを強調したいと思います。 もし役立つなら、故障した基板と比較するために完全に稼働する基板の提供についても検討できます。 検査手順および関連費用に関する事前合意を条件として、認定された技術施設への発送を手配いたします。 私たちの目標は、この繰り返し発生する問題の根本原因を特定し、現在も稼働中のインダストリアル機器に対して信頼できる修理ソリューションを開発することです。 NXPには専門の技術部門、または認可されたパートナーがいるかどうか教えていただけますか? 皆さまのサポートを大変ありがたいです。 よろしくお願いします、 ラファエレ・マッツァレッリ 技術修理部門マネージャー AQS – イタリア
記事全体を表示
[OSM-iMX937/952] Schematic review For our new project, the iMX937 and iMX952 will be using a shared board design Could you help to review iMX937 and iMX952 schematic? Please refer to the attached file. The following questions would like to be confirmed with NXP: (1) According to the EVK and checklist descriptions, C604 and C603 in the circuit exist for the NXP iMX95. Therefore, can they be directly removed in this project? (2) To reduce component count, the additional ADC VREF and VDD_DDR capacitors on page 4 of the circuit were directly removed. According to the documentation, these designs exist for the NXP iMX95, not the iMX937/952. Thanks. Re: [OSM-iMX937/952] Schematic review iMx937 and iMx952 are pretty new product since both of them is at preproduction phase. Please contact dedicated FAE for detailed datasheet and user manual Q1 : All platforms that have transmitters supporting 8.0 GT/s must implement the 176 nf to 265 nF CTX value. Platforms operating at 2.5 or 5.0 GT/s only may increase that range to 75 nf to 265 nF. For pull down capacitor, no comments since it may not be necessary I.mX937 === 1 x PCIe Gen 3.0 x1 Lane(2.5G mux) I.mX952 === 1x PCIe Gen 3.0 x1 lane (1G SGMII mux) i.mX95 === 2x PCIe Gen 3.0 x1 Q2: There are some capacitor on page5 for DDR already. Not sure it is duplicated on page4. LPDDR5 design guideline may be request from memory vendor for more detailed information due to PI consideration For VREFH_ADC0, 1 0.01 µf+0.1 µf could be a possible option but may not be deleted due to noise filter
記事全体を表示
SR150の立ち上がり時間と立ち下がり時間の要件 こんにちは、チームの皆さん、 私たちはSR150ベースの村田UWBモジュールLBUA0VG2BP-741とSTM32N657 MCUを設計に使用しています。MCU側からは最高ドライブ強度(「Very High Speed」)を設定しています。クロック信号とデータ信号の立ち上がり時間と立ち下がり時間よりも短い時間で動作しています。 時計の場合(20%~80%) 要求仕様:立ち上がり時間:2.15ns、立ち下がり時間:2ns 以下のように取得しています 1. 立ち上がり時間:3.584ns 2. 落下時間:4.937ナノ秒 データの場合(20%~80%) 要求仕様:立ち上がり時間:0.6ns、立ち下がり時間:0.55ns 以下のように取得しています 1. 立ち上がり時間:3.509ns 2. 落下時間:4.38ナノ秒 UWBモジュールのクロックピンとデータピンを設定して、必要な立ち上がり時間と立ち下がり時間を実現する方法はありますか? この上昇と下降のタイミングがコミュニケーションに影響を与えるかどうか、ご案内いただけますか? 参考のために波形を添付しました。 迅速なご対応に大変感謝いたします。 よろしくお願いします。 Re: Rise time and Fall time requirement for SR150 SR150 GPIOのプルアップ/プルダウン状態は製造段階で設定されます。 SR150の場合、デフォルト設定はOTPメモリに書き込まれます。オーバーライド状態が可能 ファームウェアによって。これは、SR150にファームウェアがロードされている場合にのみ利用可能です。詳細については、専任のFAEにお問い合わせする必要があるかもしれません Re: Rise time and Fall time requirement for SR150 こんにちは、チームの皆さん、 いいえ。私たちの設計では、MCUがSPIマスターとしてSPIクロックを生成し、SR150はSPIスレーブとして動作します。SR150がスレーブデバイスとして動作している際に、タイミングの問題でSPIデータのサンプリングが正しく行われない可能性はあるのかどうかを知りたいです。 また、SR150のピンを内部プルアップなどの設定で構成することは可能でしょうか?   よろしくお願いします。 Re: Rise time and Fall time requirement for SR150 SR150は最大16.66 Mbits/sのSPI-バス・マスタ/スレーブインターフェースをサポートしています クロック速度制御とは、SR150を使ってSPIバスのクロックを制御するという意味でしょうか? Re: Rise time and Fall time requirement for SR150 こんにちは、 あなたの調子が良いといいのですが。ご不便をおかけして申し訳ありませんが、これらの製品の情報はNDA(秘密保持契約)に基づいており、公開されていません。 ご不便をおかけして申し訳ありませんが、ご質問はトリ メンションのUWBパートナーからのモジュール/キットに関するものなので、サポートを受けるには直接その会社に相談する必要があります。 すべてのサポートはUWBパートナー、今回は村田氏から直接提供すべきです。 ドキュメントとソフトウェアは、対応するUWBモジュール・パートナーから配布されています。 モジュールを選択すると、パートナーのページに移動し、データシート、アプリケーション・ノート、必要なソフトウェアにアクセスできます。 ご迷惑をおかけして、重ねてお詫び申し上げます。 よろしくお願いいたします。 リカルド Re: Rise time and Fall time requirement for SR150 こんにちは、チームの皆さん、 SR150がスレーブデバイスとして動作している際に、タイミングの問題でSPIデータのサンプリングが正しく行われない可能性はあるのかどうかを知りたいです。 よろしくお願いします。
記事全体を表示
Code Warrior ver 8 Palm dev tools by metrowerks Does anyone have a good use for my old Code Warrior ver 8 dev tools by metrowerks? Both the Windows and Mac hosted with matching manual. Also have some other 3rd Palm development books in storage along with a Palm device. They need find a good home. Re: Code Warrior ver 8 Palm dev tools by metrowerks Thank you for the interest in CodeWarrior, while it may be possible to find or share older versions of CodeWarrior, CodeWarrior 8 is a legacy product that is no longer supported. The pages and content for previous versions have been kept available for historical reference only, so support for any CodeWarrior version prior to v11.1 is very limited. We apologize for any inconvenience this may cause. The currently maintained version is CodeWarrior v11.1, which supports a wide range of 8-bit devices and runs on Windows 10/11. We recommend using v11.1 going forward, You can download it here: CodeWarrior for MCUs (Eclipse IDE) v11.1 Best Regards Re: Code Warrior ver 8 Palm dev tools by metrowerks   Dear Luis, Thank you for your response. I am Raffaele Mazzarelli, Technical Repair Division Manager at AQS, an Italian company specializing in industrial electronics repair, particularly photovoltaic inverters. We are currently investigating a technical problem affecting the Santerno ES821 control board, which contains two digital signal processors: Motorola/Freescale DSP56F807PY80E Texas Instruments TMS320VC33PGE The main issue concerns the board’s lifetime operating timer, which does not retain its operating-time information correctly. We have already invested considerable time and resources in diagnosing this problem, including hardware investigations, memory analysis and tests involving both processors. Unfortunately, we have not yet determined whether the lifetime timer is managed by the Motorola DSP56F807, the Texas Instruments TMS320VC33, or through interaction between the two processors. We are particularly interested in obtaining technical support regarding: The internal non-volatile memory organization of the DSP56F807. The possibility of accessing and analyzing its firmware and stored operating parameters. The availability of CodeWarrior Development Studio for DSC 8.3 and compatible debugging tools. Any technical information that could help determine whether the Motorola processor is responsible for storing or managing the lifetime timer. I would also like to emphasize that we are willing to physically send an ES821 control board for technical examination, if NXP or a qualified technical partner can provide this service. If useful, we could also discuss providing a fully operational board for comparison with the faulty one. We would be happy to arrange shipment to an authorized technical facility, subject to prior agreement regarding the examination procedure and any associated costs. Our objective is to identify the root cause of this recurring problem and develop a reliable repair solution for industrial equipment that is still in service. Could you please advise whether NXP has a specialist, technical department or authorized partner who might be able to assist us? We would greatly appreciate your support. Best regards, Raffaele Mazzarelli Technical Repair Division Manager AQS – Italy
記事全体を表示
S32 Design Studio バージョン v.3.5 ライセンス こんにちは、NXPサポートチームです。 私のS32 Design Studioバージョンv.3.5のライセンスは2026年10月19日に期限切れになります。ライセンスの延長にご協力いただけますでしょうか? アクティベーションコード:30E0-0F7D-F883-9AFB ご支援ありがとうございます。
記事全体を表示
[OSM-iMX937/952] 回路図レビュー 新しいプロジェクトでは、iMX937とiMX952が共有ボード設計を採用します iMX937とiMX952の回路図の確認を手伝ってもらえますか? 添付ファイルをご参照ください。 以下の点についてNXPに確認を取りたい。 (1)EVKおよびチェックリストの説明によれば、NXP iMX95の回路にはC604およびC603が存在する。したがって、CAN、このプロジェクトで直接取り除くことは可能でしょうか? (2)部品点数を減らすため、回路図の4ページにある追加のADC VREFおよびVDD_DDRコンデンサを直接削除しました。ドキュメントによると、これらのデザインはNXP iMX95向けに存在し、iMX937/952には適用されていません。 ありがとう。 Re: [OSM-iMX937/952] Schematic review iMx937とiMx952はどちらもプリプロダクション段階なので比較的新しい製品です。詳細なデータシートおよびユーザーマニュアルについては、専属のFAEにお問い合わせください Q1:8.0 GT/s対応のトランスミッタを持つすべてのプラットフォームは、176 nfから265 nFのCTX値を実装しなければなりません。運行中のプラットフォーム 2.5または5.0 GT/sのみで、航続距離は75 nfから265 nFに増加する可能性があります。プルダウンコンデンサについては、必要ない可能性があるため、コメントは不要です。 I.mX937 === 1 x PCIe Gen 3.0 x1レーン(2.5G多重化) I.mX952 === 1x PCIe Gen 3.0 x1レーン (1G SGMIIマルチプレクサ) i.mX95 === 2x PCIe Gen 3.0 x1 Q2: DDR用のコンデンサはすでに5ページに載っています。4ページ目に重複して掲載されているかどうかは不明です。LPDDR5デザインガイドラインは、PIを考慮してメモリベンダーからより詳細な情報を求める場合があります VREFH_ADC0では、1 0.01 μf+0.1 μfのオプションが考えられますが、ノイズフィルターの関係で削除はできない場合があります
記事全体を表示
S32 Design Studio version v.3.5许可证 您好,NXP支持团队, 我的S32 Design Studio version v.3.5许可证已于2026年10月19日到期。请问您能否帮忙延长许可证期限? 激活码:30E0-0F7D-F883-9AFB 感谢您的支持。
記事全体を表示
SR150的上升时间和下降时间要求 各位同事好, 我们的设计中使用了基于 SR150 的 Murata UWB 模块 LBUA0VG2BP-741 和 STM32N657 MCU。我们从MCU端设置了最高的驱动强度(“非常高速”)。我们低于时钟信号和数据信号的上升时间和下降时间。 时钟(20% 至 80%) 根据要求,上升时间为 2.15ns,下降时间为 2ns。 我们得到的结果如下。 1. 上升时间:3.584纳秒 2. 下降时间:4.937ns 数据(20% 至 80%) 根据要求,上升时间为 0.6ns,下降时间为 0.55ns。 我们得到的结果如下。 1. 上升时间:3.509纳秒 2. 下落时间:4.38纳秒  是否有办法配置UWB模块的时钟和数据引脚,以实现所需的上升时间和下降时间? 请问这种上升时间和下降时间是否会影响通信? 我附上了波形图供您参考。 非常感谢您的快速回复。 谢谢! Re: Rise time and Fall time requirement for SR150 SR150 GPIO 的上拉/下拉状态是在制造阶段配置的。 SR150 的默认设置写入 OTP 内存。可以覆盖状态 通过固件。仅当 SR150 加载固件后才可用。您可能需要联系专用的现场应用工程师 (FAE) 获取详细信息。 Re: Rise time and Fall time requirement for SR150 各位同事好, 不。在我们的设计中,MCU 是 SPI 主设备并生成 SPI 时钟,而 SR150 则作为 SPI 从设备运行。我们想了解SR150作为从设备运行时,是否存在因时序问题而错误采样SPI数据的可能性。 另外,SR150引脚是否可以配置为内部上拉?   谢谢。 Re: Rise time and Fall time requirement for SR150 SR150 支持 SPI 总线主/从接口,最高传输速率可达 16.66 Mbits/s。 您说的时钟速度控制是指用 SR150 控制 SPI 总线时钟吗? Re: Rise time and Fall time requirement for SR150 各位同事好, 我们想了解SR150作为从设备运行时,是否存在因时序问题而错误采样SPI数据的可能性。 谢谢! Re: Rise time and Fall time requirement for SR150 你好, 希望你一切都好。很抱歉给您带来不便,但由于这些产品的信息受保密协议(NDA)约束,因此这些信息不对外公开。 很抱歉给您带来不便,但由于您的问题涉及我们Trimension UWB 合作伙伴的某个模块/套件,您需要直接与他们联系才能获得该模块/套件的支持。 所有支持都应直接来自 UWB 合作伙伴,在本例中即来自 Murata。 文档和软件由相应的UWB模块合作伙伴分发。 选择模块,您将被引导至我们合作伙伴的页面,您可以在其中访问数据手册、应用笔记和所需的使能软件。 再次为给您带来的不便表示歉意。 顺祝商祺! 里卡多
記事全体を表示
Code Warrior ver 8 Palm 开发工具,作者 metrowerks 有人觉得我那套老旧的 Metrowerks 出品的 Code Warrior 8 开发工具还有用吗?Windows 和 Mac 系统均配有相应的用户手册。此外,我还收藏了一些其他第三版 Palm 开发书籍以及一台 Palm 设备。他们需要找到一个好归宿。 Re: Code Warrior ver 8 Palm dev tools by metrowerks 感谢您对 CodeWarrior 的关注,虽然可能可以找到或分享旧版本的 CodeWarrior,但 CodeWarrior 8 是一个不再受支持的旧版产品。先前版本的页面和内容仅供历史参考,因此对 v11.1 之前的任何 CodeWarrior 版本的支持都非常有限。由此造成的不便,我们深表歉意。 目前维护的版本是 CodeWarrior v11.1,它支持各种 8 位设备,并且可以在 Windows 10/11 上运行。 我们建议您使用 v11.1 版本,您可以从这里下载: CodeWarrior for MCUs (Eclipse IDE) v11.1 顺祝商祺! Re: Code Warrior ver 8 Palm dev tools by metrowerks   亲爱的路易斯, 感谢您的回复。 我是 Raffaele Mazzarelli,AQS 公司技术维修部门经理。AQS 是一家意大利公司,专门从事工业电子产品维修,特别是光伏逆变器维修。 我们目前正在调查影响 Santerno ES821 控制板的技术问题,该控制板包含两个数字信号处理器: 摩托罗拉/飞思卡尔 DSP56F807PY80E 德州仪器 TMS320VC33PGE 主要问题在于板的寿命运行计时器,它无法正确保存运行时间信息。 我们已经投入了大量时间和资源来诊断这个问题,包括硬件调查、内存分析以及涉及两个处理器的测试。 遗憾的是,我们尚未确定生命周期定时器是由摩托罗拉 DSP56F807、德州仪器 TMS320VC33 管理,还是通过这两个处理器之间的交互管理。 我们尤其希望获得以下方面的技术支持: DSP56F807 的内部非易失性存储器组织结构。 能够访问和分析其固件和存储的运行参数。 CodeWarrior Development Studio for DSC 8.3 及兼容的调试工具的可用性。 任何有助于确定摩托罗拉处理器是否负责存储或管理生命周期计时器的技术信息。 我还要强调,如果恩智浦半导体或合格的技术合作伙伴能够提供这项服务,我们愿意将 ES821 控制板实物寄送进行技术检验。 如果需要,我们还可以讨论提供一个功能齐全的板,以便与故障电路板进行比较。 我们很乐意安排将货物运送至经授权的技术机构,但需事先就检验程序和相关费用达成一致。 我们的目标是找出这一反复出现问题的根本原因,并为仍在服役的工业设备开发可靠的维修方案。 请问NXP是否有专家、技术部门或授权合作伙伴可以帮助我们? 我们非常感谢您的支持。 此致, 拉斐尔·马扎雷利 技术维修部经理 AQS – 意大利
記事全体を表示
Rise time and Fall time requirement for SR150 Hello Team, We are using SR150 based Murata UWB module LBUA0VG2BP-741 with STM32N657 MCU in our design. We have set highest drive strength ("Very High Speed") from MCU side. We are below rise time and fall time with clock and data signals. For Clock (20% to 80%) As per requirement rise time : 2.15ns and fall time : 2ns We are getting as per below  1. Rise time : 3.584ns  2. fall time : 4.937ns For Data  (20% to 80%) As per requirement rise time : 0.6ns and fall time : 0.55ns We are getting as per below  1. Rise time : 3.509ns  2. fall time : 4.38ns  Is there any way to configure UWB module clock and data pins to achieve the required rise time and fall time?  Could you please guide us if this rise time and fall time will impact communication or not? I have attached waveform for reference. Your quick response is highly appreciated. Thanks Re: Rise time and Fall time requirement for SR150 The SR150 GPIOs pullup/pulldown state are configured during the manufacturing phase of SR150, the defaults setting are written in OTP memory. An override state is possible by the firmware. Which only available when firmware is loaded in SR150. You may need to contact with dedicated FAE for detailed information Re: Rise time and Fall time requirement for SR150 Hello Team, No. In our design, the MCU is the SPI master and generates the SPI clock, while the SR150 operates as the SPI slave. We would like to understand whether there is any possibility of the SR150 incorrectly sampling SPI data due to timing, while operating as a slave device.  Also, is there any possibility to configure SR150 pins such as internal pull up?   Thanks.  Re: Rise time and Fall time requirement for SR150 The SR150 supports SPI-bus Master/Slave interface, up to 16.66 Mbits/s For clock speed control, do you mean control the SPI bus clock with SR150? Re: Rise time and Fall time requirement for SR150 Hello Team, We would like to understand whether there is any possibility of the SR150 incorrectly sampling SPI data due to timing, while operating as a slave device.  Thanks Re: Rise time and Fall time requirement for SR150 Hello, Hope you are doing well. Sorry for the inconvenience this might cause you but as the information of these products it's under NDA (Non-Disclosure Agreement) the information it's not public. I apologize for the inconveniences, but as your question is about a Module/Kit from one of our Trimension UWB Partners, you would need to go directly with them to receive support for their Module/Kit. All the support should come directly from the UWB Partner, in this case from Murata. The documentation and software is distributed by the corresponding UWB Module partner. By selecting a module, you will be guided to our partner’s page where you can access datasheets, application notes, and the required enablement software.   I apologize again for the inconveniences. Best Regards, Ricardo
記事全体を表示