I'm trying to DMA data from a FIFO on some hardware that was set by the FPGA. The FIFO is a 16-bit address that we read from. Here are the snippets of code for my setup of things:
/Allocate a Transfer Complete Code (tcc)
//We need to do this dynamically since DSPI uses so many
//of these for DMA'ing different data
Int32Type tcc = EDMA_intAlloc(-1);
//Check for a valid tcc
if (tcc != -1)
{
// Standard settings, may be moved upstairs
emifEdmaConfig.opt = EDMA_OPT_RMK(
EDMA_OPT_PRI_HIGH,
// since we want to burst we need to keep it in WORDS
// remember we have 2 16bit consective registers to read from.
EDMA_OPT_ESIZE_32BIT,
EDMA_OPT_2DS_NO,
EDMA_OPT_SUM_NONE,
EDMA_OPT_2DD_NO,
EDMA_OPT_DUM_INC,
EDMA_OPT_TCINT_YES,
EDMA_OPT_TCC_OF( tcc & 0x0F),
EDMA_OPT_TCCM_OF( (tcc >> 4) & 0x03 ),
EDMA_OPT_ATCINT_DEFAULT,
EDMA_OPT_ATCC_DEFAULT,
EDMA_OPT_PDTS_DEFAULT,
EDMA_OPT_PDTD_DEFAULT,
EDMA_OPT_LINK_YES,
EDMA_OPT_FS_YES );
emifEdmaConfig.src = (Uint32) RX_FIFO_DATA;
emifEdmaConfig.idx = EDMA_IDX_OF( 0 );
emifEdmaConfig.rld = EDMA_RLD_OF( 0 );
//Hook the "EmifMsgEdmaRxCmpltIsr" operation for when the EDMA transfer completes
EDMA_intHook(tcc, (EDMA_IntHandler) EmifMsgEdmaRxCmpltIsr);
EDMA_intClear(tcc);
//Enable the interrupt
EDMA_intEnable(tcc);
......
Then in the routine that is called after the interrupt:
//The first word of the EMIF message is the length of the data
//Convert to number of 32-bit words and remove the length of the header
dataLength = (*RX_FIFO_DATA);
//Read the second part of the data length (should be zeros)
fifoRead = (*RX_FIFO_DATA);
//The second word of the EMIF message is the label ID. We don't use this with DSPI
//Just read and clear (16-bit reads, so we do two)
fifoRead = (*RX_FIFO_DATA);
fifoRead = (*RX_FIFO_DATA);
//Invalidate the cache
CACHE_invL2(reinterpret_cast<Uint32Type*>(&theMsg->msg[0]), dataLength*4, CACHE_WAIT);
dataLength -= 2;
//Set the length and destination fields of the EDMA config structure
//Since we are going to tack on a 'fake' PPM header, we start the DMA
//2 words into the data message.
emifEdmaConfig.cnt = dataLength;
emifEdmaConfig.dst = (Uint32) &theMsg->msg[PPMI_MSG_HDR_SIZE_WORDS];
//Check to make sure there IS a length!
if (emifEdmaConfig.cnt)
{
// QEDMA the data
EDMA_qdmaConfig(&emifEdmaConfig);
// Wait for EDMA completion (release the CPU for others)
SEM_pend (emifRxEDMASem, SYS_FOREVER);
}
else
{
LOG_printf(&trace, "No data length on EDMAConfig arg!");
}
What I'm seeing is that the data is put into the "theMsg->msg[PPMI_MSG_HDR_SIZE_WORDS]" address, but it starts one word later than it should (we can tell by the sequence were sending). We have verified things look good in the FIFO by doing a simple loop of reading the FIFO and outputting what we see. The data is in the right order there, so it has to be the DMA or a setting I have. I have the config.src set to the FIFO address, so I don't know what I'm doing wrong at this point.