Post Go back to editing

Caching seg_ext_dma for DMA

Category: Software
Product Number: ADSP-21569
Software Version: Cross Core Embedded Studio version 2.9.4.0

Hi,

I need to us SDRAM for storage of date that needs to be loaded and saved in L1.  The DMA should be able to transfer data at 450 MB/sec using the cache.   I am seeing numbers which are an order of magnitude slower indicating that the cache is not enabled for SDRAM and DMA transfers to L1.   I have looked at cache and DMA examples and they indicate that cache needs to be setup in the .ldf.  When I add the seg_ext_pmda to cache there is no performance change. 

Are there any specific instructions, examples or documentation that specifies how to setup caching SDRAM for DMA?

dxe_l2_pm_data PM 32
{
// L2 pm data.
INPUT_SECTIONS( $OBJS_LIBS(seg_pmda_nw seg_pmda seg_ext_pmda) )
} > MY_L2_CACHED_MEM

dxe_l2_pm_data_bw BW
{
// L2 pm data.
INPUT_SECTION_ALIGN(4)
INPUT_SECTIONS( $OBJS_LIBS(seg_pmda seg_ext_pmda) )
} > MY_L2_CACHED_MEM

-Steve

  • Hi Steve,

    We are looking into this and we will get back to as soon as possible.

    Regards,
    Divya.P

  • Hi Steve,

    Apologies for the delay

    To use cache, you have to place the code/data in external memory and enable the Cache in "Cache Configuration tab" from system.svc > Startup Code/LDF. This will automatically execute externally located functions and data from cache memory.

    Also if issue still exists, Please share your project.

    Regards,
    Anand Selvaraj.

  • Hi Anand Selvaraj,

    How do I share a project?

    Can you confirm the DMA xfer rate for the ADSP-21569 is 450 MB/sec.

     

    My project has  2 sets of coefficients and echo path buffers to transfer.

     

    #define AEC_COEF_SIZE_I8        102400  // size in 8-bit byte

    #define AEC_ECHOPATH_SIZE_I8    54008   // size in 8-bit byte

     

    Total 312,816 bytes.

     

    My program DMAs to and from L1 and SDRAM.

    The transfer is split into 4 separate DMA operations since 4 different memory locations are used.

    The expected xfer rate would be:

    312,816 / (48x1000000) = 0.006517 seconds

     

    I am seeing 174 MIPS = .69 seconds.

     

    Our target is less than half (80 MIPs) ~= .34 seconds.

     

    Something seems wrong with my numbers.

     

    This would make my actual DMA numbers off by a factor of 100.

     

    I am seeing 174 MIPs performing 4 sequential DMA transfers.

     

    I expected it to be half using 2 DMAs, instead it doubled.  There must be conflict with caching when 2 DMAs are actively accessing L1 and SDRAM?

     

    I want to straighten out the numbers.

     

    From all the documentation, examples and support that I have received the cache should be enabled:

     

    Instruction cache: 16KB

    PM cache: 64KB

    DM cache: 32KB

     

    These are the max cache values that can be set while running a small test progam.

     

    I would like to send the program for your review.

     

    * ADSP_21569_MDMA1.c
     *****************************************************************************/
    
    #include <sys/platform.h>
    #include "adi_initialize.h"
    #include "ADSP_21569_MDMA1.h"
    
    #include "stdio.h"
    #include <services/int/adi_int.h>
    
    
    void MDMA0_Write();
    void MDMA_Completion_ISR0();
    
    /*********************************************************************************
    
    Copyright(c) 2018 Analog Devices, Inc. All Rights Reserved.
    
    This software is proprietary and confidential.  By using this software you agree
    to the terms of the associated Analog Devices License Agreement.
    
    *********************************************************************************/
    /*!
     * @file      MemCopyArrayMode.c
     * @brief     Example to demonstrate memory copy using Array mode.
     * @version:  $Revision: 37126 $
     * @date:     $Date: 2018-10-10 11:20:31 +0530 (Wed, 10 Oct 2018) $
     *
     * @details
     *            This is the primary source file to demonstrate
     *            memory copy using DMA Array mode with Memory DMA manager APIs.
     *
     */
    
    /*=============  I N C L U D E S   =============*/
    
    /* Array mode Memory Copy example includes */
    #include "MemCopyArrayMode1.h"
    
    /* Managed drivers and/or services include */
    #include "adi_initialize.h"
    
    #include <sys/platform.h>
    #define AEC_COEF_SIZE_I8        102400  // size in 8-bit byte
    #define AEC_ECHOPATH_SIZE_I8    54008   // size in 8-bit byte
    
    #pragma section("seg_l1_block1")
    _Pragma("align 64")
    float Buffer_For_Coef_Ping[(AEC_COEF_SIZE_I8)/sizeof(float)];
    #pragma section("seg_l1_block3")
    _Pragma("align 64")
    float Buffer_For_Coef_Pong[(AEC_COEF_SIZE_I8)/sizeof(float)];
    #pragma section("seg_l1_block2")
    _Pragma("align 64")
    float Buffer_For_EchoPath_Ping[(AEC_ECHOPATH_SIZE_I8)/sizeof(float)];
    #pragma section("seg_l1_block1")
    _Pragma("align 64")
    float Buffer_For_EchoPath_Pong[(AEC_ECHOPATH_SIZE_I8)/sizeof(float)];
    
    #if !defined(ADI_CACHE_LINE_LENGTH)
    /* The ADI_CACHE_* macros were introduced in CCES 2.4.0 in <sys/platform.h>.
     * If using an older toolchain, define them here.
     */
     #if defined(__ADSPARM__)
      #define ADI_CACHE_LINE_LENGTH (32uL)
      #define ADI_CACHE_ALIGN_MIN_4 __attribute__((aligned(ADI_CACHE_LINE_LENGTH)))
     #elif defined(__ADSP215xx__)
      #define ADI_CACHE_LINE_LENGTH (64uL)
      #define ADI_CACHE_ALIGN_MIN_4 _Pragma("align 64")
     #else
      #error Unknown ADI_CACHE_LINE_LENGTH
     #endif
     #define ADI_CACHE_ROUND_UP_SIZE(size, type) \
        (((((((size) * sizeof(type)) \
               + (ADI_CACHE_LINE_LENGTH - 1uL)) \
              / ADI_CACHE_LINE_LENGTH) * ADI_CACHE_LINE_LENGTH) \
          + (sizeof(type) - 1uL)) / sizeof(type))
    #endif
    
    /*=============  LOCAL DEFINES   =============*/
    
    /* When the processor's L1 and/or L2 cache is enabled the receive data buffers must */
    /* be aligned on cache line boundaries. If they are not then any data access by the core may        */
    /* pull a buffer into the cache while the DMA is operating on the data buffer. Both the core and    */
    /* the DMA are masters on the bus. The core will be performing cache operations. The DMA engine will*/
    /* not be. So it is important for the application to both align data that will be operated on by the*/
    /* DMA and to separate this data from other application data.                                       */
    #if defined(__ICCARM__)
     #define SRCALIGN _Pragma("data_alignment=4")
     #define DSTALIGN _Pragma("data_alignment=32")
    #elif defined(__ADSPGCC__)
     #define DSTALIGN ADI_CACHE_ALIGN_MIN_4
     #define SRCALIGN __attribute__ ((aligned (4)))
    #else
     #define DSTALIGN ADI_CACHE_ALIGN_MIN_4
     #define SRCALIGN _Pragma("align 4")
    #endif
    
    /*=============  D A T A  =============*/
    
    
    
    /* Source and Destination channel data buffer.
     * Aligned at least to an MSIZE-byte boundary.
     */
    
    
    //static float Buffer_For_Coef[(0x0001fc00)/sizeof(float)];
    #pragma section("seg_ext_pmda")
    DSTALIGN static uint8_t CoefDataBuf[ADI_CACHE_ROUND_UP_SIZE(MEMCOPY_BYTES_ALLOC_PER_CHANNEL_DESC_COEF, uint8_t)];
    
    #pragma section("seg_ext_pmda")
    DSTALIGN static uint8_t EchoPathDataBuf[ADI_CACHE_ROUND_UP_SIZE(MEMCOPY_BYTES_ALLOC_PER_CHANNEL_DESC_ECHOPATH, uint8_t)];
    
    static uint8_t* CoefPingBuf;
    static uint8_t* CoefPongBuf;
    static uint8_t* EchoPathPingBuf;
    static uint8_t* EchoPathPongBuf;
    
    
    /*=============  L O C A L    F U N C T I O N S  =============*/
    
    /* Prepares data buffers for Memory DMA copy */
    static void PrepareDataBuffers (void);
    static void UpdateDataBuffers (void);
    
    typedef enum
    {
        ADI_DMA_SUCCESS = 0,                /*!< 0x00 - Generic success */
        ADI_DMA_FAILURE,                    /*!< 0x01 - Generic failure */
        ADI_DMA_IN_USE,                     /*!< 0x02 - Supplied DMA channel/stream ID is already open and in use */
        ADI_DMA_NOT_OPEN,                   /*!< 0x03 - Channel is not open to preform the requested task */
        ADI_DMA_ALREADY_RUNNING,            /*!< 0x04 - Function not permitted since DMA is already running */
        ADI_DMA_BAD_HANDLE,                 /*!< 0x05 - Bad channel/stream handle */
        ADI_DMA_BAD_STREAM_ID,              /*!< 0x06 - No such memory stream ID */
        ADI_DMA_BAD_MSIZE,                  /*!< 0x07 - Bad memory transfer size */
        ADI_DMA_BAD_PSIZE,                  /*!< 0x08 - Bad peripheral transfer size */
        ADI_DMA_BAD_XCOUNT,                 /*!< 0x09 - An invalid XCount value was supplied */
        ADI_DMA_BAD_YCOUNT,                 /*!< 0x0A - An invalid YCount value was supplied */
        ADI_DMA_BAD_START_ADDR,             /*!< 0x0B - Supplied start address in invalid */
        ADI_DMA_ADDR_ALIGNMENT_ERROR,       /*!< 0x0C - Start address alignment error */
        ADI_DMA_INT_REGISTER_FAILED,        /*!< 0x0D - Can't register an interrupt */
        ADI_DMA_INT_UNREGISTER_FAILED,      /*!< 0x0E - Can't unregister an interrupt */
        ADI_DMA_INVALID_NULL_POINTER,       /*!< 0x0F - Specified pointer is invalid and pointing to NULL. */
        ADI_DMA_NO_BUFFER_TO_PROCESS        /*!< 0x10 - Can't start DMA data transfer as there is no valid buffer to process */
    } ADI_DMA_RESULT;
    
    /* Verifies memory DMA copy by comparing destination data with source */
    static ADI_DMA_RESULT VerifyDataCopy (void);
    
    
    /*=============  C O D E  =============*/
    
    bool 				PingPong = 0;
    volatile uint32_t   Current_Channel = 0;
    
    
    unsigned long Applyatime, Applybtime;
    static float facc_time=0;
    static float avgtime = 0;
    
    static  uint8_t *pSourceAddress;
    static  uint8_t *pDestAddress;
    
    
    volatile int DMA_Completed0 = 0;
    volatile int DMA_Completed1 = 0;
    void MDMA0_Write(uint8_t * pReadAddress, uint8_t * pWriteAddress, uint32_t iXCount);
    void MDMA_Completion_ISR0(void);
    void MDMA1_Write(uint8_t * pReadAddress, uint8_t * pWriteAddress, uint32_t iXCount);
    void MDMA_Completion_ISR1(void);
    
    void MDMA0_Write(uint8_t * pReadAddress, uint8_t * pWriteAddress, uint32_t iXCount)
    {
    
        *pREG_DMA8_ADDRSTART = (uint32_t *)pReadAddress;		//Initialize start address
        *pREG_DMA8_XCNT      = iXCount/4;			//Initialize X count
        *pREG_DMA8_XMOD	  = 4;			//Initialize DMA X modifier
        *pREG_DMA8_YCNT	  = 0;			//Initialize Y count
        *pREG_DMA8_YMOD	  = 0;			//Initialize DMA Y modifier
    
        *pREG_DMA9_ADDRSTART = (uint32_t *)pWriteAddress;		//Initialize start address
        *pREG_DMA9_XCNT	  = iXCount/4;			//Initialize DMA X count
        *pREG_DMA9_XMOD	  = 4;			//Initialize DMA X modifier
        *pREG_DMA9_YCNT	  = 0;			//Initialize DMA Y count
        *pREG_DMA9_YMOD	  = 0;			//Initialize DMA Y modifier
    
        *pREG_DMA9_CFG 	  = ENUM_DMA_CFG_EN |  ENUM_DMA_CFG_PSIZE04 |ENUM_DMA_CFG_MSIZE04 |ENUM_DMA_CFG_WRITE | ENUM_DMA_CFG_XCNT_INT;		//Initialize DMA config register
        *pREG_DMA8_CFG    = ENUM_DMA_CFG_EN | ENUM_DMA_CFG_PSIZE04 |ENUM_DMA_CFG_MSIZE04;//Initialize DMA config register
    
    }
    
    void MDMA1_Write(uint8_t * pReadAddress, uint8_t * pWriteAddress, uint32_t iXCount)
    {
    
    
        // MDMA0 uses DMA channel 18 and 19 on GUL
    
        *pREG_DMA18_ADDRSTART = (uint32_t *)pReadAddress;		//Initialize start address
        *pREG_DMA18_XCNT      = iXCount/4;			//Initialize X count
        *pREG_DMA18_XMOD	  = 4;			//Initialize DMA X modifier
        *pREG_DMA18_YCNT	  = 0;			//Initialize Y count
        *pREG_DMA18_YMOD	  = 0;			//Initialize DMA Y modifier
    
        *pREG_DMA19_ADDRSTART = (uint32_t *)pWriteAddress;		//Initialize start address
        *pREG_DMA19_XCNT	  = iXCount/4;			//Initialize DMA X count
        *pREG_DMA19_XMOD	  = 4;			//Initialize DMA X modifier
        *pREG_DMA19_YCNT	  = 0;			//Initialize DMA Y count
        *pREG_DMA19_YMOD	  = 0;			//Initialize DMA Y modifier
    
        *pREG_DMA19_CFG 	  = ENUM_DMA_CFG_EN |  ENUM_DMA_CFG_PSIZE04 |ENUM_DMA_CFG_MSIZE04 |ENUM_DMA_CFG_WRITE | ENUM_DMA_CFG_XCNT_INT;		//Initialize DMA config register
        *pREG_DMA18_CFG    = ENUM_DMA_CFG_EN | ENUM_DMA_CFG_PSIZE04 |ENUM_DMA_CFG_MSIZE04;//Initialize DMA config register
    
    }
    
    #if 0
    void MDMA_Completion_ISR0(void)
    {
    	*pREG_DMA9_STAT |= 0x1;
    	if(DMA_Completed0 == 0)
    	{
    		if(PingPong == 0)
    		{
    			pSourceAddress   = &EchoPathPingBuf[0];
    		}
    		else
    		{
    			pSourceAddress   = &EchoPathPongBuf[0];
    		}
    		pDestAddress  = &EchoPathDataBuf[(Current_Channel) * MEMCOPY_BYTES_PER_CHANNEL_DESC_ECHOPATH];
    
    		MDMA0_Write((uint8_t *)((uint32_t)pSourceAddress|(uint32_t)0x28000000),(uint8_t *)((uint32_t)pDestAddress),MEMCOPY_BYTES_PER_CHANNEL_DESC_ECHOPATH);
    
    		DMA_Completed0 = 1;
    	}
    	else
    	{
    		DMA_Completed0 = 2;
    	}
    
    }
    #endif
    #if 1
    void MDMA_Completion_ISR0(void)
    {
    	*pREG_DMA9_STAT |= 0x1;
    	DMA_Completed0 = 1;
    }
    #endif
    
    #if 1
    void MDMA_Completion_ISR1(void)
    {
    	*pREG_DMA19_STAT |= 0x1;
    	DMA_Completed1 = 1;
    }
    #endif
    
    #if 0
    void MDMA_Completion_ISR1(void)
    {
    	*pREG_DMA19_STAT |= 0x1;
    	if(DMA_Completed1 == 0)
    	{
    		if((Current_Channel +2) < MEMCOPY_NUM_CHANNELS)
    		{
    			/* Load the next set of Coeficients from Ax +2 */
    			pSourceAddress  = &CoefDataBuf[(Current_Channel +2) * MEMCOPY_BYTES_PER_CHANNEL_DESC_COEF];
    		}
    		else if((Current_Channel +1) < MEMCOPY_NUM_CHANNELS)
    		{
    			/* Wrap. Load the next set of Coeficients from A1*/
    			pSourceAddress = &CoefDataBuf[0];
    
    		}
    		else
    		{
    			/* Wrap. Load the next set of Coeficients from A2*/
    			pSourceAddress = &CoefDataBuf[MEMCOPY_BYTES_PER_CHANNEL_DESC_COEF];
    		}
    
    		if(PingPong == 0)
    		{
    			pDestAddress   = &CoefPingBuf[0];
    		}
    		else
    		{
    			pDestAddress  = &CoefPongBuf[0];
    		}
    
    		MDMA1_Write((uint8_t *)((uint32_t)pSourceAddress),(uint8_t *)((uint32_t)pDestAddress|(uint32_t)0x28000000),MEMCOPY_BYTES_PER_CHANNEL_DESC_COEF);
    
    		DMA_Completed1 = 1;
    	}
    	else
    	{
    		DMA_Completed1 = 2;
    	}
    
    }
    #endif
    /*********************************************************************
    *
    *   Function:   DMAcopy
    *
    *********************************************************************/
    
    int DMAcopy()
    {
    
    	unsigned long time,max_time = 0, atime,btime;
    
        /* DMA Return code */
        ADI_DMA_RESULT      eResult = ADI_DMA_SUCCESS;
    
    	if(Current_Channel == (MEMCOPY_NUM_CHANNELS ))
    	{
    		Current_Channel = 0;
    	}
    #if 1
    	/* Verify data copy */
    	eResult = VerifyDataCopy ();
    
    	if (eResult != ADI_DMA_SUCCESS)
    	{
    		DBG_MSG("Data verification failed\n");
    		return(1);
    	}
    	/* Modify contents of Ping Pong buffers */
    
    	UpdateDataBuffers();
    
    	Applybtime = __builtin_emuclk();
    #endif
    	if(PingPong == 0)
    	{
    		pSourceAddress   = &CoefPingBuf[0];
    	}
    	else
    	{
    		pSourceAddress  = &CoefPongBuf[0];
    	}
    	pDestAddress   = &CoefDataBuf[(Current_Channel) * MEMCOPY_BYTES_PER_CHANNEL_DESC_COEF];
    	MDMA0_Write((uint8_t *)((uint32_t)pSourceAddress|(uint32_t)0x28000000),(uint8_t *)((uint32_t)pDestAddress),MEMCOPY_BYTES_PER_CHANNEL_DESC_COEF);
    	while(DMA_Completed0 == 0);
    	DMA_Completed0 = 0;
    #if 1
    	if(PingPong == 0)
    	{
    		pSourceAddress   = &EchoPathPingBuf[0];
    	}
    	else
    	{
    		pSourceAddress   = &EchoPathPongBuf[0];
    	}
    	pDestAddress  = &EchoPathDataBuf[(Current_Channel) * MEMCOPY_BYTES_PER_CHANNEL_DESC_ECHOPATH];
    
    	MDMA0_Write((uint8_t *)((uint32_t)pSourceAddress|(uint32_t)0x28000000),(uint8_t *)((uint32_t)pDestAddress),MEMCOPY_BYTES_PER_CHANNEL_DESC_ECHOPATH);
    	while(DMA_Completed0 == 0);
    	DMA_Completed0 = 0;
    #endif
    	if((Current_Channel +2) < MEMCOPY_NUM_CHANNELS)
    	{
    		/* Load the next set of Coeficients from Ax +2 */
    		pSourceAddress    = &EchoPathDataBuf[(Current_Channel +2) * MEMCOPY_BYTES_PER_CHANNEL_DESC_ECHOPATH];
    	}
    	else if((Current_Channel +1) < MEMCOPY_NUM_CHANNELS)
    	{
    		/* Wrap. Load the next set of Coeficients from A1*/
    		pSourceAddress    = &EchoPathDataBuf[0];
    
    	}
    	else
    	{
    		/* Wrap. Load the next set of Coeficients from A2*/
    		pSourceAddress    = &EchoPathDataBuf[MEMCOPY_BYTES_PER_CHANNEL_DESC_ECHOPATH];
    	}
    	if(PingPong == 0)
    	{
    		pDestAddress   = &EchoPathPingBuf[0];
    	}
    	else
    	{
    		pDestAddress   = &EchoPathPongBuf[0];
    	}
    
    	MDMA1_Write((uint8_t *)((uint32_t)pSourceAddress),(uint8_t *)((uint32_t)pDestAddress|(uint32_t)0x28000000),MEMCOPY_BYTES_PER_CHANNEL_DESC_ECHOPATH);
    	while(DMA_Completed1 == 0);
    	DMA_Completed1 = 0;
    
    #if 1
    	if((Current_Channel +2) < MEMCOPY_NUM_CHANNELS)
    	{
    		/* Load the next set of Coeficients from Ax +2 */
    		pSourceAddress  = &CoefDataBuf[(Current_Channel +2) * MEMCOPY_BYTES_PER_CHANNEL_DESC_COEF];
    	}
    	else if((Current_Channel +1) < MEMCOPY_NUM_CHANNELS)
    	{
    		/* Wrap. Load the next set of Coeficients from A1*/
    		pSourceAddress = &CoefDataBuf[0];
    
    	}
    	else
    	{
    		/* Wrap. Load the next set of Coeficients from A2*/
    		pSourceAddress = &CoefDataBuf[MEMCOPY_BYTES_PER_CHANNEL_DESC_COEF];
    	}
    
    	if(PingPong == 0)
    	{
    		pDestAddress   = &CoefPingBuf[0];
    	}
    	else
    	{
    		pDestAddress  = &CoefPongBuf[0];
    	}
    
    	MDMA1_Write((uint8_t *)((uint32_t)pSourceAddress),(uint8_t *)((uint32_t)pDestAddress|(uint32_t)0x28000000),MEMCOPY_BYTES_PER_CHANNEL_DESC_COEF);
    	while(DMA_Completed1 == 0);
    	DMA_Completed1 = 0;
    #endif
    
    	Applyatime = __builtin_emuclk();
    
    	Applyatime = Applyatime-Applybtime;
    
    	facc_time = (float)Applyatime;
    	avgtime = facc_time;
    
    
    	avgtime /= 1000000.;
    	printf("Time = %f seconds\n",avgtime);
    	avgtime *= 250;
    	printf("Mips  = %f\n",avgtime);
    
    	Current_Channel++;
    
    	PingPong ^= 1;
    
    	return 0;
    
    }
    
    
    int DMAinit(void)
    {
    	 /* Time-out counter to make sure the example exits */
    
    	unsigned long time, max_time = 0, atime,btime;
    	float facc_time=0;
    	/* DMA Return code */
    	ADI_DMA_RESULT      eResult = ADI_DMA_SUCCESS;
    
    
    	CoefPingBuf     = Buffer_For_Coef_Ping;
    	CoefPongBuf     = Buffer_For_Coef_Pong;
    	EchoPathPingBuf = Buffer_For_EchoPath_Ping;
    	EchoPathPongBuf = Buffer_For_EchoPath_Pong;
    
    	/* Prepare data buffers */
    
    	PrepareDataBuffers ();
    
    	adi_int_InstallHandler(INTR_SYS_MDMA1_DST,MDMA_Completion_ISR1,0,true);
    	adi_int_InstallHandler(INTR_SYS_MDMA0_DST,MDMA_Completion_ISR0,0,true);
    
    	//Configure MDMA0 Source and Destination channels as secure masters
    	*pREG_SPU0_SECUREP110 = BITM_SPU_SECUREP_MSEC;
    	*pREG_SPU0_SECUREP111 = BITM_SPU_SECUREP_MSEC;
    
    	//Configure MDMA1 Source and Destination channels as secure masters
    	*pREG_SPU0_SECUREP112 = BITM_SPU_SECUREP_MSEC;
    	*pREG_SPU0_SECUREP113 = BITM_SPU_SECUREP_MSEC;
    
    	return(0);
    }
    
    
    /*
     * Prepares data buffers for Memory DMA copy.
     *
     * Parameters
     *  None
     *
     * Returns
     *  None
     *
     */
    static void PrepareDataBuffers (void)
    {
        /* Loop variable */
        uint32_t    i;
    
    	/* Generate Source data, Clear destination buffer */
    	for (i = 0u; i < CHANNEL_MEMCOPY_BUF_SIZE_COEF; i++)
    	{
    		CoefDataBuf[i]  = (uint8_t)rand();
    	}
    	for (i = 0u; i < CHANNEL_MEMCOPY_BUF_SIZE_ECHOPATH; i++)
    	{
    		EchoPathDataBuf[i]  = (uint8_t)rand();
    	}
    	memcpy(CoefPingBuf, CoefDataBuf, MEMCOPY_BYTES_PER_CHANNEL_DESC_COEF);
    	memcpy(CoefPongBuf, CoefDataBuf+MEMCOPY_BYTES_PER_CHANNEL_DESC_COEF, MEMCOPY_BYTES_PER_CHANNEL_DESC_COEF);
    	memcpy(EchoPathPingBuf, EchoPathDataBuf, MEMCOPY_BYTES_PER_CHANNEL_DESC_ECHOPATH);
    	memcpy(EchoPathPongBuf, EchoPathDataBuf+MEMCOPY_BYTES_PER_CHANNEL_DESC_ECHOPATH, MEMCOPY_BYTES_PER_CHANNEL_DESC_ECHOPATH);
    }
    
    static void UpdateDataBuffers (void)
    {
    	/* Loop variable */
    	uint32_t    i;
    	if(PingPong == 0)
    	{
    		/* Generate Source data, Clear destination buffer */
    		for (i = 0u; i < MEMCOPY_BYTES_PER_CHANNEL_DESC_COEF; i++)
    		{
    			CoefPingBuf[i]  += 1;
    		}
    		for (i = 0u; i < MEMCOPY_BYTES_PER_CHANNEL_DESC_ECHOPATH; i++)
    		{
    			EchoPathPingBuf[i]  += 1;
    		}
    	}
    	else
    	{
    		for (i = 0u; i < MEMCOPY_BYTES_PER_CHANNEL_DESC_COEF; i++)
    		{
    			CoefPongBuf[i]  += 1;
    		}
    		for (i = 0u; i < MEMCOPY_BYTES_PER_CHANNEL_DESC_ECHOPATH; i++)
    		{
    			EchoPathPongBuf[i]  += 1;
    		}
    	}
    }
    /*
     * Verifies memory DMA copy by comparing destination data with source.
     *
     * Parameters
     *  None
     *
     * Returns
     *  - ADI_DMA_SUCCESS   - Data verification success
     *  - ADI_DMA_FAILURE   - Data verification failed
     *
     */
    static ADI_DMA_RESULT VerifyDataCopy (void)
    {
        /* Loop variable */
        uint32_t        i;
    
        /* Compare the destination data with source */
        for (i = 0u; i < MEMCOPY_BYTES_PER_CHANNEL_DESC_COEF; i++)
        {
        	if(PingPong == 0)
    		{
        		if (CoefPingBuf[i] != CoefDataBuf[(Current_Channel * MEMCOPY_BYTES_PER_CHANNEL_DESC_COEF) + i])
    			{
    				/* Return error */
        			DBG_MSG("Failed compare 1: Current_Channel\n", Current_Channel);
    				return ADI_DMA_FAILURE;
    			}
    		}
    		else
    		{
    			if (CoefPongBuf[i] != CoefDataBuf[(Current_Channel * MEMCOPY_BYTES_PER_CHANNEL_DESC_COEF) + i])
    			{
    				/* Return error */
    				DBG_MSG("Failed compare 2: Current_Channel\n", Current_Channel);
    				return ADI_DMA_FAILURE;
    			}
    		}
            /* IF (Destination data not same as source) */
    
        }
        for (i = 0u; i < MEMCOPY_BYTES_PER_CHANNEL_DESC_ECHOPATH; i++)
    	{
    		if(PingPong == 0)
    		{
    			if (EchoPathPingBuf[i] != EchoPathDataBuf[(Current_Channel * MEMCOPY_BYTES_PER_CHANNEL_DESC_ECHOPATH) + i])
    			{
    				/* Return error */
    				DBG_MSG("Failed compare 3: Current_Channel\n", Current_Channel);
    				return ADI_DMA_FAILURE;
    			}
    		}
    		else
    		{
    			if (EchoPathPongBuf[i] != EchoPathDataBuf[(Current_Channel * MEMCOPY_BYTES_PER_CHANNEL_DESC_ECHOPATH) + i])
    			{
    				/* Return error */
    				DBG_MSG("Failed compare 4: Current_Channel\n", Current_Channel);
    				return ADI_DMA_FAILURE;
    			}
    		}
    		/* IF (Destination data not same as source) */
    
    	}
        /* Return success */
        return (ADI_DMA_SUCCESS);
    }
    /*****/
    
    /*
    ** EOF
    */
    
    
    int main(int argc, char *argv[])
    {
    	/**
    	 * Initialize managed drivers and/or services that have been added to
    	 * the project.
    	 * @return zero on success
    	 */
    	adi_initComponents();
    
    	DMAinit();
    
    	while(1)
    	{
    		DMAcopy();
    	}
    
    	return 0;
    }
    
    
    review.

     

    Seems to be some fundamental issues that need to be resolved.

     

    -Steve

  • Hi Anand Selvaraj,

    I was able to verify  DMA transfers happen at the SCLK0 rate of 125MHz, or 1/8 of the core clock.  My DMA results confirm that they are running cached.  This being the case, investigating the use of multiple DMAs.   

    Adding a second DMA to the project and performing  2 DMAs together doubles the transfer time from when each DMA is performed sequentially.

    Is there a way to architect the 2 DMAs in order to realize an increased data transfer rate from SDRAM <-> L1.?

     

    -Steve

  • Hi Steve,

    Apologies for the delay

    For better optimization and performance we recommend to refer EE-412, Please find the Application note and associated code link below

    www.analog.com/.../ee412v02.pdf

    Associated code zip: www.analog.com/.../ee412v02.zip

    Regards,
    Anand Selvaraj.