Part Number: PROCESSOR-SDK-AM437X
Tool/software: TI-RTOS
Hi,
What I see when I debug my code is that sometimes (seems to be random) EDMA transfer is doubled.
What I do is "EDMA multi-dimensional shift register" triggered with CPU. I use "self-chain" for partial transfer (for huge data size is advice to split transfer into several smaller chunks) and "self-prepare / link mode" to reload PaRAM without CPU intervention.
Can you please check my setup:
ch_chain_link1 = EDMA3_DRV_LINK_CHANNEL;
ch_chain_link2 = EDMA3_DRV_LINK_CHANNEL;
for(ch_chain = 31; ch_chain < 64; ch_chain++){
tcc_chain = ch_chain;
edmaResult = EDMA3_DRV_requestChannel(hEdma, &ch_chain, &tcc_chain,(EDMA3_RM_EventQueue)2,NULL, NULL);
if(edmaResult == EDMA3_DRV_SOK){
break;
}
}
if(edmaResult != EDMA3_DRV_SOK){
ERROR_H;
}
edmaResult = EDMA3_DRV_requestChannel(hEdma, &ch_chain_link1, NULL,(EDMA3_RM_EventQueue)2,NULL, NULL);
if(edmaResult != EDMA3_DRV_SOK){
ERROR_H;
}
edmaResult = EDMA3_DRV_requestChannel(hEdma, &ch_chain_link2, NULL,(EDMA3_RM_EventQueue)2,NULL, NULL);
if(edmaResult != EDMA3_DRV_SOK){
ERROR_H;
}
/* Transfer complete chaining enable. */
chain.tcchEn = EDMA3_DRV_TCCHEN_DIS;
/* Intermediate transfer complete chaining enable. */
chain.itcchEn = EDMA3_DRV_ITCCHEN_EN;
/* Transfer complete interrupt is enabled. */
chain.tcintEn = EDMA3_DRV_TCINTEN_EN;
/* Intermediate transfer complete interrupt is disabled. */
chain.itcintEn = EDMA3_DRV_ITCINTEN_DIS;
memset(&opt, 0, sizeof(opt));
opt.reg = 0;
/* Src & Dest are in INCR modes */
opt.reg_bit.sam = 0;
opt.reg_bit.dam = 0;
/* Program the TCC */
opt.reg |= ((tcc_chain << (0x0000000Cu)) & (0x0003F000u));
/* Final transfer completion interrupt */
opt.reg_bit.itcinten = 0;
opt.reg_bit.tcinten= 1;
opt.reg_bit.syncdim = 1;
PaRAM.opt = opt.reg;
PaRAM.srcAddr = (uint32_t)&context->FIRdata.FIR_shiftReg[0][FIR_LEN-2];
PaRAM.destAddr = (uint32_t)&context->FIRdata.FIR_shiftReg[0][FIR_LEN-1];
PaRAM.aCnt = sizeof(context->FIRdata.FIR_shiftReg[0][0]);
PaRAM.bCnt = FIR_LEN-1;
PaRAM.cCnt = NUMBER_OF_FIR_CH;
PaRAM.bCntReload = FIR_LEN-1;
PaRAM.srcBIdx = (int16_t)( (int32_t)&context->FIRdata.FIR_shiftReg[0][FIR_LEN-3] - (int32_t)&context->FIRdata.FIR_shiftReg[0][FIR_LEN-2]);
PaRAM.srcCIdx = (int16_t)((int32_t)&context->FIRdata.FIR_shiftReg[1][0] - (int32_t)&context->FIRdata.FIR_shiftReg[0][0]);
PaRAM.destBIdx = (int16_t)((int32_t)&context->FIRdata.FIR_shiftReg[0][FIR_LEN-2] - (int32_t)&context->FIRdata.FIR_shiftReg[0][FIR_LEN-1]);
PaRAM.destCIdx = (int16_t)((int32_t)&context->FIRdata.FIR_shiftReg[1][0] - (int32_t)&context->FIRdata.FIR_shiftReg[0][0]);
PaRAM.linkAddr = 0xFFFF;
edmaResult |= EDMA3_DRV_setPaRAM (context->hEdma, ch_chain, &PaRAM);
edmaResult |= EDMA3_DRV_chainChannel(context->hEdma, ch_chain, ch_chain, (EDMA3_DRV_ChainOptions *)&chain);
edmaResult |= EDMA3_DRV_registerTccCb(context->hEdma,
ch_chain,
FIRshift_DmaIRQ, context);
edmaResult |= EDMA3_DRV_getPaRAM(context->hEdma, ch_chain, &PaRAM);
edmaResult |= EDMA3_DRV_setPaRAM (context->hEdma, ch_chain_link1, &PaRAM);
edmaResult |= EDMA3_DRV_setPaRAM (context->hEdma, ch_chain_link2, &PaRAM);
edmaResult |= EDMA3_DRV_linkChannel (context->hEdma, ch_chain, ch_chain_link1);
edmaResult |= EDMA3_DRV_linkChannel (context->hEdma, ch_chain_link1, ch_chain_link2);
edmaResult |= EDMA3_DRV_linkChannel (context->hEdma, ch_chain_link2, ch_chain_link1);
if(edmaResult != EDMA3_DRV_SOK){
ERROR_H;
}
This is how I triger:
if(EDMA3_DRV_SOK != EDMA3_DRV_enableTransfer(context->hEdma,context->CH, EDMA3_DRV_TRIG_MODE_MANUAL)){
ERROR_H;
}
This is isr callback function:
static void FIRshift_DmaIRQ(uint32_t tcc,EDMA3_RM_TccStatus status,void *appData){
FIR_shiftContext *context = (FIR_shiftContext *)appData;
int x;
if(EDMA3_RM_XFER_COMPLETE == status){
Custom_cache_invalidate((uint32_t)context->FIRdata.FIR_shiftReg, sizeof(context->FIRdata.FIR_shiftReg));
// for(x = 0; x < NUMBER_OF_FIR_CH; x++){
// context->FIRdata.FIR_shiftReg[x][0] = context->FIRdata.inputBuff.inputFIR[x];
// Custom_cache_writeBack((uint32_t)&context->FIRdata.FIR_shiftReg[x][0], sizeof(context->FIRdata.FIR_shiftReg[x][0]));
// }
context->FIRdata.FIR_shiftReg[0][0].int_shiftReg = context->FIRdata.inputBuff.filds.index;
Custom_cache_writeBack((uint32_t)&context->FIRdata.FIR_shiftReg[0][0], sizeof(context->FIRdata.FIR_shiftReg[0][0].int_shiftReg));
context->FIRdata.FIR_shiftReg[1][0].int_shiftReg = context->FIRdata.inputBuff.filds.UTC;
Custom_cache_writeBack((uint32_t)&context->FIRdata.FIR_shiftReg[1][0], sizeof(context->FIRdata.FIR_shiftReg[0][0].int_shiftReg));
context->FIRdata.FIR_shiftReg[2][0].float_shiftReg = context->FIRdata.inputBuff.filds.freq;
Custom_cache_writeBack((uint32_t)&context->FIRdata.FIR_shiftReg[2][0], sizeof(context->FIRdata.FIR_shiftReg[0][0].int_shiftReg));
for(x = 0; x < FIR_PHASOR_LEN; x++){
context->FIRdata.FIR_shiftReg[3+x*2][0].float_shiftReg = context->FIRdata.inputBuff.filds.phasor[x].Re_;//re
Custom_cache_writeBack((uint32_t)&context->FIRdata.FIR_shiftReg[x*2][0], sizeof(context->FIRdata.FIR_shiftReg[0][0].float_shiftReg));
context->FIRdata.FIR_shiftReg[4+x*2][0].float_shiftReg = context->FIRdata.inputBuff.filds.phasor[x].Im_;//im
Custom_cache_writeBack((uint32_t)&context->FIRdata.FIR_shiftReg[1+x*2][0], sizeof(context->FIRdata.FIR_shiftReg[0][0].float_shiftReg));
}
//postEvent
if(context->DownSamplingCounters.lastREGISTER != context->FIRdata.inputBuff.filds.index){
context->DownSamplingCounters.lastREGISTER = context->FIRdata.inputBuff.filds.index;
Event_post(context->FIRactionEvent, EVENT_FIR_SHIFT_END);
}
else{
__asm__("BKPT");
}
}
else{
__asm__("BKPT");
}
}
After some random time, I get duplicated index.. also I can see duplicated value in output data....
Is this issue/behavioural known? Or more likely I do something stupid (but can't see for a week of investigating)..
Best regards , Mare