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.

  • 0
    •  Analog Employees 
    on Jan 6, 2010 12:37 AM

    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

  • Thanks for the quick response.

    Your answer doesn't explain why the DMA transfer never gets started.  I am monitoring the Ext RAM Write Enable signal, and there is no activity.  Using the interrupt would work to determine when the transfer is complete, as would monitoring the interrupt flag.

    Also, per def21065L.h, the Ext DMA channels are 6 and 7.

    /* DMA Channel Status (DMASTAT) */

    #define

    DMA0ST BIT_0 /* DMA channel 0 (SPORT0_A RX) Active Status */

    #define

    DMA1ST BIT_1 /* DMA channel 1 (SPORT1_A RX) Active Status */

    #define

    DMA2ST BIT_2 /* DMA channel 2 (SPORT0_A TX) Active Status */

    #define

    DMA3ST BIT_3 /* DMA channel 3 (SPORT1_A TX) Active Status */

    #define

    DMA4ST BIT_4 /* DMA channel 4 (SPORT0_B RX) Active Status */

    #define

    DMA5ST BIT_5 /* DMA channel 5 (SPORT1_B RX) Active Status */

    #define

    DMA6ST BIT_6 /* DMA channel 6 (EPB0) Active Status */

    #define

    DMA7ST BIT_7 /* DMA channel 7 (EPB1) Active Status */

    #define

    DMA8ST BIT_8 /* DMA channel 8 (SPORT0_B TX) Active Status */

    #define

    DMA9ST BIT_9 /* DMA channel 9 (SPORT1_B TX) Active Status */

     

    Please advise.

  • 0
    •  Analog Employees 
    on Jan 8, 2010 2:28 AM

    Hi Dan,

            I would like to first clarify on the DMA channel need to be used for External port channel 1. Please refer the ADSP-21065L user manual on the below link:

    http://www.analog.com/static/imported-files/processor_manuals/37788354774923823818314265L_book_um.pdf.

     

    Table 6-1 and Table 6-2 shows that the External port channel 1 is associated with DMA channel 1. On the def21065l.h file,the below definitions show the same:

     

    #define      IIEP1      0x48      /* DMA channel 9 index reg.            */
    #define      IMEP1      0x49      /* DMA channel 9 modify                */
    #define      CEP1       0x4A      /* DMA channel 9 count reg.            */
    #define      CPEP1      0x4B      /* DMA channel 9 chain pointer reg.    */
    #define      GPEP1      0x4C      /* DMA channel 9 general purpose reg.  */
    #define      EIEP1      0x4D      /* DMA channel 9 external index reg.  
    */
    #define      EMEP1      0x4E      /* DMA channel 9 external modify       */
    #define      ECEP1      0x4F      /* DMA channel 9 external count reg.  
    */

     

     

    #define      II9      0x48        /* DMA channel 9 index reg.            */
    #define      IM9      0x49        /* DMA channel 9 modify                */
    #define      C9       0x4A        /* DMA channel 9 count reg.            */
    #define      CP9      0x4B        /* DMA channel 9 chain pointer reg.    */
    #define      GP9      0x4C        /* DMA channel 9 general purpose reg.  */
    #define      EI9      0x4D        /* DMA channel 9 external index reg.  
    */
    #define      EM9      0x4E        /* DMA channel 9 external modify       */
    #define      EC9      0x4F        /* DMA channel 9 external count reg.   */

     

    I feel the comments used on the def21065l.h is not applicable for ADSP-21065L completely. I will take care of this and make sure that these comments are updated correctly.

     

    Also refer the Table 5-2 which shows the memory map for the processor. The maximum external memory address supported by the processor is on 0x03FFFFFF.  But the example sequence you have posted uses the external memory address of 0x10000000. I feel this might be the reason for the DMA not starting up.

     

    I have also added an example code which uses the DMA channel 9 for transfering data to the external SDRAM on the EZ-KIT. I have tested this code for both interrupt driven and polling mode. This code works fine.

     

    Best Regards,

    Jeyanthi

     

  • Many thanks!  I will check out your sample code.

    Note that table 6-12 in the UM also has the bit assignments wrong.  I actually looked at them both, and when they agreed, I figured they were correct.

  • After further experimenting, I determined that the reason the DMA didn't start was a bad destination address, as you suggested.  It now works correctly.

    However, I do observe that bit 7 is the correct one to monitor in DMASTAT for polling, as stated in the manual.  Bit 9 does not work for me.