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.

TMS570LC4357: DMA Bus error on first transfer to EMIF

Part Number: TMS570LC4357

The first time I start a DMA transfer from internal RAM to SDRAM on my 570LC4357 Eval board, I get a DMA bus error (indicated by ESM 1.20 bit and ESM interrupt) before any transfer happens. The transfer completes successfully.  I can repeat the transfer with out any further errors.  Both the internal RAM and SDRAM are initialized with a pattern before the transfer is started.  The destination address is 0x80000800 so it is not at the start or end of the SDRAM. I can DMA from SDRAM to internal RAM without  any error. I did not see anything in the errata (chip rev B) that addressed this. How can I identify the cause of this error?

  • Hi Darryl,

    The bus error may occurs during an instruction fetch while a watchdog timeout abort or other d-abort/p-abort occurs, or occurs if the memory (read from or write to) is not implemented or not ready for access.

    Is the bus error repeatable in your test? Has the SDRAM been initialized successfully before performing DMA transfer? 

  • The bus error happens only once when I start up a repeating DMA process.  The bus error is repeatable if I use the debugger to do a System Reset.  

    The SDRAM was initialized to a pattern before the test began, and the debugger is able to display it at a breakpoint before the error happens.

  • This issue is not resolved.  Is there anything else I can check?  

  • I did some test with DMA to transfer data between SRAM and SDRAM. I did not get DMA bus error.

    Since all master (CPU, DMA, HTU,...) has point to point connection to EMIF without going through ACP for coherency check. The coherency maintenance on EMIF between CPU and DMA needs to be handled by SW. Is the SDRAM accessed by other master?

  • This particular buffer in SDRAM is filled with a pattern before the DMA is started. No other masters access this buffer.  It was my understanding that access to the SDRAM is not cached. Is that not correct?

  • Hi Darryl,

    Cache is only used by CPU. DMA doesn't use cache.

  • Hi Darryl,

    I did more test today, and same as before, no DMA error is generated.

    This is my main():

    int main(void)
    {
    /* USER CODE BEGIN (3) */
    /* enable IRQ interrupt */
    uint16 i;
    uint32_t *ptr;
    gioInit();

    _enable_IRQ_interrupt_();

    emif_SDRAMInit();

    ptr = (unsigned int*)(0x80000000);
    for(i=0; i<0x4000; i++)
       *ptr++ = 0x00000000;

    /* - creating a data chunk in system ram to start with ... */
    loadDataPattern(D_SIZE, &TXDATA_RAM[0], 0x5A5A5A5A);
    loadDataPattern(D_SIZE, &TXDATA_RAM1[0], 0x5B5B5B5B);

    ptr = (unsigned int *)(0x80002000);
    for(i=0; i<(F_COUNT*E_COUNT); i++)
       *ptr++ = i;

    /* - configuring dma control packets */
    g_dmaCTRLPKT1.SADD = (uint32)TXDATA_RAM; /* source address */
    g_dmaCTRLPKT1.DADD = (uint32)(0x80000800);  /* destination address; SDRAM */
    g_dmaCTRLPKT1.CHCTRL = 0; /* channel control */
    g_dmaCTRLPKT1.FRCNT = F_COUNT; /* frame count */
    g_dmaCTRLPKT1.ELCNT = E_COUNT; /* element count */
    g_dmaCTRLPKT1.ELDOFFSET = 0; /* element destination offset */
    g_dmaCTRLPKT1.ELSOFFSET = 0; /* element destination offset */
    g_dmaCTRLPKT1.FRDOFFSET = 0; /* frame destination offset */
    g_dmaCTRLPKT1.FRSOFFSET = 0; /* frame destination offset */
    g_dmaCTRLPKT1.PORTASGN = PORTA_READ_PORTA_WRITE;
    g_dmaCTRLPKT1.RDSIZE = ACCESS_32_BIT; /* read size */
    g_dmaCTRLPKT1.WRSIZE = ACCESS_32_BIT; /* write size */
    g_dmaCTRLPKT1.TTYPE = FRAME_TRANSFER ; /* transfer type */
    g_dmaCTRLPKT1.ADDMODERD = ADDR_INC1; /* address mode read */
    g_dmaCTRLPKT1.ADDMODEWR = ADDR_INC1; /* address mode write */
    g_dmaCTRLPKT1.AUTOINIT = AUTOINIT_ON; /* autoinit */


    g_dmaCTRLPKT2.SADD = (uint32)(0x80002000);  /* source address */
    g_dmaCTRLPKT2.DADD = (uint32)RXDATA_RAM; /* destination address */
    g_dmaCTRLPKT2.CHCTRL = 0; /* channel control */
    g_dmaCTRLPKT2.FRCNT = F_COUNT; /* frame count */
    g_dmaCTRLPKT2.ELCNT = E_COUNT; /* element count */
    g_dmaCTRLPKT2.ELDOFFSET = 0; /* element destination offset */
    g_dmaCTRLPKT2.ELSOFFSET = 0; /* element destination offset */
    g_dmaCTRLPKT2.FRDOFFSET = 0; /* frame destination offset */
    g_dmaCTRLPKT2.FRSOFFSET = 0; /* frame destination offset */
    g_dmaCTRLPKT2.PORTASGN = PORTA_READ_PORTA_WRITE;
    g_dmaCTRLPKT2.RDSIZE = ACCESS_32_BIT; /* read size */
    g_dmaCTRLPKT2.WRSIZE = ACCESS_32_BIT; /* write size */
    g_dmaCTRLPKT2.TTYPE = FRAME_TRANSFER ; /* transfer type */
    g_dmaCTRLPKT2.ADDMODERD = ADDR_INC1; /* address mode read */
    g_dmaCTRLPKT2.ADDMODEWR = ADDR_INC1; /* address mode write */
    g_dmaCTRLPKT2.AUTOINIT = AUTOINIT_ON; /* autoinit */

    /* - setting dma control packets */
    dmaSetCtrlPacket(DMA_CH1,g_dmaCTRLPKT1); //tx
    dmaSetCtrlPacket(DMA_CH0,g_dmaCTRLPKT2); //rx

    /* - setting the dma channel to trigger on h/w request */
    dmaSetChEnable(DMA_CH1, DMA_SW);
    dmaSetChEnable(DMA_CH0, DMA_SW);

    dmaEnableInterrupt(DMA_CH0, HBC, DMA_INTA);

    dmaEnableInterrupt(DMA_CH1, HBC, DMA_INTA);

    dmaEnable();
    while(1);

    }