Zephyrのnxp_hpdacドライバをMCXN947ベースのボード用にZephyr 4.3にバックポートしています。
アップストリームドライバーはデバイスinitコールバックを使用しません。しかし、Zephyr 4.3では、ペリフェラルを使う前にDAC2クロック、SPCアナログモジュールを明示的に初期化し、リセットしないとHPDACが正しく動作しません。
以下の手順を実行するnxp_hpdac_init()関数を追加しました。
CLOCK_SetClkDiv(kCLOCK_DivDac2Clk, 1U)
CLOCK_AttachClk(kFRO_HF_to_DAC2)
CLOCK_EnableClock(kCLOCK_Dac2)
SPC_EnableActiveModeAnalogModules(SPC0, kSPC_controlDac2)
SPC_EnableLowPowerModeAnalogModules(SPC0, kSPC_controlDac2)
RESET_PeripheralReset(kDAC2_RST_SHIFT_RSTn)
DAC14_DoSoftwareReset()
DAC14_DoFIFOReset()
SPC_EnableActiveModeAnalogModules(SPC0, kSPC_controlVref)
これらの初期化手順は、MCXN947リファレンスマニュアルに基づいており、対応するMCUX SDK APIを使用して実装されました。
初期化関数は、DEVICE_DT_INST_DEFINE() を介してデバイス初期化コールバックとして登録されます。これらの変更により、HPDACは正常に動作するようになりました。
また、Zephyr MCUXのSYSCONクロックコントロールドライバーとmcux_lpc_syscon_clock.hも確認しましたバインディングは使っていますが、このペリフェラルのHPDAC/DAC2クロック識別子やクロック制御実装が見つからなかったため、現在はMCUX SDKのクロック、SPC、リセットAPIを直接使っています。
私の質問は以下のとおりです。
1. MCXN947 HPDACドライバーをバックポートする際、この方法は正しいのでしょうか?
2. 新しいZephyrバージョンでは、これらのリソースは別の場所で初期化されているのか、それとも上流nxp_hpdacドライバーはすでに設定済みだと想定しているのか?
3. HPDACデバイスのinitコールバックがこのMCXN947固有の初期化の正しい場所でしょうか?それともこれらのステップはZephyrの他の部分で処理すべきでしょうか?
参考までに完全なバックポートドライバを添付しました。
こんにちは、 @wesOS
1. MCXN947 HPDACドライバーをバックポートする際、この方法は正しいのでしょうか?
はい、これはバックポートを行う上で合理的かつ現実的なアプローチです。必要なDAC2クロック、SPCアナログモジュール、VREF、リセットリソースがZephyr 4.3環境の他の場所で初期化されていない場合、正しいHPDAC動作を確保するためにドライバーでの初期化が必要です。
2. 新しいZephyrバージョンでは、これらのリソースは別の場所で初期化されているのか、それとも上流nxp_hpdacドライバーはすでに設定済みだと想定しているのか?
HPDAC サポートはすでに上流に追加されています:
https://github.com/zephyrproject-rtos/zephyr/pull/104642
しかし、現在のアップストリーム実装を使用して簡単な検証を行ったところ、DAC2クロックが設定されていないことが確認されました。例えば、CLOCK_GetDacClkFreq(2)は私のテスト環境で0Hzを報告していますが、同等のMCUX SDK例ではDACクロック設定後は48MHzと報告されています。
この観察から、現在のドライバは特定のデバイスリソースがすでに設定されていると仮定しているようです。あなたの側の時計設定経路ももう一度確認してもらえますか?
また、クロック初期化のバグが確認された場合は、Zephyrチームにも報告し、さらなる調査を依頼します。
3. HPDACデバイスのinitコールバックがこのMCXN947固有の初期化の正しい場所でしょうか?それともこれらのステップはZephyrの他の部分で処理すべきでしょうか?
バックポートの場合、このロジックをHPDACデバイスの初期化コールバックに配置することは、実用的かつ許容できる解決策です。
とはいえ、MCXN947固有のDAC2クロック、SPC、VREF、およびリセットの設定は、汎用的なHPDACの動作として組み込まれるのではなく、SoC固有の機能として明確に分離されるべきである。長期的には、これらのリソースはクロック、リセット、パワーマネージメントフレームワークなど、Zephyrのインフラストラクチャを通じて管理されることが望ましいです。
BR
ハリー
ありがとうございます。MCXN947の設定でDAC2のクロックパスを再確認しました。
HPDACドライバーがクロックを設定する前に:
後:
CLOCK_SetClkDiv(kCLOCK_DivDac2Clk, 1U);
CLOCK_AttachClk(kFRO_HF_to_DAC2);
CLOCK_EnableClock(kCLOCK_Dac2);
次のようなメッセージが表示されました:
私も同じ挙動を目にしています:HPDACドライバーの初期化前にDAC2クロックが設定されていません。
MCXN947固有のリソース処理を分離しておくというあなたの説明も理にかなっています。
私が今主に理解しようとしているのは、最終的な上流ソリューションにおいて、その初期化処理がどのように分割されることを期待しているのかということです。
例えば、DAC2のクロック構成、SPC/VREFの設定、リセット処理がそれぞれ対応するZephyr/SoCインフラストラクチャに移行し、「dac_nxp_hpdac.c」と設定される予定ですか?汎用的なHPDAC初期化のみを保持するのですか?
主に各初期化ステップの意図された所有権を理解し、バックポートをその方向に合理的に整合させたいためです。
ありがとう。
BR
ウアシム
こんにちは、 @wesOS
結果の確認ありがとうございます。設定前にDAC2のクロックが0 Hz、48000000 Hzが設定後に起きているという事実は、HPDACドライバーが動作する前にDAC2クロックが初期化されていないことを強く示唆しています。
すでに内部のZephyrチームにバグ修正を報告しました。
FRDM-MCXN947実装をさらに調べたところ、既存のDACクロック初期化は現在、DACドライバ自体ではなく基板レベルで処理されていることがわかりました。
zephyr/boards/nxp/frdm_mcxn947/board.c
機能:
void board_early_init_hook(void)
DAC0とDAC1の両方について、クロックとSPCの初期化を実行します。
#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(dac0))
SPC_EnableActiveModeAnalogModules(SPC0, kSPC_controlDac0);
CLOCK_SetClkDiv(kCLOCK_DivDac0Clk, 1u);
CLOCK_AttachClk(kFRO_HF_to_DAC0);
CLOCK_EnableClock(kCLOCK_Dac0);
#endif
#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(dac1))
SPC_EnableActiveModeAnalogModules(SPC0, kSPC_controlDac1);
CLOCK_SetClkDiv(kCLOCK_DivDac1Clk, 1u);
CLOCK_AttachClk(kFRO_HF_to_DAC1);
CLOCK_EnableClock(kCLOCK_Dac1);
#endif
現在の実装から考えると、既存の基板設計と一貫性を保つことが期待されています。言い換えれば、DAC2のクロック初期化は既存のDAC0/DAC1初期化に加えてboard_early_init_hook()に追加でき、基板固有のクロックセットアップを汎用HPDACドライバに配置するのではなく、
BR
ハリー