Tip / ログイン to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Translation_Bot
Community Manager
Community Manager
Community Manager

私のコード要件: ADC グループ G8、チャネル 0 ~ 7 (つまり 8 チャネル) のデータを DMA 経由でターゲット アレイに転送しますが、テストの結果、転送数が間違っていることがわかりました。結果については、添付の図を参照してください。

要件は 8 チャネル、transferCount は 8、つまり毎回 8 チャネルが転送され、movesize は 16 ビットです。

対象配列の循環バッファは 128 Byte、ステップは Step_1、つまり 8 チャネルずつ移動し、サイクルは 8 回です。

コードを実行すると、ターゲット配列のインデックス 0 ~ 19 のみが更新されていることがわかります。つまり、0 ~ 19 のデータが更新されており、その他はすべて 0 です。

見てみるのを手伝ってください:

Snipaste_2023-12-15_14-24-28.png

コードは以下のように表示されます

グローバル変数は次のとおりです。

/* ターゲット配列*/

IFX_ALIGN(4) U16 g_u16EvadcDmaDestDataTest[8*8];

#define GROUPID_8 IfxEvadc_GroupId_8 /* EVADC グループ */
#define CHANNELS_NUM 8 /* 使用チャンネル数 */


/* EVADC ハンドル */
IfxEvadc_Adc g_evadc; /* EVADC モジュール ハンドル変数 */
IfxEvadc_Adc_Group g_adcGroup; /* EVADC グループ ハンドル変数 */
IfxEvadc_Adc_Channel g_adcChannel[CHANNELS_NUM]; /* EVADC チャネル ハンドル配列 */

/* DMA グローバル データ */
IfxDma_Dma_Channel g_stEvadcDmaChl;

 

1 つ目は、ILLD デモから直接コピーされた ADC の初期化です。

/* EVADC モジュールをデフォルトのパラメータで初期化する関数 */
void initEVADCModule()
{
/* 構成を作成します */
IfxEvadc_Adc_Config adcConfig;
IfxEvadc_Adc_initModuleConfig(&adcConfig, &MODULE_EVADC);
 
/* モジュールを初期化します */
IfxEvadc_Adc_initModule(&g_evadc, &adcConfig);
}
 
/* EVADC グループをデフォルトのパラメータで初期化する関数 */
void initEVADCGroup()
{
/* グループ設定を作成し、デフォルト値で初期化します */
IfxEvadc_Adc_GroupConfig adcGroupConfig;
IfxEvadc_Adc_initGroupConfig(&adcGroupConfig, &g_evadc);
 
/* グループ 2 を使用したユーザー構成の設定 */
adcGroupConfig.groupId = GROUPID_8;
adcGroupConfig.master = GROUPID_8;
 
/* キューに入れられたソースを有効にする */
adcGroupConfig.arbiter.requestSlotQueue0Enabled= TRUE;
 
/* すべてのゲートを「常時」モードで有効にする (エッジ検出なし) */
adcGroupConfig.queueRequest[0].triggerConfig.gatingMode = IfxEvadc_GatingMode_always;
 
/* グループを初期化します */
IfxEvadc_Adc_initGroup(&g_adcGroup, &adcGroupConfig);
}
 
void initEVADCChannels()
{
/* チャネル構成を作成します */
IfxEvadc_Adc_ChannelConfig adcChannelConfig[CHANNELS_NUM];
 
for(uint16 idx = 0; idx < CHANNELS_NUM; idx++)
{
/* デフォルト値で構成を初期化します */
IfxEvadc_Adc_initChannelConfig(&adcChannelConfig[idx], &g_adcGroup);
 
/* チャネル ID とそれぞれの結果レジスタを選択します */
adcChannelConfig[idx].channelId = (IfxEvadc_ChannelId)(idx);
adcChannelConfig[idx].resultRegister = (IfxEvadc_ChannelResult)(idx);
 
/* DMA */
adcChannelConfig[0].resultPriority = (IfxDma_ChannelId_0);
adcChannelConfig[0].resultServProvider = IfxSrc_Tos_dma;
 
/* チャネルを初期化します */
IfxEvadc_Adc_initChannel(&g_adcChannel[idx], &adcChannelConfig[idx]);
}
}
 
void fillAndStartQueue()
{
for(uint16 idx = 0; idx < CHANNELS_NUM; idx++)
{
/* 補充オプションを有効にしてチャネルをキューに追加します */
IfxEvadc_Adc_addToQueue(&g_adcChannel[idx], IfxEvadc_RequestSource_queue0, IFXEVADC_QUEUE_REFILL);
}
 
/* キューを開始します */
IfxEvadc_Adc_startQueue(&g_adcGroup, IfxEvadc_RequestSource_queue0);
}
 
