ΣSigmaStudio Ask AI Русский Log in

Caching seg_ext_dma for DMA

Processors & DSP SteveADT Aug 18, 2022 00:00 5 replies Original on forum ↗
Subscribe
SteveADT Question
Aug 18, 2022 00:00

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

ADSP-21569

Audio Signal Processors

software

Cross Core Embedded Studio version 2.9.4.0

SHARC Audio Processors/SoCs

Divya.P Reply
Aug 19, 2022 00:00

Hi Steve,

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

Regards,
Divya.P

ADIApproved Reply
Aug 23, 2022 00:00

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.

SteveADT Reply
Aug 25, 2022 00:00

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

SteveADT Reply
Aug 29, 2022 00:00

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

ADIApproved Reply
Aug 30, 2022 00:00

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.