私はFRDM-MCXN947上で、以下のオーディオハードウェアを使用してリアルタイムANCシステムを構築しています。
このシステムでは、16ミリ秒ごとのフレームで4つのマイクすべてを同時にキャプチャする必要があります。
MCXN947は DMA要求ラインは1つだけ SAI1 RX用
(kDma0RequestMuxSai1Rx = 101U)、FIFO結合モード(RCR4.FCOMB)は唯一の
SDKでサポートされている、単一のDMAチャネルでRXD0とRXD1の両方からデータを受信する方法。
SDKバージョン: MCUXpresso SDK (mcuxsdk-core、コミット 0455af2)
ドライバーバージョン: fsl_sai v2.4.11 / fsl_sai_edma v2.7.4
ファイル: ドライバ/sai/fsl_sai.c
SAI_RxSetConfig() 無条件にクリアする RCR4.FCOMB いつでも channelNums > 1、
呼び出し元が明示的に設定した場合でも fifoCombine = kSAI_RXFifoCombineModeEnabledOnRead。
通話の流れは以下のとおりです。
SAI_RxSetFifoConfig() (fsl_sai.c(1103~1105行目)—正しく設定します RCR4.FCOMB
から config->fifoCombine:
rcr4 &= ~I2S_RCR4_FCOMB_MASK; rcr4 |= I2S_RCR4_FCOMB(config->fifoCombine); // ← set correctly base->RCR4 = rcr4;
SAI_RxSetConfig() (fsl_sai.c(1439行目~1444行目)— 後 ステップ1と
無条件にクリアします:
/* make sure combine mode disabled while multipe channel is used */
if (config->channelNums > 1U)
{
base->RCR4 &= ~I2S_RCR4_FCOMB_MASK; // ← always clears, ignores fifoCombine
}SAI_TransferRxSetConfigEDMA() (fsl_sai_edma.c362行目から368行目)— アサート()
それは正しい 必要 fifoCombine ゼロでないとき channelNums > 1 ですが、
ハードウェアレジスタではなく、設定構造体を検証します。assert は通過する
RCR4.FCOMB ハードウェア上では既に0になっています。
ステップ2のコメントにはこうあります。 「複数のチャネルを使用している間は、結合モードが無効になっていることを確認してください」
これは、TX側のロジックが誤ってRX側に適用されたものと思われます。RXの場合、FIFO
結合モードは 必須 マルチチャネルDMAについては、サンプルコードに記載されています。
で fsl_sai_edma.c 340~350行目。
電話した後 SAI_TransferRxSetConfigEDMA() と channelMask = kSAI_Channel0Mask | kSAI_Channel1Mask
そして fifoCombine = kSAI_RXFifoCombineModeEnabledOnRead:
シングルチャネルに戻す (kSAI_Channel0Mask のみ、 channelNums=1) 復元します
システムは直ちに完全稼働します。
の _sai_fifo_combine enum で fsl_sai.h (272~277行目)では数値が入れ替わっている。
TXとRXの方向については、以下を参照してください。
kSAI_FifoCombineModeEnabledOnRead = 1U, // TX only kSAI_RXFifoCombineModeEnabledOnRead = 2U, // RX only
サンプルコード fsl_sai_edma.c 348行目では kSAI_FifoCombineModeEnabledOnRead
(TX列挙型、値=1)はRX構成用です。デバイスでは
FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE=1 これは代わりにwrite-combineを暗黙的に構成します
RX の読み取り結合。
現在は手動で復元することでこの問題を回避しています RCR4.FCOMB 後 SAI_TransferRxSetConfigEDMA()
戻り値:
SAI_TransferRxSetConfigEDMA(SAI1, &s_saiRxHandle, &rxConfig); /* Workaround: fsl_sai.c:1443 clears RCR4.FCOMB unconditionally when channelNums>1 */ SAI1->RCR4 = (SAI1->RCR4 & ~I2S_RCR4_FCOMB_MASK) | I2S_RCR4_FCOMB(2U);
これは脆弱なため、SDK APIを介さずに直接レジスタにアクセスする必要があります。
完全な呼び出しチェーン分析を含むバグレポート全文を添付します。
お時間とサポートをいただき、ありがとうございました。
よろしくお願いします、
フイン・マオ
huynhmaook@gmail.com
こんにちは、 @maohuynh さん。
ご辛抱いただきありがとうございます。
こんにちは、 @maohuynh さん。
投稿ありがとうございます。ご指摘いただいた件について現在調査中です。できるだけ早くご連絡いたします。
BR
セレステ
こんにちは、 @Celeste_Liu さん。
ご説明いただきありがとうございます。
ソースコードを読み直した後、
SAI_RxSetFifoConfig() がクリア後に RCR4.FCOMB を復元するという点については同意します。実行順序に関するあなたの説明は正しいです。
しかし、ハードウェア障害の根本原因は別の問題です。列挙型_sai_fifo_combineはTXとRX間で数値を共有しますが、同じ数値に対してTCR4.FCOMBとRCR4.FCOMBのハードウェアエンコーディングが逆になっています(PERI_I2S.hで確認済み)。
fsl_sai_edma.c のサンプルコード348行目では、fifoCombine = kSAI_FifoCombineModeEnabledOnRead (= 1) と指示しています。これはTX列挙型です。その名前はRX DMA読み取りには正しいように聞こえますが、その数値(1)はRCR4の書き込み結合に対応しており、読み取り結合には対応していません。366行目のassert文は、この同じ誤った値を検証し、エラーを黙って通過させるため、ハードウェアの設定が誤っている間はエラーは報告されません。
私が適用した回避策は、SAI_TransferRxSetConfigEDMA() の直後に I2S_RCR4_FCOMB(2U) を書き込むことです。NXPは、348行目のサンプルコードでkSAI_RXFifoCombineModeEnabledOnRead(= 2)を使用すべきかどうか、また366行目のアサートをそれに合わせて更新すべきかどうかを確認していただけますか?
確認を手伝っていただけますか?
BRs、
マオ・フイン