This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

am335x EDMA Transfer Request Latency

I've got a simple Starterware GPMC project running with Beaglebone Black. I configured EDMA to transfer an array (ACNT=32, BCNT=1, CCN =1) of bytes from memory to GPMC and it's very fast. The GPMC is configured as 8-bit, non-multiplexed A/D, and with the GPMC timing I specified it sustains 8 MBytes/sec. No delays are introduced by EDMA and as far as I can tell, the GPMC transfers are 100% back-to-back.

However, when I use an external event (XDMA_EVENT_INTR2) for an "A" synchronized transfer with ACNT=1, BCNT=32, CCNT=1, there is an additional 375 nsec between GPMC bytes. How can I reduce or eliminate this delay? That delay is about what I can achieve with programmed IO!

My project only allocates one DMA channel (with crossbar map to XDMA_EVENT_INTR2) so there shouldn't be anything else delaying the request. Please tell me it shouldn't be that slow! Could you explain section 11.3.12.1.3 in the reference manual and how this could apply or be optimized for my application?

My transfer complete interrupt does get called at the end and I'm not using intermediate transfer complete or chaining and no event miss are reported.

  • You can NOT reduce this delay.

    This delay is the result of the bus arbitration. It occurs for each single access to the bus.

    So, using DMA with ACNT=1 is not a good idea if you want speed.

    Solution: use an external FIFO in your device, and transfer more than 1 Byte at a time.

    regards

    Wolfgang

  • I changed my code so EDMA uses ACNT=8 and BCNT=4 so each event transfers 8 bytes. It writes to GPMC as expected when using source and destination increment mode (SAM and DAM = 0). The chip I’m interfacing has an internal FIFO but it must be accessed at relative address 0 so I need to not increment the destination so I set DAM = 1. But when I do this, neither GPMC_CS1 nor GPMC_WRN are asserted but I do get a transfer complete interrupt after 4 events (BCNT). Below is my PaRAM. Why would simply changing DAM cause GPMC to not assert these signals? It even fails if I set FWID in OPT to 3 (64-bit, 8 bytes).

    paramSet.srcAddr = (unsigned int)(SrcBuff);	// DATA_ALIGN(SrcBuff, SOC_CACHELINE_SIZE_MAX);
    paramSet.destAddr = (unsigned int)(GPMC_CS1_BASE_ADDR + FIFO_ADDR); 	// 0x02000000 + 0
    
    paramSet.aCnt = (unsigned short)aCount;		// aCount = 8
    paramSet.bCnt = (unsigned short)bCount;		// bCount = 4
    paramSet.cCnt = (unsigned short)cCount;		// cCount = 1
    
    paramSet.srcBIdx = (short)aCount;		// Bump source address by 8 after each event
    paramSet.destBIdx = 0;		// but don’t bump destination address
    
    paramSet.srcCIdx = 0;
    paramSet.destCIdx = 0;
    
    paramSet.bCntReload = 0;
    paramSet.linkAddr = (unsigned short)0xFFFF;
    paramSet.rsvd = 0;
    
    paramSet.opt = 0u;
    paramSet.opt |= EDMA3CC_OPT_DAM;	// Increment source, don’t increment destination
    
    tccNum = EDMA3_CHAN_NUM;	// Channel 12
    paramSet.opt |= ((tccNum << EDMA3CC_OPT_TCC_SHIFT) & EDMA3CC_OPT_TCC); // Completion code
    
    paramSet.opt |= (1 << EDMA3CC_OPT_TCINTEN_SHIFT);		// Transfer complete interrupt
    // At this point OPT = 0x0010C002
    EDMA3SetPaRAM(EDMAAPP_EDMACC_BASE_ADDRESS, tccNum, &paramSet); // Write PaRAM EDMA3EnableTransfer(SOC_EDMA30CC_0_REGS, EDMA3_CHAN_NUM, EDMA3_TRIG_MODE_EVENT);
  • GPMC does NOT support FIFO addressing mode. You have to use increment mode. Period.

    You may change the wiring between GPMC and the external chip so that the LSBs of the address bus are unused. So they can increment for each access, and the external device will not notice this.

    regards

    Wolfgang