I have a 6413 project with a hardware interrupt (HWI_INT4) that is triggered externally at 120 kHz. At the beginning of this interrupt I set up the QDMA to read two 16-bit words from external memory, as follows:
volatile unsigned int *base; base = (volatile unsigned int*)(_EDMA_QOPT_ADDR); base[_EDMA_QSRC_OFFSET] = (unsigned int)source; base[_EDMA_QCNT_OFFSET] = (unsigned int)count; base[_EDMA_QDST_OFFSET] = (unsigned int)dest; base[_EDMA_QIDX_OFFSET] = (unsigned int)0; base[_EDMA_QSOPT_OFFSET] = (unsigned int)0x29200001;
I then go on to execute some code in my interrupt that does not depend on the values to be read. Eventually I hit a point where I can't continue until I've gotten the data from QDMA, so I want the processor to wait until the transfer has completed.
I have tried the following:
while (!(EDMA_getPriQStatus() & EDMA_OPT_PRI_HIGH));
but that does not appear to work as expected (i.e., the processor seems to get past this line of code even though the transfer is not completed).
I have also tried setting the TCINT bit in QSOPT, leaving TCC and TCCM zero as above, and waiting for bit zero of CIPR to be set:
base[_EDMA_QSOPT_OFFSET] = (unsigned int)0x29300001; // replace corresponding line in setup above
volatile unsigned int *base; base = (volatile unsigned int*)_EDMA_CIPR_ADDR; while (!(*base & 0x1));
However, this also seems to allow the processor to conitnue in cases where the transfer has not completed.
What is the recommended way to check for the completion of a QDMA transfer within an ISR?
Hello,
The TCINT method is the standard one; sure you actively reset the CIPR bit 0 after use (or before programming QDMA) ?
Jakez
Hi Jakez, thanks for the quick response.
It seems like the problem may have been that I was resetting the CIPR bit after use, but not before programming the QDMA. Does it make sense that this would lead to unexpected behavior?
My sequence now is:
This appears to be working as expected. Does it sound OK to you? I'm guessing that step 5 is redundant with step 1 since I'm doing this repeatedly.
I meant the CIPR must be 0 before starting the transfer, by resetting it either before or after the repeated process (while before is preferable, ie step 5 may be suppressed).
Jon,
Step 1, clearing CIPR before the transfer begins, is a requirement for a reliable design. Without doing this before the transfer, you are counting on the device reset leaving this bit in the 0 state, and that is not a safe choice. You could do a soft reset or an emulation reset or branch to _c_int00 or many other things, and these could possibly leave the CIPR bit in the set state (1).
Please follow Jakez' recommendation to use step 1 and suppress step 5.
Regards,RandyP
Search for answers, Ask a question, click Verify when complete, Help others, Learn more.
Thanks Jakez and Randy. It's working now that I am clearing the CIPR bit in the appropriate place.