Hello,
I currently have a problem regarding multiple EDMA accesses on a RT1052.
An EDMA channel is used to receive UART data from another RT1052 (peripheral to memory). This is started at the beginning of a millisecond task.
I want to use another DMA to read data via hyperbus from an FPGA (memory to memory). This DMA is started at the beginning of a 16kHz interrupt.
Now the following happens:
The UART DMA runs correctly. As soon as I execute the FPGA DMA once the UART DMA is not finished anymore (the Done flag is not set).
Here is the configuration of the UART DMA:
// set up RX DMA
CO_memset(&sEdma, 0, sizeof(sEdma));
sEdma.bytesEachRequest = 1;
sEdma.channelnum = CC_RXDMA_NUM;
sEdma.destaddr = pRxBuffer->pBuffer;
sEdma.transferbytes = pRxBuffer->uiSize;
sEdma.destwidth = 1;
sEdma.srcaddr = (void *)&CC_UART->DATA;
sEdma.srcwidth = 1;
sEdma.dmasource = CC_RXDMA_SRC;
sEdma.type = kEDMA_PeripheralToMemory;
EDMA_PrepareSingleBuffer(&g_sRxDmaHandle, &sEdma, 0);
And the configuration of the FPGA DMA:
// DMA Configuration
// RX DMA
CO_memset(&sEdma, 0, sizeof(sEdma));
sEdma.bytesEachRequest = 8;
sEdma.channelnum = DMANUM_FPGA_MOVER_RX;
sEdma.destaddr = &g_fpgaMoverDataRead.uiGPBits;
sEdma.transferbytes = sizeof(g_fpgaMoverDataRead) - 8;
sEdma.destwidth = 8;
sEdma.srcaddr = (void*)(FPGABASEADDR_HIPERBUS_DPRAM_UC1 + 8 + FPGA_MOVER_DATA_RX_OFFSET);
sEdma.srcwidth = 8;
sEdma.type = kEDMA_MemoryToMemory;
DMAMUX_EnableAlwaysOn(DMANUM_FPGA_MOVER_RX, 1);
EDMA_PrepareBuffer(&rxFPGA_DmaHndlMover, &sEdma, 0);
The DMA Setup function:
long EDMA_PrepareBuffer(register EDMA_HANDLE_TYPE *handle0, EDMA_SETUP_TYPE *setup0, unsigned long isringbuffer0)
{
unsigned long srctransfersize = 0; // Source data transfer size.
unsigned long desttransfersize = 0; // Destination data transfer size.
unsigned short srcoffset; // Sign-extended offset applied to the current source address to form the next-state value as each source read is completed.
unsigned short destoffset; // Sign-extended offset applied to the current destination address to form the next-state value as each destination write is completed.
unsigned char channel;
if (systemstatus.init.dma_init == 0) return(__SYS_ERROR_INIT());
if (handle0 == NULL) return(__TRACE_ERROR());
MEM_set(handle0, 0, sizeof(EDMA_HANDLE_TYPE));
if (setup0->channelnum >= 32) return(__TRACE_ERROR());
if (setup0->bytesEachRequest == 0) return(__TRACE_ERROR());
if ((setup0->transferbytes / setup0->bytesEachRequest) == 0) return(__TRACE_ERROR());
channel = setup0->channelnum;
DMAMUX_EnableChannel(channel);
DMAMUX_SetSource(channel, setup0->dmasource);
DMA0->TCD[channel].SADDR = 0;
DMA0->TCD[channel].SOFF = 0;
DMA0->TCD[channel].ATTR = 0;
DMA0->TCD[channel].NBYTES_MLNO = 0;
DMA0->TCD[channel].SLAST = 0;
DMA0->TCD[channel].DADDR = 0;
DMA0->TCD[channel].DOFF = 0;
DMA0->TCD[channel].CITER_ELINKNO = 0;
DMA0->TCD[channel].DLAST_SGA = 0;
DMA0->TCD[channel].CSR = 0;
DMA0->TCD[channel].BITER_ELINKNO = 0;
handle0->buffersize = setup0->transferbytes;
handle0->channel = channel;
handle0->config.destaddr = (unsigned long)setup0->destaddr;
handle0->config.srcaddr = (unsigned long)setup0->srcaddr;
handle0->config.bytesEachRequest = setup0->bytesEachRequest;
handle0->config.transferbytes = setup0->transferbytes;
handle0->config.type = setup0->type;
handle0->config.majorloopcounts = (handle0->config.transferbytes / handle0->config.bytesEachRequest);
switch (setup0->srcwidth)
{
case 1U: srctransfersize = kEDMA_TransferSize1Bytes; break;
case 2U: srctransfersize = kEDMA_TransferSize2Bytes; break;
case 4U: srctransfersize = kEDMA_TransferSize4Bytes; break;
case 8U: srctransfersize = kEDMA_TransferSize8Bytes; break;
// case 16U: srctransfersize = kEDMA_TransferSize16Bytes; break;
case 32U: srctransfersize = kEDMA_TransferSize32Bytes; break;
default: break;
}
switch (setup0->destwidth)
{
case 1U: desttransfersize = kEDMA_TransferSize1Bytes; break;
case 2U: desttransfersize = kEDMA_TransferSize2Bytes; break;
case 4U: desttransfersize = kEDMA_TransferSize4Bytes; break;
case 8U: desttransfersize = kEDMA_TransferSize8Bytes; break;
// case 16U: desttransfersize = kEDMA_TransferSize16Bytes; break;
case 32U: desttransfersize = kEDMA_TransferSize32Bytes; break;
default: break;
}
switch (setup0->type)
{
case kEDMA_MemoryToMemory:
destoffset = setup0->destwidth;
srcoffset = setup0->srcwidth;
DMA0->TCD[channel].SLAST = (unsigned long)(-1 * (long)setup0->transferbytes);
DMA0->TCD[channel].DLAST_SGA = (unsigned long)(-1 * (long)setup0->transferbytes);
break;
case kEDMA_MemoryToPeripheral:
destoffset = 0U;
srcoffset = setup0->srcwidth;
DMA0->TCD[channel].SLAST = (unsigned long)(-1 * (long)setup0->transferbytes);
DMA0->TCD[channel].DLAST_SGA = 0;
break;
case kEDMA_PeripheralToMemory:
destoffset = setup0->destwidth;
srcoffset = 0U;
handle0->bufferptr = (unsigned char*)setup0->destaddr;
DMA0->TCD[channel].SLAST = 0;
DMA0->TCD[channel].DLAST_SGA = (unsigned long)(-1 * (long)setup0->transferbytes);
break;
default:
return(__TRACE_ERROR());
}
DMA0->TCD[channel].SADDR = handle0->config.srcaddr; // source address
DMA0->TCD[channel].DADDR = handle0->config.destaddr; // destination address
DMA0->TCD[channel].ATTR = DMA_ATTR_SSIZE(srctransfersize) | DMA_ATTR_DSIZE(desttransfersize); // Source data and destination data transfer size
DMA0->TCD[channel].SOFF = srcoffset; // Source address signed offset
DMA0->TCD[channel].DOFF = destoffset; // Destination address signed offset
DMA0->TCD[channel].NBYTES_MLNO = setup0->bytesEachRequest; // Minor byte transfer count
DMA0->TCD[channel].CITER_ELINKNO = handle0->config.majorloopcounts; // Current major iteration count
DMA0->TCD[channel].CSR = 0;
if (isringbuffer0)
handle0->status.ringbuffer = 1;
else
DMA0->TCD[channel].CSR = DMA_CSR_DREQ(1);
DMA0->TCD[channel].BITER_ELINKNO = handle0->config.majorloopcounts; // Starting major iteration count
handle0->status.init = 1;
return(0);
}
Is it possible that the start of the FPGA DMA effects the UART DMA?
Best regards
Daniel