RT1052 and multiple EDMA Channels

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

RT1052 and multiple EDMA Channels

148 Views
dz1
Contributor I

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

0 Kudos
0 Replies