S32K348-GPIO EIRQからDMA要求親愛なるNXPサポートチームへ、
今、GPIO PTD6でEIRQ14の立ち上がりエッジ検出を設定し、このピン信号をDMAチャネルにマッピングし、PIT_1 Timer[0]から現在の値を取得しようとしています。これはフリーランニングとして設定されています。
SIUL2はPTDAで正しく設定されているようで、関連するMCUピンで信号(1Hz)を接続するとこのピンが切り替えられているのが確認できます。
でもDMAは私には合いません
私の推測では、PTD6から>DMAMUX-> DMAチャネル4の適切なチェーンを見つけるのに問題があるのだと思います。そして、これらの情報を正確にどこで見つけられるかも調べてください。
S32K3xx_DMAMUX_map.xlsx から以下の情報を取得しました。
OndrejK_0-1784190602227.png
そこで最初の問題です:PTD6(EIRQ14)に専用のソース>リクエストはどれですか?
RMマニュアルの表44とはどのように関連しているのでしょうか?
OndrejK_1-1784190821068.png
以下は、私が現在取り組んでいるコードの断片です。
PTD6 のセットアップ
void Setup_PTD6_EIRQ14_for_DMA ( void )
{
/* 1. MSCRレジスタによる物理ピンPTD6の設定 */
// PTD6 は、インデックス MSCR[102] に対応します (スクリーンショットに示されているとおり)
IP_SIUL2 -> MSCR [ 102 ] = 0 ; // レジスタをクリア
IP_SIUL2->MSCR[102] |= (1 << 19); // IBE = 1(入力バッファ有効化 - ピンを入力として設定)
IP_SIUL2 -> IMCR [ 542 - ( 512 )] = 3u ;
オプション:信号が浮かんでいる場合は、プルアップ(PUE=1、PUS=1)またはプルダウン(PUE=1、PUS=0)を有効にすることができます。
/* 2. 回線EIRQ[14]でのエッジ検出の有効化 */
// すべての立ち上がりエッジのタイムスタンプを取得したい
IP_SIUL2 -> IREER0 |= ( 1 << 14 ); // IREER0[EIRE14] = 1 (立ち上がりエッジを有効にする)
IP_SIUL2 -> IFEER0 &= ~ ( 1 << 14 ); // IFEER0[EIRE14] = 0 (立ち下がりエッジを無効化)
/* 3. リクエストルーティング: 割り込みからDMAへの変更 */
// このステップにより、エッジがCPU(NVIC)を起動せず、代わりにDMAラインをトリガーすることが保証されます。
IP_SIUL2->DIRSR0 |= (1 << 14); // DIRSR0[DIRS14] = 1(割り込みではなくDMA要求を選択する)
/* 4.EIRQのDMA要求生成の最終有効化[14] */
IP_SIUL2->DIRER0 |= (1 << 14); // DIRER0[EIRE14] = 1(DMA要求ラインを起動)
}
DMAチャネルの設定:
void Setup_eDMA_Channel4_Capture_PIT1 ( void )
{
/* 1.eDMAチャネル4のDMAMUX初期化 */
EIRQ14(ソース14)をeDMAチャンネル4にマッピング
IP_DMAMUX_1 -> CHCFG [ 4 ] = DMAMUX_CHCFG_ENBL_MASK | DMAMUX_CHCFG_SOURCE ( 7u ); // EIRQ14 は DMAMUX_1 のソース 7 です
//IP_DMAMUX_0->CHCFG[4] = 0U;
/* 2.チャネルPIT_1 4のTCD構成(正確なS32K3ベアメタル構文)*/
// ソース: PIT_1 タイマー 0 の現在の値
IP_TCD -> TCD4_SADDR = ( uint32_t ) & ( IP_PIT_1 -> TIMER [ 0 ]. CVAL );
IP_TCD -> TCD4_SOFF = 0 ; // ソースはインクリメントされません
IP_TCD -> TCD4_ATTR = 0x0202 ; // 32ビットソース、32ビットデスティネーション
// マイナーループ: 1回のトリガーで転送されるバイト数
// S32K3では、これはNBYTES_MLOFFNOレジスタに対応します(マイナーループリンクなし)
IP_TCD -> NBYTES4 . TCD4_NBYTES_MLOFFNO = 4 ; // トリガーごとに 4 バイト (32 ビット) を転送
// 宛先: RAM 内の配列
IP_TCD -> TCD4_DADDR = ( uint32_t ) dma_timestamps ;
IP_TCD -> TCD4_DOFF = 4 ; // 各エッジの後に RAM で 4 バイトシフトする
// 循環バッファ: 配列全体を埋めた後、先頭に戻る
IP_TCD -> TCD4_DLAST_SGA = - ( BUFFER_SIZE * 4 );
// 主要ループカウンタ:ループ内の反復回数の合計
//IP_TCD->CITTER4.TCD4_CITER_ELINKNO = BUFFER_SIZE;
IP_TCD -> CITER4 . TCD4_CITER_ELINKNO = BUFFER_SIZE ;
IP_TCD -> BITER4 . TCD4_BITER_ELINKNO = BUFFER_SIZE ;
/* 3.公式マクロによるハードウェアトリガーのeDMAチャネルアクティベーション */
//IP_TCD->CH4_CSR |= DMA_TCD_CH4_CSR_ERQ_MASK;
/* 3.ハードウェアトリガーのeDMAチャネル起動(非同期モード有効時)*/
// ビット 0 (ERQ) = 1 -> ハードウェア トリガーを有効にする
// ビット 2 (EARQ) = 1 -> 外部ピン (SIUL2 EIRQ) からの非同期要求を有効にします
IP_TCD -> CH4_CSR |= 3u ; // ERQ=1、EARQ=1
}
おそらくここが重要な部分でしょう。
IP_DMAMUX_1 -> CHCFG [ 4 ] = DMAMUX_CHCFG_ENBL_MASK | DMAMUX_CHCFG_SOURCE ( 7u ); // EIRQ14 は DMAMUX_1 のソース 7 です
どの IP_DMAMUX とどの DMAMUX_CHCFG_SOURCE を使用すればよいのか、また、これに関する適切な情報はどこにあるのか、少し混乱しています。
よろしくお願いします
オンドレイ
Re: S32K348-GPIO EIRQ to DMA requestこんにちは、@ OndrejK
「つまり、MCUには32のTCDチャネルがあり、TCD 0から15はDMAMUX_0に有効で、TCD 15から31はDMAMUX_1に適用されるということですか?"
はい、これらの情報はデータシートに記載されています。参考のためにコピーしておきます。
Senlent_0-1784272853624.png
Re: S32K348-GPIO EIRQ to DMA requestこんにちは、Senlentさん。
ご回答ありがとうございます。
TCDマッピングについてのあなたの意味がどこから出たのか教えてもらえますか?
つまり、MCUは32のTCDチャネルを持ち、TCD 0から15がDMAMUX_0に有効で、TCD 15から31は
DMAMUX_1?
DMAMUXとeDMAに関する情報について、まだ少し混乱しています。
よろしくお願いします
オンドレイ
Re: S32K348-GPIO EIRQ to DMA requestこんにちは、@OndrejK
あなたの理解は正しいです。
PTD6->EIRQ14->DMAMUX1.SOURCE 7.
IP_DMAMUX_1->CHCFG[4] = DMAMUX_CHCFG_ENBL_MASK | DMAMUX_CHCFG_SOURCE(7u); // EIRQ14 is source 7 for DMAMUX_1
しかし、TDC設定が間違っています。
私の理解では、それらは以下のようになるはずです。
IP_DMAMUX_1->CHCFG[0] ->TCD 16
IP_DMAMUX_1->CHCFG[4] -> TCD4ではなくTCD20
Re: S32K348-GPIO EIRQ to DMA requestこんにちは、センレントさん。
観察結果に基づいて、コードにいくつか変更を加えました。
これが私の最新のコードです。
メイン初期化:
Setup_PTD6_EIRQ14_for_DMA ();
Setup_PIT1_Timer0_FreeRunning ();
Setup_DMAMUX_Channel0_ToTCD16_Capture_PIT1 ();
// EIRQ14割り込みフラグをクリアする
IP_SIUL2 -> DISR0 = ( 1 << 14 );
そして、残りのコードは以下のとおりです。
void Setup_PTD6_EIRQ14_for_DMA ( void )
{
// 1. SIUL2 に対するフィルタ前の操作 (AK Už nie je povolený inde)
IP_SIUL2 -> IFCPR = 0U ; // Nastavenie deličky filtra na Functional Clock (bez dodatočného delenia)
// 2. Voliteľne vypnite フィルター pre daný EIRQ インデックス アレボ ホ ナスターブテ ナ 最小限のポチェト cyklov
// EIRQ14 より前 (v závislosti od mapovania registrov IFMCR):
IP_SIUL2 -> IFMCR [ 14 ] = 0U ; // 0U vypína digitalálny フィルター、hrana prechádza okamžite ako čistýhardvérový トリガー
/* 1. MSCRレジスタによる物理ピンPTD6の設定 */
// PTD6 は、インデックス MSCR[102] に対応します (スクリーンショットに示されているとおり)
IP_SIUL2 -> MSCR [ 102 ] = 0 ; // レジスタをクリア
IP_SIUL2->MSCR[102] |= (1 << 19); // IBE = 1(入力バッファ有効化 - ピンを入力として設定)
IP_SIUL2 -> IMCR [ 542 - ( 512 )] = 3u ;
オプション:信号が浮かんでいる場合は、プルアップ(PUE=1、PUS=1)またはプルダウン(PUE=1、PUS=0)を有効にすることができます。
/* 2. 回線EIRQ[14]でのエッジ検出の有効化 */
// すべての立ち上がりエッジのタイムスタンプを取得したい
IP_SIUL2 -> IREER0 |= ( 1 << 14 ); // IREER0[EIRE14] = 1 (立ち上がりエッジを有効にする)
IP_SIUL2 -> IFEER0 &= ~ ( 1 << 14 ); // IFEER0[EIRE14] = 0 (立ち下がりエッジを無効化)
/* 3. リクエストルーティング: 割り込みからDMAへの変更 */
// このステップにより、エッジがCPU(NVIC)を起動せず、代わりにDMAラインをトリガーすることが保証されます。
IP_SIUL2->DIRSR0 |= (1 << 14); // DIRSR0[DIRS14] = 1(割り込みではなくDMA要求を選択する)
/* 4.EIRQのDMA要求生成の最終有効化[14] */
IP_SIUL2->DIRER0 |= (1 << 14); // DIRER0[EIRE14] = 1(DMA要求ラインを起動)
}
void Setup_DMAMUX_Channel0_ToTCD16_Capture_PIT1 ( void )
{
/* 1.eDMAチャネル4のDMAMUX初期化 */
// Podľa NXP tabuľky prislúcha SIUL2 DMA要求 4 zdrojový index 7u
//IP_DMAMUX_1->CHCFG[4] = DMAMUX_CHCFG_ENBL_MASK | DMAMUX_CHCFG_SOURCE(7u);
ドキュメントに従い、まずチャネル4を無効にし、次に設定し、最後に有効にしてください
IP_DMAMUX_1 -> CHCFG [ 0 ] = 0u ;
/* 2.チャネルPIT_1 4のTCD構成(正確なS32K3ベアメタル構文)*/
// ソース: PIT_1 タイマー 0 の現在の値
IP_TCD -> TCD16_SADDR = ( uint32_t ) & ( IP_PIT_1 -> TIMER [ 0 ]. CVAL );
IP_TCD -> TCD16_SOFF = 0 ; // ソースはインクリメントされません
IP_TCD -> TCD16_ATTR = 0x0202 ; // 32ビットソース、32ビットデスティネーション
// マイナーループ: 1回のトリガーで転送されるバイト数
// S32K3では、これはNBYTES_MLOFFNOレジスタに対応します(マイナーループリンクなし)
IP_TCD -> NBYTES16 . TCD16_NBYTES_MLOFFNO = 4 ; // トリガーごとに 4 バイト (32 ビット) を転送
// 宛先: RAM 内の配列
IP_TCD -> TCD16_DADDR = ( uint32_t ) dma_timestamps ;
IP_TCD -> TCD16_DOFF = 4 ; // 各エッジの後に RAM で 4 バイトシフトする
// 循環バッファ: 配列全体を埋めた後、先頭に戻る
IP_TCD -> TCD16_DLAST_SGA = - ( BUFFER_SIZE * 4 );
// 主要ループカウンタ:ループ内の反復回数の合計
//IP_TCD->CITTER20.TCD20_CITER_ELINKNO = BUFFER_SIZE;
IP_TCD -> CITER16 . TCD16_CITER_ELINKNO = BUFFER_SIZE ;
IP_TCD -> BITER16 . TCD16_BITER_ELINKNO = BUFFER_SIZE ;
//IP_TCD->CH16_CSR |= 3u; // ERQ=1、EARQ=1
DMAMUXチャネル0を有効にする
IP_DMAMUX_1 -> CHCFG [ 0 ] = DMAMUX_CHCFG_ENBL_MASK | DMAMUX_CHCFG_SOURCE ( 6u );
__asm volatile ( "nop" );
__asm volatile ( "nop" );
IP_TCD -> CH16_CSR |= 3u ;
}
そして、このアサートが発生すると、EIRQ(14)によるDMA転送を開始できません。デバッガーでは、MCU PTD6ピンの信号を変更するとフラグが表示されます。
次に、手動でSTARTビットでDMA転送を開始できTCD16_CSR TCDチャネルではCITTERの値を減らし、PIT1_TIMER[0]の値をdma_timestampsアレイに格納します。
ちなみに、これは「通常の」SRAMセクションで定義されるべきです。以前、これをdata_cacheセクションに設定していたため、DMA「宛先バスエラー」が発生しました。
新しい定義:
__attribute__ ((整列( 32 ))) __attribute__ ((セクション( ".mcal_data" )))
uint32_t dma_timestamps [ BUFFER_SIZE ];
しかし、手動STARTをスキップして(コードの冒頭から設定してはいけません)、PTD6ピンの信号を変えると、DMAチャネルは何もせず、CITTERレジスタは初期化値のままです。
どこに問題があるのか教えてもらえますか?
それでも、PTD6-EIRQ(14)の主張フラグからTCD16チャネルへの適切な接続に問題があるようです。
DMAMUXチャネルの正しいソースかもしれませんね?
DMAMUX1-CH[0]については、すべてのソース(1~ DMAMUXのExcelテーブルにリストされているSUIL2インスタンスについて、成功しませんでしたが、ここでも私の手順が正しかったかどうかはわかりません。
Re: S32K348-GPIO EIRQ to DMA requestこんにちは、@ OndrejK
参考までに、PTD6を使用して単一のデータ転送のためにDMAをトリガーするデモを作成しました。
これはS32K344 + RTD 7.0.1をベースにしています。
そして私はそれを試してみました。
私の理解は正しいと保証します。
PTD6の場合、ソースは7である必要があります。
IP_DMAMUX_1 -> CHCFG [ 0 ] = DMAMUX_CHCFG_ENBL_MASK | DMAMUX_CHCFG_SOURCE ( 7u );
Senlent_1-1784689141057.png
Re: S32K348-GPIO EIRQ to DMA requestこんにちは、Senlentさん。
素晴らしい例をありがとうございました。
いくつか変更を加えた結果、動作するサンプルができました。調整済みプロジェクトを添付しますが、重要な問題が一つありました。
DMAリクエーションを有効にしたSIUL ICUは、DMA TCDチャネル全体が完全に設定される前にセットアップされました。その場合、TCD_SADDRとTCD_DADDRは空(値がゼロ)で、その後SULでDMAリクオンを有効にするとDMAエラー、つまり「ソースバスエラー」が発生します。これが私の理解です。
この初期化の順序変更後。例が私の環境で動作し始めました。
しかし、DMAMUXチャネルとTCDチャネルの正確な関係はまだ理解できません。
あなたは、DMAMUXはCHCGF[0]として構成する必要があると書いていました。
S32k344カスタム開発ボードでアプリをダウンロードして起動したところ、DMAMUX-CHCFG[3]が設定されており、関数のコード Dma_Mux_Ip_Init_Privileged 正確にこの構成に繋がっていることがわかりました。
RegisterIndex = DMA_MUX_IP_GATE_OFFSET((pConfig->pChannelConfigArr[ChannelCount].チャネル));
こちらはLauterbach Trace32デバッガのスクリーンショットで、すべての初期化ステップ後の最終セットアップを見ることができます:
OndrejK_0-1784795174339.png
Design Studioでは、RTDを7.0.1にアップデートした後の次の設定があります:
OndrejK_1-1784795478141.png
これは正しいですか?また、ここに3つのDMAマルチプレクサソースの選択肢があるとはどういう意味ですか?
Re: S32K348-GPIO EIRQ to DMA requestこんにちは、@ OndrejK
それは良かったですね。
この設定ツールは、初心者開発者にとっては混乱を招く可能性があります。
S32K348の場合、DMAMUX_3は存在せず、DMAMUX_0とDMAMUX_1のみが存在します。
•S32K310、S32K311、S32K312では、DMAMUX_0チャネル0–5およびDMAMUX_1チャネル0–5はそれぞれeDMA転送制御ディスクリプタ(TCD)0–5およびeDMAトランスファー制御ディスクリプタ(TCD)6–11にマッピングされます。したがって、DMAMUX_0 チャネル6〜15およびDMAMUX_1 チャネル6〜15のプログラミングは期待されていません。しかし、プログラムされた場合、アクセスはチャネル8から15に対してエラー応答、またはチャネル6から7に対してエラー応答なしのいずれかを引き起こします。
•残りのS32K3xxデバイスについては、DMAMUX_0チャネル0–15およびDMAMUX_1チャネル0–15がそれぞれeDMA転送制御ディスクリプタ(TCD)0–15およびeDMAトランスファーコントロールディスクリプタ(TCD)16–31にマッピングされています。
上記はデータシートからの抜粋であり、理解しやすい内容です。
「DMAハードウェアチャネル」はTCD番号に対応します。
DMA_CHANNEL_0~DMA_CHANNEL_15を選択した場合、デフォルトではDMAMUX_0が使用されます。
16~31を選択した場合、デフォルトでDMAMUX_1が使用されます。
例えば、このトピックではPTD6はDMAMUX_1のSource 7に対応し、「DMAハードウェアチャネル」はDMA_CHANNEL_16からDMA_CHANNEL_31までの任意の値に設定できます。
別の例を挙げましょう。もしEIRQ 7をDMAをトリガーすると、「DMAハードウェアチャネル」はDMA_CHANNEL_0からDMA_CHANNEL_15どの値にも設定できます。
Re: S32K348-GPIO EIRQ to DMA requestこんにちは、SenLentさん、
DMAチャネルを選ぶことについて、関連するグループから自由に選べるというイメージDMA_MUX
その間に他のDMA_MUX<-> <>TCDの組み合わせも試し、自分の側では次の1つだけを操作しました
IP_DMAMUX_1->CHCFG[3]およびTCD16。
次に他のものも試してみます。
IP_DMAMUX_1->CHCFG[4]とTCD17。
IP_DMAMUX_1->CHCFG[0]とTCD16。
そして、なぜ正確には IP_DMAMUX_1->CHCFG[3] と TCD16 だけなのか教えてください。働く ?
IP_DMAMUX_1->CHCFG[xx]とTCDyyの関係はどうなっているのでしょうか?
Re: S32K348-GPIO EIRQ to DMA requestこんにちは、@ OndrejK
正しい順番は以下のとおりです。
IP_DMAMUX_0>CHCFG[0]とTCD0。
IP_DMAMUX_0->CHCFG[1]とTCD1。
IP_DMAMUX_0->CHCFG[2]とTCD2。
IP_DMAMUX_0->CHCFG[3]とTCD3。
IP_DMAMUX_0->CHCFG[4]とTCD4。
IP_DMAMUX_0->CHCFG[5]とTCD5。
IP_DMAMUX_0->CHCFG[6]とTCD6。
IP_DMAMUX_0->CHCFG[7]とTCD7。
IP_DMAMUX_0->CHCFG[8]とTCD8。
IP_DMAMUX_0->CHCFG[9]とTCD9。
IP_DMAMUX_0->CHCFG[10]とTCD10。
IP_DMAMUX_0->CHCFG[11]とTCD11。
IP_DMAMUX_0->CHCFG[12]とTCD12。
IP_DMAMUX_0->CHCFG[13]とTCD13。
IP_DMAMUX_0->CHCFG[14]とTCD14。
IP_DMAMUX_0->CHCFG[15]とTCD15。
IP_DMAMUX_1->CHCFG[0]とTCD16。
IP_DMAMUX_1->CHCFG[1]とTCD17。
IP_DMAMUX_1->CHCFG[2]とTCD18。
IP_DMAMUX_1->CHCFG[3]とTCD19。
IP_DMAMUX_1->CHCFG[4]とTCD20。
IP_DMAMUX_1->CHCFG[5]とTCD21。
IP_DMAMUX_1->CHCFG[6]とTCD22。
IP_DMAMUX_1->CHCFG[7]とTCD23。
IP_DMAMUX_1->CHCFG[8]とTCD24。
IP_DMAMUX_1->CHCFG[9]とTCD25。
IP_DMAMUX_1->CHCFG[10]とTCD26。
IP_DMAMUX_1->CHCFG[11]とTCD27。
IP_DMAMUX_1->CHCFG[12]とTCD28。
IP_DMAMUX_1->CHCFG[13]とTCD29。
IP_DMAMUX_1->CHCFG[14]とTCD30。
IP_DMAMUX_1->CHCFG[15]とTCD31。
Re: S32K348-GPIO EIRQ to DMA requestこんにちは、SenLentさん。
最新のS32 DSプロジェクトでテストを行い、DMA_MUXの設定をさらに追加しました。
私の設定画面のスクリーンショットはこちらです。
OndrejK_0-1785138171795.png
そして、ビルドコードをボードにダウンロードした後の結果がこちらです。
OndrejK_2-1785138306423.png
ご覧の通り、DMA_MUXとTCDの割り当て順番は守られていません。
同じバグはRTDソフトウェアでも起きているのでしょうか?
Re: S32K348-GPIO EIRQ to DMA requestこちらが私のプロジェクトで、先に添付した最新のものを調整したばかりです
DMA_MUX_0でDMA_Channel_0とDMA_Channel_1の2チャネルを作成しました。
これらのチャネルにはDMA_MUX_0->CHCFG[3]およびDMA-MUX_0-CHCFG[2]が割り当てられています。
DMA_MUX_1で見られるような「混合」の順序です
Re: S32K348-GPIO EIRQ to DMA requestこんにちは、@ OndrejK
問題が何なのか分かりません。もっと分かりやすく説明してもらえますか?またはテストプロジェクト全体を教えていただけますか?そうすれば、どこに疑問があるのか教えてください。
Re: S32K348-GPIO EIRQ to DMA requestこんにちは、@ OndrejK
これは、使用しているデバッガー、あるいはデバッガーのバージョンに関連している可能性が高いことは明らかです。
Re: S32K348-GPIO EIRQ to DMA requestこんにちは、@ OndrejK
これはあなたが提供してくれたデモです。私は何も変更を加えていません。
これが私のテスト結果です。
Senlent_0-1785142055872.png
Re: S32K348-GPIO EIRQ to DMA requestこんにちは、Senlentさん。
その間、私は別の同僚とこの同じプロジェクトをテストしました。同僚はS32DSバージョン3.6.3を使用しています。そしてOzoneデバッガーも使用しましたが、結果はあなたと同じです。
あなたの言う通りみたいですね。でも、私の側で何が起こっているのか全く分かりません。
Re: S32K348-GPIO EIRQ to DMA requestこんにちは、SenLentさん。
ついに、ここでの「問題」がどこにあるのか分かりました。
問題は、OzoneとLauterbachが単にDMA_MUX->CHCFGの表示方法が異なることです。最後のコツは、これらのCHCFGレジスタがMCU側(DMA_MUX_1のベースアドレスは0x40284000)にこの順番でマッピングされていることです。
0x40284000 ->CHCFG[3]
0x40284001 ->CHCFG[2]
0x40284002 ->CHCFG[1]
0x40284003 ->CHCFG[0]
0x40284004 ->CHCFG[7]
0x40284005 ->CHCFG[6]
0x40284006 ->CHCFG[5]
0x40284007 ->CHCFG[4]
0x40284008 ->CHCFG[11]
....
下のスクリーンショットをご覧ください
OndrejK_0-1785316902701.png
そしてこの瞬間から私の結果は意味を持ち、あなたのアドバイスと一致しました
サポートありがとうございます
そして、この問題はCANで解決できるのでしょう
Re: S32K348-GPIO EIRQ to DMA requestこんにちは、@ OndrejK
よろしい。このトピックを閉じるには「解決策として受け入れる」をクリックしてください。