/* デフォルトのパラメータで EVADC を初期化する関数 */
void initEVADC()
{
initEVADCModule(); /* EVADC モジュールを初期化します */
initEVADCGroup(); /* EVADC グループを初期化します */
initEVADCChannels(); /* チャネルを初期化します */
fillAndStartQueue(); /* キューを埋めて開始します */
}

 

次に、DMA の初期化が行われます。

uint32 dma_isr_count = 0;
 
IFX_INTERRUPT(ISR_フィードバック、0、ISR_PRIORITY_DMA);
void ISR_フィードバック(void)
{
dma_isr_count++;
}
 
 
 
void Demo_EVADC_Dma_Config(void)
{
IfxDma_Dma dma;
/* モジュール構成を作成します */
IfxDma_Dma_Config dmaConfig;
IfxDma_Dma_ChannelConfig dmaChlCfg;
 
 
/* モジュールを初期化します */
IfxDma_Dma_initModuleConfig(&dmaConfig, &MODULE_DMA);
IfxDma_Dma_initModule(&dma, &dmaConfig);
/*DMA チャネルの初期化*/
IfxDma_Dma_initChannelConfig(&dmaChlCfg, &dma);
 
 
/* チャネル固有の設定 */
dmaChlCfg.channelId= (IfxDma_ChannelId)(IfxDma_ChannelId_0);
 
/* 以下の設定は個別のチャネルで使用されます */
dmaChlCfg.transferCount= 8;
dmaChlCfg.requestMode= IfxDma_ChannelRequestMode_oneTransferPerRequest;//;
dmaChlCfg.moveSize= IfxDma_ChannelMoveSize_16bit;
dmaChlCfg.blockMode= IfxDma_ChannelMove_1;
dmaChlCfg.operationMode= IfxDma_ChannelOperationMode_continuous;
 
 
/* ソース */
dmaChlCfg.sourceAddress= (uint32_t)(&EVADC_G8_RES0);//g_stEvadcDmaSrcRes[u8ANG_Idx].u32AN_RES;
dmaChlCfg.sourceAddressCircularRange= IfxDma_ChannelIncrementCircular_32;
dmaChlCfg.sourceAddressIncrementDirection= IfxDma_ChannelIncrementDirection_positive;
dmaChlCfg.sourceAddressIncrementStep= IfxDma_ChannelIncrementStep_2;
dmaChlCfg.sourceCircularBufferEnabled= TRUE;
 
#if 1
/* 宛先 */
dmaChlCfg.destinationAddress= IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), &g_u16EvadcDmaDestDataTest[0]); //(uint32)&g_u16EvadcDmaDestDataTest[4];//(uint32)&g_u16EvadcDmaDestDataTest;//(uint32)&g_u16Evadc DmaDestData [u8ANG_Idx];
dmaChlCfg.destinationAddressCircularRange= IfxDma_ChannelIncrementCircular_128;//IfxDma_ChannelIncrementCircular_none;
dmaChlCfg.destinationAddressIncrementDirection= IfxDma_ChannelIncrementDirection_positive;
dmaChlCfg.destinationAddressIncrementStep= IfxDma_ChannelIncrementStep_1;
dmaChlCfg.destinationCircularBufferEnabled= TRUE;
#endif
 
/* ハードウェア リクエスト */
dmaChlCfg.requestSource= IfxDma_ChannelRequestSource_peripheral;
dmaChlCfg.hardwareRequestEnabled= 1;
 
#if 1
/* トランザクション後に割り込みが生成される */
dmaChlCfg.channelInterruptEnabled= TRUE; /* 割り込みの生成を有効にする */
dmaChlCfg.channelInterruptControl= IfxDma_ChannelInterruptControl_thresholdLimitMatch; /* 完全なトランザクションが完了すると、DMA は割り込みをトリガーします */
dmaChlCfg.channelInterruptTypeOfService= IfxSrc_Tos_cpu0; /* CPU0 はこの割り込みの割り込みサービス プロバイダーです */
dmaChlCfg.channelInterruptPriority= ISR_PRIORITY_DMA; /* 割り込みに優先順位を割り当てます */
#endif
 
/* DMA 初期化 */
IfxDma_Dma_initChannel(&g_stEvadcDmaChl, &dmaChlCfg);
IfxDma_Dma_startChannelTransaction(&g_stEvadcDmaChl);
}

smartconx_target@Q!w2e3r4t5y6u7i8o9p0||/t5/AURIX/TC399-%E5%A4%9A%E9%80%9A%E9%81%93ADC-DMA%E6%90%AC%E8%BF%90%E6%95%B0%E6%8D%AE%E4%B8%8D%E6%88%90%E5%8A%9F/td-p/660585

0 件の賞賛
0 返答(返信)