Tool/software: TI-RTOS
Hi,
I'm wondering about the options for setting up interrupts.
In my application setup I'm using ARM main cpu and ICSS - PRU collaboration. PRU collect data and send it to DDR memory where ARM process this data.
Idea is that PRU work as "custom" periphery and EDMA write from PRU 1-D buffer (from internal PRU memory) to circular 2-D buffer (in DDR).
Now if I present current operation flow.
ARM use library :
#include <ti/sdo/edma3/drv/sample/bios6_edma3_drv_sample.h> #include <ti/sdo/edma3/drv/src/edma3.h>
I request "main" chanell and "link" chanels.
EDMA_ch_context.G_tcc = EDMA3_DRV_TCC_ANY;
EDMA_ch_context.G_chId = EDMA3_DRV_DMA_CHANNEL_ANY;
edmaResult = EDMA3_DRV_requestChannel(hEdma, &EDMA_ch_context.G_chId, &EDMA_ch_context.G_tcc,
(EDMA3_RM_EventQueue)1,
NULL, NULL);
for(x = 0; x < numOfLinkChannels; x++){
EDMA_ch_context.tcc[x] = EDMA3_DRV_TCC_ANY;
EDMA_ch_context.chId[x] = EDMA3_DRV_LINK_CHANNEL;
edmaResult = EDMA3_DRV_requestChannel(hEdma, &EDMA_ch_context.chId[x], &EDMA_ch_context.tcc[x],
(EDMA3_RM_EventQueue)1,
NULL, NULL);
}
In this case I don't use callback (but I would like to in future).
OPT field is constant for all channels:
//*************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 |= ((EDMA_ch_context.G_tcc << (0x0000000Cu)) & (0x0003F000u));
/* Enable Intermediate & Final transfer completion interrupt */
opt.reg_bit.itcinten = 1;
opt.reg_bit.tcinten= 1;
opt.reg_bit.syncdim = 1;//AB-sync
Now I define "testLinkingStruct"-struct which is then written to PRU (so PRU can found flags in EDMA registers).
testLinkingStruct.dmaReg.ch = EDMA_ch_context.G_chId;
testLinkingStruct.dmaReg.tcc = EDMA_ch_context.G_tcc;
testLinkingStruct.dmaReg.tccMask = (uint32_t)(1UL << EDMA_ch_context.G_tcc);
testLinkingStruct.dmaReg.triggerType = (uint32_t*)&edma3DrvChBoundRes[edma3Id][EDMA_ch_context.G_chId].trigMode;
if(EDMA_ch_context.G_chId < 32){
testLinkingStruct.dmaReg.ESRx = (uint32_t*)&drvInst->shadowRegs->ESR;
testLinkingStruct.dmaReg.ICRx = (uint32_t*)&drvInst->shadowRegs->ICR;
testLinkingStruct.dmaReg.IPRx = (uint32_t*)&drvInst->shadowRegs->IPR;
testLinkingStruct.dmaReg.channelMask = (uint32_t)(1UL << EDMA_ch_context.G_chId);
}
else{
testLinkingStruct.dmaReg.ESRx = (uint32_t*)&drvInst->shadowRegs->ESRH;
testLinkingStruct.dmaReg.ICRx = (uint32_t*)&drvInst->shadowRegs->ICRH;
testLinkingStruct.dmaReg.IPRx = (uint32_t*)&drvInst->shadowRegs->IPRH;
testLinkingStruct.dmaReg.channelMask = (uint32_t)(1UL << (EDMA_ch_context.G_chId-32));
}
Then when PRU has data ready to transmit it can trigger transfer as:
*(testLinkingStruct.dmaReg.ESRx) |= testLinkingStruct.dmaReg.channelMask;//start transfer
*(testLinkingStruct.dmaReg.triggerType) = 0;
Which is equivalent to
EDMA3_DRV_enableTransfer
from my uderstanding.....
Then PRU collect new data, but before it transfer new chunk of data it need to check if previous transfer was complete - that why Intermediate interrupt is needed
while(! (*(testLinkingStruct.dmaReg.IPRx) & testLinkingStruct.dmaReg.tccMask));
Which is equalent to
EDMA3_DRV_checkAndClearTcc
Now when total number of cCnt is complete, PRU send msg to ARM that total transfer of data chunk is complete. And this bother me...
I wish to make callback function on ARM when tcinten happen, but also need itcinten for PRU previous transfer complete check.
Is any option for this kind functionality? Can I pull any other register (insted of IPR) with PRU to check previous transfer complete, so I can use callback on ARM side on tcinten?
Any suggestion?