ADSP-21065L Memory DMA

I am supporting a legacy product that is using the 21065L.  I would like to replace a memcpy() with a DMA copy to improve the throughput.

The original code is:

UNSIGNED32 *extMem = 0x10000000;

UNSIGNED32 *intMem = 0x0000D000;

memcpy(extMem, intMem, 100);

The DMA code is:

    // DMA off
    *pDMAC1 = 0;


    // set DMA control regs
    *pIIEP1 = (UNSIGNED32)(intMem); // internal RAM     
    *pIMEP1 = 1; // single increment
    *pCEP1 = 100; // count
    *pEIEP1 = (UNSIGNED32)(extMem); // external RAM
    *pEMEP1 = 1; // single increment
    *pECEP1 = 100; // count


    // turn DMA on
    *pDMAC1 = (DEN | TRAN | MASTER);


    // wait for DMA to finish, to keep the same flow as with memcpy
    while ((*pDMASTAT & DMA7ST) != 0);  

When I run this, nothing happens.  It doesn't hang, it just falls through with no memory writes at all.

I'm sure it's something simple, as I'm not familiar with this device.

TIA.

Parents
  • Hi Dan,

            On the ADSP-21065L processors the DMA channel 9 is used for EPB1 FIFO. In your code sequence you are polling the status of the DMA7ST. Please change this to DMA9ST as below and test.  That should help.

       while ((*pDMASTAT & DMA9ST) != 0); 

    Alternatively you may enable the interrupt for the EP1 and set some software flag inside the ISR. Instead of polling the DMASTAT register you may check for the software flag to become 1.

    int DMA_done = 0;

    main()

    {

    interrupt(SIG_EP1I,External_Port_Isr);

    // DMA off
        *pDMAC1 = 0;


        // set DMA control regs
        *pIIEP1 = (UNSIGNED32)(intMem); // internal RAM     
        *pIMEP1 = 1; // single increment
        *pCEP1 = 100; // count
        *pEIEP1 = (UNSIGNED32)(extMem); // external RAM
        *pEMEP1 = 1; // single increment
        *pECEP1 = 100; // count


        // turn DMA on
        *pDMAC1 = (DEN | TRAN | MASTER);


        // wait for DMA to finish, to keep the same flow as with memcpy
         while(DMA_done == 0);

    }

    void External_Port_Isr(int i)
    {
    DMA_done = 1; 
    }

    Let me know if you still see any problem.

    Best Regards,

    Jeyanthi

Reply
  • Hi Dan,

            On the ADSP-21065L processors the DMA channel 9 is used for EPB1 FIFO. In your code sequence you are polling the status of the DMA7ST. Please change this to DMA9ST as below and test.  That should help.

       while ((*pDMASTAT & DMA9ST) != 0); 

    Alternatively you may enable the interrupt for the EP1 and set some software flag inside the ISR. Instead of polling the DMASTAT register you may check for the software flag to become 1.

    int DMA_done = 0;

    main()

    {

    interrupt(SIG_EP1I,External_Port_Isr);

    // DMA off
        *pDMAC1 = 0;


        // set DMA control regs
        *pIIEP1 = (UNSIGNED32)(intMem); // internal RAM     
        *pIMEP1 = 1; // single increment
        *pCEP1 = 100; // count
        *pEIEP1 = (UNSIGNED32)(extMem); // external RAM
        *pEMEP1 = 1; // single increment
        *pECEP1 = 100; // count


        // turn DMA on
        *pDMAC1 = (DEN | TRAN | MASTER);


        // wait for DMA to finish, to keep the same flow as with memcpy
         while(DMA_done == 0);

    }

    void External_Port_Isr(int i)
    {
    DMA_done = 1; 
    }

    Let me know if you still see any problem.

    Best Regards,

    Jeyanthi

Children
No Data