こんにちは
i.MXRT1024 EvkとMCUxpressoをプログラミングに使用しています。GPIOがローになるたびに、LPSPIからメモリに数バイトを転送する必要があります。受信したバイトの処理は、DMA チャネルのメジャー ループ割り込みで行う必要があります。プロセッサは FreeRTOS で実行されています。転送を開始できず、GPIO ISR から DMA チャネル割り込みを発生させることができません。私がこれまでに発見したことを以下で見つけてください。
1)タスクからDMA転送を開始するとき、すべて問題ありません。DMA 転送が開始され、DMA 割り込みが発生しました。LPSPI_MasterTransferEDMALite(LPSPI3, &g_m_edma_handle, &eDMA_masterXfer); 関数を使用しています
2) LPSPI_MasterTransferEDMALite (LPSPI3, &g_m_edma_handle, &eDMA_masterXfer) を使用して GPIO 割り込みで DMA 転送を開始しているとき、転送も割り込みも行われません
3)以下のコードを使用している場合、タスク内ではすべて(転送+完了割り込み)抽出は問題ありませんが、GPIO割り込み内では問題ありません。転送は開始されますが、メジャー ループ割り込みは開始されません
DMA0->TCD[0]です。DADDR = 0x81E00000;DADDR がメモリの先頭にリセットされる
EDMA_StartTransfer(g_m_edma_handle.edmaTxDataToTxRegHandle);
EDMA_StartTransfer(g_m_edma_handle.edmaRxRegToRxDataHandle);
LPSPI_EnableDMA(LPSPI3, (uint32_t)kLPSPI_RxDmaEnable | (uint32_t)kLPSPI_TxDmaEnable);
割り込みISR内でDMA転送を開始するのを手伝ってもらえますか?
転送後に DMA チャネルのメジャー ループ割り込みを生成します。よろしくお願いいたします。
Best regards, Jérémy
親愛なるメイリウ
私はついに問題が何であるかを見つけました。それは、ブロッキングSPI転送とDMA転送を混在させていたという事実から来ました。私のプログラムは現在完全に正常に動作しており、ブロッキングとDMA転送を問題なくオンザフライで切り替えることができます。
私の問題を解決するための希望を見させてくれてありがとう。
Best regards, Jérémy
私の前の投稿を参照してください、私はそれがうまくいくと確信しています。
私が行ったことを理解できたら、コードをプロジェクトにマージできます。
ぜひお試しください。
ありがとうございます
親愛なるメイリュー
迅速な返信をいただき、誠にありがとうございます。残念ながら、私のプログラムでは機能しません。lwip_ipv4_ipv6_echoの例から始めました。私が発見したのは、別のタスクから転送を開始しても、割り込みもトリガーされないということです。clock の spi が正しいバイト数 (私のプログラムでは 28) に切り替わっているのがわかりますが、TCD の DONE ビットは設定されていないため、割り込みは発生しません。各ピン割り込みでDMAMUX、DMA、およびDMAチャネル(以下の抜粋)の初期化全体を行う場合も同じことが起こります。FREERTOSの実行が問題の原因であるかどうかはわかりません。万が一、それが役立つ場合に備えて、メインのCファイルとADS1299_HALファイルを添付しました。
DMA転送の開始は、ADS1299_HAL.cの機能ActivateDMA(ligne 490)で行われます。
ピン割り込みは、同じファイル内の関数void GPIO1_Combined_16_31_IRQHandler(void)ligne 565で処理されます。NeedActivateDMA = 1 を発生させます。フラグを使用して、ActivateDMA() を呼び出すように別のタスクにシグナルを送ります。
ご協力いただきありがとうございます。
Best regards, Jérémy
これが ActivateDMA() のフォントです
DMAMUX_Init(DMAMUX);
DMAMUX_SetSource(DMAMUX, LPSPI_MASTER_DMA_RX_CHANNEL, kDmaRequestMuxLPSPI3Rx);
DMAMUX_EnableChannel(DMAMUX、LPSPI_MASTER_DMA_RX_CHANNEL);
DMAMUX_SetSource(DMAMUX, LPSPI_MASTER_DMA_TX_CHANNEL, kDmaRequestMuxLPSPI3Tx);
DMAMUX_EnableChannel(DMAMUX、LPSPI_MASTER_DMA_TX_CHANNEL);
/* EDMA init*/
EDMA_GetDefaultConfig(&userConfig);
userConfig.enableDebugMode = true;
EDMA_Init(DMA0, &userConfig);
/* lpspi マスターの設定*/
memset(&(lpspiEdmaMasterRxRegToRxDataHandle), 0, sizeof(lpspiEdmaMasterRxRegToRxDataHandle));
memset(&(lpspiEdmaMasterTxDataToTxRegHandle), 0, sizeof(lpspiEdmaMasterTxDataToTxRegHandle));
EDMA_CreateHandle(&(lpspiEdmaMasterRxRegToRxDataHandle), DMA0, LPSPI_MASTER_DMA_RX_CHANNEL);
EDMA_CreateHandle(&(lpspiEdmaMasterTxDataToTxRegHandle), DMA0, LPSPI_MASTER_DMA_TX_CHANNEL);
LPSPI_MasterTransferCreateHandleEDMA(LPSPI3, &g_m_edma_handle, LPSPI_MasterUserCallback, NULL, &lpspiEdmaMasterRxRegToRxDataHandle, &lpspiEdmaMasterTxDataToTxRegHandle);
LPSPI_MasterTransferPrepareEDMALite(LPSPI3、&g_m_edma_handle、 kLPSPI_MasterPcs0);
/* マスター転送を開始し、スレーブからデータを受け取る */
eDMA_masterXfer.txData = NULL;
eDMA_masterXfer.rxData = eDMA_masterRxData;
eDMA_masterXfer。データサイズ = 28;
CS1Low();
isTransferCompleted = false;
spiレベルで転送を生成しない修飾子
LPSPI_MasterTransferEDMALite(LPSPI3, &g_m_edma_handle, &eDMA_masterXfer);
LPSPI_EnableDMA(LPSPI3, (uint32_t)kLPSPI_RxDmaEnable | (uint32_t)kLPSPI_TxDmaEnable);
Hi @jterrien ,
私たちの製品に興味を持ち、コミュニティをご利用いただき、誠にありがとうございます。
私はあなたのためにテストをしました、私は割り込みISR内でDMA転送を開始し、転送後にDMAチャネルメジャーループ割り込みを生成することができます。
SDKデモ「evkmimxrt1024_igpio_input_interrupt」と「evkmimxrt1024_lpspi_edma_b2b_transfer_master」をマージします。MIMXRT1024-EVKボードを使用しています。
SW4ボタンを押すと、このGPIO IRQハンドラーでLPSPI_MasterTransferEDMALite関数を呼び出すと、プログラムがコールバック関数に入ることができることがわかりますLPSPI_MasterUserCallback。
それがあなたの助けになることを願っています。
それでもご不明な点がございましたら、お気軽にお知らせください。
良い一日をお過ごしください!
よろしくお願いいたします
メイリュウ