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.

EDMA Problem with MSI mechanism of PCIe

Hello,

I am using 6678 DSP with EDMA and PCIe interfaces included.
In our application project, we are using EDMA(CSL version, not LLD) for fast data transfer over PCIe interface. I am transferring 1 MB of data each time using EDMA.
The EDMA part of software is divided into 3 functions: ConfigureDMA(), PerformDMATransfer(const void *srcBuff, void* dstBuff) and CloseDMA() which are included in EDMA.txt file attached. Please find it. And I am initializing DMA parameters as

instNum= 0;
regionNum= -1;
channelNum = 16;

I am using ConfigureDMA() function once for initializing, and then calling  PerformDMATransfer() in a seperate task periodically.

  1. My first problem is : I can not achieve data transfer after first time(First 1 MB transfer is achieved but then no transfer could completed). As long as I don't call ConfigureDMA()  in PerformDMATransfer() function, the transfer is not achived. Meaning that if I configure DMA everytime I call PerformDMA, then the transfer occurs. Do I have to configure DMA everytime I want to transfer data over it ? What may be the problem about this configuration process ? I think that I shall do it only once during initialization. 

Now I am using PerformDMATransfer() funciton with configuration process done every time.

According to the project requirements, I have to enable MSI.
But after enabling MSI, there had occurred a strange situation: EDMA stops working after a while.
I configured a Hardware Interrupt statically for deploying in the MSI mechanism. I had used interrupt vector 11 as input of MSI events and priority of 1 (I had used different interrupt vectors and priorities after I recognized the problem but nothing changed). Please find the attached cfg(edmaCFG.txt)  file which includes all the details about my configuration.

      2. After a couple of minutes(I am doing 1 MB of data transfer in every 150 ms), EDMA stops transferring data. It remains in the while loop of PerformDMATransfer()        function      and returns with timeout error. At first I thought that there may be some interrupt configuration error but if it is so, the transfer shouldn't have started at the beginning.  Do you have any idea about this problem ?

Regards,
Koray

int CPCIeModule::ConfigureDMA(void)
{
    /* Module initialization */
    if (CSL_edma3Init(&context) != CSL_SOK)
    {
        return PCIE_DMA_NOT_INITIALIZED;
    }

    /* Module level open */
    hModule = CSL_edma3Open(&edmaObj,instNum,NULL,&status);
    if ((hModule == NULL) || (status != CSL_SOK))
    {
        return PCIE_DMA_NOT_INITIALIZED;
    }

    /* Is this for GLOBAL or SHADOW Region */
    if (regionNum != CSL_EDMA3_REGION_GLOBAL)
    {
        /* Shadow Region: Enable DRAE enable(Bits 0-15) it. */
        regionAccess.region = regionNum;
        regionAccess.drae   = 0xFFFF;
        regionAccess.draeh  = 0x0000;
        if (CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_DMAREGION_ENABLE, &regionAccess) != CSL_SOK)
        {
             return PCIE_DMA_NOT_INITIALIZED;
        }

        /* Enable access for all QDMA channels in the SHADOW Region. */
        qraeSetup.region = regionNum;
        qraeSetup.qrae   = 0xFF;
        if (CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_QDMAREGION_ENABLE, &qraeSetup) != CSL_SOK)
        {
             return PCIE_DMA_NOT_INITIALIZED;
        }
    }

    /* QDMA Channel Open */
    chAttr.regionNum = regionNum;
    chAttr.chaNum    = channelNum;
    hChannel = CSL_edma3ChannelOpen(&chObj, instNum, &chAttr, &status);
    if ((hChannel == NULL) || (status != CSL_SOK))
    {
        return PCIE_DMA_NOT_INITIALIZED;
    }

    /* Map QDMA Channel to the PING Param Block i.e. 1 */
    CSL_edma3HwChannelSetupParam (hChannel, 1);

    /* Setup the trigger word for the QDMA Channel. */
    CSL_edma3HwChannelSetupTriggerWord(hChannel, 7);

    /* PING Parameter Entry Handle */
    hParamPing = CSL_edma3GetParamHandle(hChannel, 1, &status);
    if (hParamPing == NULL)
    {
        return PCIE_DMA_NOT_INITIALIZED;
    }

    /* Setup param entry */
    myParamSetup.option = CSL_EDMA3_OPT_MAKE(CSL_EDMA3_ITCCH_DIS, \
                                             CSL_EDMA3_TCCH_DIS, \
                                             CSL_EDMA3_ITCINT_DIS, \
                                             CSL_EDMA3_TCINT_EN,\
                                             0,CSL_EDMA3_TCC_NORMAL,\
                                             CSL_EDMA3_FIFOWIDTH_NONE, \
                                             CSL_EDMA3_STATIC_DIS, \
                                             CSL_EDMA3_SYNC_AB, \
                                             CSL_EDMA3_ADDRMODE_INCR, \
                                             CSL_EDMA3_ADDRMODE_INCR);
    myParamSetup.srcAddr    = (Uint32)NULL;
    myParamSetup.aCntbCnt   = CSL_EDMA3_CNT_MAKE(/*128*/ 128, PCIE_BUFFER_SIZE/128 /*2*/);
    myParamSetup.dstAddr    = (Uint32)NULL;
    myParamSetup.srcDstBidx = CSL_EDMA3_BIDX_MAKE(128, 128 /*0, 0*/);
    myParamSetup.linkBcntrld= CSL_EDMA3_LINKBCNTRLD_MAKE(/*hParamPing*/ CSL_EDMA3_LINK_NULL /*NULL*/, 0);
    myParamSetup.srcDstCidx = CSL_EDMA3_CIDX_MAKE(0,0);
    myParamSetup.cCnt       = 1;

   /* Enable Channel */
   if (CSL_edma3HwChannelControl(hChannel,CSL_EDMA3_CMD_CHANNEL_ENABLE, NULL) != CSL_SOK)
   {
       return PCIE_DMA_NOT_INITIALIZED;
   }

   return SUCCESS;
}


int CPCIeModule::PerformDMATransfer(const void *srcBuff, void *dstBuff)
{

   //debug
   this->ConfigureDMA();


   myParamSetup.srcAddr    = (Uint32)srcBuff;
   myParamSetup.dstAddr    = (Uint32)dstBuff;

   /* Setup PING to operate with this PARAM Entry. */
   if (CSL_edma3ParamSetup(hParamPing, &myParamSetup) != CSL_SOK)
   {
      return PCIE_DMA_TRANSFER_FAIL;
   }

   /* Trigger the word by writing to the trigger word... */
   if (CSL_edma3ParamWriteWord(hParamPing,7,1) != CSL_SOK)
   {
      return PCIE_DMA_TRANSFER_FAIL;
   }

   /* Poll IPR bit */
   regionIntr.region = regionNum;

   int iEnd = 0;
   int iStart = Clock_getTicks();

   do
   {
      CSL_edma3GetHwStatus(hModule,CSL_EDMA3_QUERY_INTRPEND,&regionIntr);

      iEnd = Clock_getTicks();
      if (PCIE_TIMEOUT_DMA_TRANSFER_CHECK < (iEnd - iStart))
      {
         return PCIE_DMA_TRANSFER_FAIL;
      }
   } while (!(regionIntr.intr & /*0x2*/0x1));

   /* Clear pending interrupt */
   if (CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_INTRPEND_CLEAR, &regionIntr) != CSL_SOK)
   {
      return PCIE_DMA_TRANSFER_FAIL;
   }

   return SUCCESS;
}

int CPCIeModule::CloseDMA(void)
{
   /* Disable the channel */
    CSL_edma3HwChannelControl(hChannel,CSL_EDMA3_CMD_CHANNEL_DISABLE, NULL);

    /* Close channel */
    if (CSL_edma3ChannelClose(hChannel) != CSL_SOK)
    {
        return PCIE_DMA_NOT_CLOSED;
    }

    /* Close EDMA module */
    if (CSL_edma3Close(hModule) != CSL_SOK)
    {
        return PCIE_DMA_NOT_CLOSED;
    }

    return SUCCESS;
}
/********************************************************************************************************************
*  Specify all needed RTSC Modules and configure them.																*
********************************************************************************************************************/

var Memory  =   xdc.useModule('xdc.runtime.Memory');

var BIOS    =   xdc.useModule('ti.sysbios.BIOS');
var List = xdc.useModule('ti.sdo.utils.List');
var MessageQ = xdc.useModule('ti.sdo.ipc.MessageQ');
var Main = xdc.useModule('xdc.runtime.Main');
var Idle = xdc.useModule('ti.sysbios.knl.Idle');
var Settings = xdc.useModule('ti.drv.pcie.Settings');

var EDMA3RM = xdc.loadPackage('ti.sdo.edma3.rm');
var EDMA3RMSample = xdc.loadPackage('ti.sdo.edma3.rm.sample');
var EDMA3Driver = xdc.loadPackage('ti.sdo.edma3.drv');
var EDMA3Sample = xdc.loadPackage('ti.sdo.edma3.drv.sample');
var ECM = xdc.useModule ('ti.sysbios.family.c64p.EventCombiner');
var Plib = xdc.loadPackage('ti.platform.evmc6678l');
var TCI66 = xdc.useModule('ti.sysbios.family.c66.tci66xx.CpIntc');


//added for EDMA integration
var Defaults = xdc.useModule('xdc.runtime.Defaults');			//
var Error = xdc.useModule('xdc.runtime.Error');					//
var LoggerBuf = xdc.useModule('xdc.runtime.LoggerBuf');			//
var SysMin = xdc.useModule('xdc.runtime.SysMin');				//
var Text = xdc.useModule('xdc.runtime.Text');					//
var HeapBuf = xdc.useModule('ti.sysbios.heaps.HeapBuf');		//
var Event = xdc.useModule('ti.sysbios.knl.Event');				//
var Cache = xdc.useModule('ti.sysbios.hal.Cache');				//

var loggerBufParams = new LoggerBuf.Params();			//
loggerBufParams.numEntries = 32;
var logger0 = LoggerBuf.create(loggerBufParams);
Defaults.common$.logger = logger0;
//Main.common$.diags_INFO = Diags.ALWAYS_ON;

//added for EDMA integration-end


/* Enable BIOS Task Scheduler */
BIOS.taskEnabled  =   true;

var Task    =   xdc.useModule('ti.sysbios.knl.Task');

/*
** Allow storing of task names. By default if you name a task with a friendly display name it will not be saved
** to conserve RAM. This must be set to true to allow it. We use friendly names on the Task List display.
*/
Task.common$.namedInstance = true;

var Clock   =   xdc.useModule ('ti.sysbios.knl.Clock');

/* 
** Interface with IPC. Depending on the version of BIOS you are using the 
** module name may have changed.
*/

/* Use this for BIOS 6.30 plus to get the IPC module */
var Sem	= xdc.useModule ('ti.sysbios.knl.Semaphore');

/* Hardware Interrupt  module */
var Hwi	= xdc.useModule ('ti.sysbios.hal.Hwi');

var Ecm = xdc.useModule ('ti.sysbios.family.c64p.EventCombiner');

/*
 * Enable Event Groups here and registering of ISR for specific GEM INTC is done
 * using EventCombiner_dispatchPlug() and Hwi_eventMap() APIs
 */
Ecm.eventGroupHwiNum[0] = 7;
Ecm.eventGroupHwiNum[1] = 8;
Ecm.eventGroupHwiNum[2] = 9;
Ecm.eventGroupHwiNum[3] = 10;


/*
* Diagnostic Module
*/
var Diags       = xdc.useModule('xdc.runtime.Diags');
var Exc = xdc.useModule('ti.sysbios.family.c64p.Exception');
Exc.enablePrint = true; /* prints exception details to the CCS console */

/*
**  Give the Load module it's own LoggerBuf to make sure the
**  events are not overwritten.
*/
/* var loggerBufParams = new LoggerBuf.Params();
loggerBufParams.exitFlush = true;
loggerBufParams.numEntries = 64;
Load.common$.logger = LoggerBuf.create(loggerBufParams); 
*/

/*
** Use this load to configure NDK 2.2 and above using RTSC. In previous versions of
** the NDK RTSC configuration was not supported and you should comment this out.
*/
var Global       = xdc.useModule('ti.ndk.config.Global');

/* 
** This allows the heart beat (poll function) to be created but does not generate the stack threads 
**
** Look in the cdoc (help files) to see what CfgAddEntry items can be configured. We tell it NOT
** to create any stack threads (services) as we configure those ourselves in our Main Task
** thread hpdspuaStart.
*/  
Global.enableCodeGeneration = false;


/* Define a variable to set the MAR mode for DDR2 as all cacheable */
/*FixUp - changed to C66*/
var Cache       =   xdc.useModule('ti.sysbios.family.c66.Cache');
/*FixUp*/ /*Cache.MAR224_255 = 0x0000000f;*/

var Startup     =   xdc.useModule('xdc.runtime.Startup');

var System      =   xdc.useModule('xdc.runtime.System');

/* Required if using System_printf to output on the console */
SysStd          		=   xdc.useModule('xdc.runtime.SysStd');
System.SupportProxy     =   SysStd;


/*
** Heap Management Module - Create a default Heap. 
*/
var HeapMem = xdc.useModule('ti.sysbios.heaps.HeapMem');
var heapMemParams = new HeapMem.Params();
heapMemParams.size = 4194304;
heapMemParams.sectionName = "systemHeap";
Program.global.heap0 = HeapMem.create(heapMemParams);
Memory.defaultHeapInstance = Program.global.heap0;

/* Load the CSL package  - LoadPackage is equivalent to linking the library */
var Csl 					    = 	xdc.loadPackage('ti.csl');

/* Load the CPPI package - LoadPackage is equivalent to linking the library */
var Cppi                        =   xdc.loadPackage('ti.drv.cppi'); 

/* Load the QMSS package  - LoadPackage is equivalent to linking the library*/
var Qmss                        =   xdc.loadPackage('ti.drv.qmss');

/* Load the PA package  - LoadPackage is equivalent to linking the library*/
var Pa 							= 	xdc.loadPackage('ti.drv.pa');

/* Load Platform Library - LoadPackage is equivalent to linking the library */
var Plib						= xdc.loadPackage('ti.platform.evmc6678l');

/* Load Platform Library - LoadPackage is equivalent to linking the library */
var Nimulib						= xdc.loadPackage('ti.transport.ndk');

/********************************************************************************************************************
* 	Define our Memory Map. We made up the  memory  names LL2RAM, DDR2 and SL2RAM. They do have special meaning.		*
*																													*
*	DDR - Anyhting destined for DDR always goes into the external RAM on the paltform.							*
*	L2SRAM - This is data that should be placed into the Local L2 of the core.										*
*	MCMSRAM - This is data that should go into the shared L2 (if it exists) or could be placed into LL2 if it doesnt.*
*																													*
*	These section names are mapped to specific addresses for a paltform using our custom memroy maps which are 		*
*	defined using the Platform Wizard. Examples are custom.hpdpsua.evm6678l, etc.,.									*
********************************************************************************************************************/

Program.sectMap[".vecs"] 		= {loadSegment: "L2SRAM", loadAlign:8};		/* CSL per core data structures 	*/
Program.sectMap[".switch"] 		= {loadSegment: "L2SRAM", loadAlign:8};		/* CSL per core data structures 	*/
Program.sectMap[".cio"]  		= {loadSegment: "L2SRAM", loadAlign:8};		/* per core data structures 		*/
Program.sectMap[".args"] 		= {loadSegment: "L2SRAM", loadAlign:8};		/* per core data structures 		*/
Program.sectMap[".cppi"] 		= {loadSegment: "L2SRAM", loadAlign:16};	/* per core data structures 		*/
Program.sectMap[".far:NDK_OBJMEM"]= {loadSegment: "L2SRAM", loadAlign:16}; 	/* NDK structures 					*/
Program.sectMap[".nimu_eth_ll2"]= {loadSegment: "L2SRAM", loadAlign:16};	/* per core data structures 		*/
Program.sectMap[".qmss"] 		= {loadSegment: "L2SRAM", loadAlign:16}; 	/* per core data structures 		*/
Program.sectMap[".resmgr_memregion"] = {loadSegment: "L2SRAM", loadAlign:128}; 	/* QMSS descriptors region 			*/
Program.sectMap[".resmgr_handles"] = {loadSegment: "L2SRAM", loadAlign:16};     /* CPPI/QMSS/PA Handles				*/
Program.sectMap[".resmgr_pa"]	= {loadSegment: "L2SRAM", loadAlign:8};		    /* PA Memory						*/
Program.sectMap[".stack"]		= "L2SRAM";

Program.sectMap[".bss"]			= "DDR3";									/* BSS. .neardata and .rodata are GROUPED */
Program.sectMap[".neardata"]	= "DDR3";
Program.sectMap[".rodata"]		= "DDR3";
Program.sectMap["systemHeap"] 	= {loadSegment: "DDR3", loadAlign:128};	  	/* XDC Heap .. eg Memory_alloc () 	*/
Program.sectMap[".far"] 		= "DDR3";
Program.sectMap[".cinit"] 		= "DDR3";
Program.sectMap[".const"]		= "DDR3";
Program.sectMap[".text"]		= "DDR3";
Program.sectMap[".code"]		= "DDR3";
Program.sectMap[".data"]		= "DDR3";
/* Program.sectMap[".sysmem"] 		= "DDR";								/* Malloc memory area 					*/	
Program.sectMap["platform_lib"]	= "DDR3";								/* Platform Library data structures 	*/
/* Program.sectMap[".gBuffer"]		= {loadSegment: "DDR", loadAlign:32};  	/* Upload buffer used by the Web Server	*/
/* Program.sectMap[".far:WEBDATA"]	= {loadSegment: "DDR", loadAlign: 32}; 	/* Web Pages and web server structures 	*/

Program.sectMap[".far:taskStackSection"]= "DDR3";								/* BIOS task stacks */	 
Program.sectMap[".far:NDK_PACKETMEM"]= {loadSegment: "MSMCSRAM", loadAlign: 128};	/* NDK Buffer Pool */

/********************************************************************************************************************
* Define hooks and static tasks  that will always be running.               										*
 ********************************************************************************************************************/

/* 
** Register an EVM Init handler with BIOS. This will initialize the hardware. BIOS calls before it starts. 
**
** If yuo are debugging with CCS, then this function will execute as CCS loads it if the option in your 
** Target Configuraiton file (.ccxml) has the option set to execute all code before Main. That is the 
** default.
*/

/* Because NDK is disabled via ethernetTask, no need to initialize EVM */

Startup.firstFxns.$add('&EVM_init');


/* Ethernet task is disable due to testing */

var StartEthernetParams = new Task.Params();
StartEthernetParams.instance.name = "ethernetTask";
StartEthernetParams.priority = 9;
Program.global.ethernetTask = Task.create("&StartEthernet", StartEthernetParams);
Global.netSchedulerPri = Global.NC_PRIORITY_HIGH;


var Log = xdc.useModule('xdc.runtime.Log');
var LogSnapShot = xdc.useModule('ti.uia.runtime.LogSnapshot');
//var Logger = xdc.useModule('ti.uia.runtime.LoggerCircBuf');
var Snapshot = xdc.useModule('ti.uia.events.UIASnapshot');


/*
** Load Module - Configure this to turn on the CPU Load Module for BIOS.
**
*/


var LoggingSetup = xdc.useModule('ti.uia.sysbios.LoggingSetup');
//LoggingSetup.mainLogging = true;
LoggingSetup.mainLoggerSize = 32768;
LoggingSetup.sysbiosTaskLogging = true;     // Task izlemek icin
LoggingSetup.sysbiosSwiLogging  = false;
LoggingSetup.sysbiosHwiLogging  = false;
LoggingSetup.sysbiosLoggerSize  = 32768;         // Set to e.g. 32768 if sysBiosTaskLogging = true
LoggingSetup.loadLogging = true;             // CPU Load izlemek icin true olmali, default true
LoggingSetup.loadLoggerSize = 32768;         // set to e.g. 32768 if loadLogging = true
LoggingSetup.eventUploadMode = LoggingSetup.UploadMode_JTAGRUNMODE;
LoggingSetup.disableMulticoreEventCorrelation = true;

var ServiceMgr = xdc.useModule('ti.uia.runtime.ServiceMgr');
ServiceMgr.topology = ServiceMgr.Topology_SINGLECORE;

Main.common$.diags_ENTRY = Diags.ALWAYS_ON;
Main.common$.diags_USER1 = Diags.ALWAYS_ON;
Main.common$.diags_EXIT = Diags.ALWAYS_ON;

// Process incoming commands task
var Task1Params = new Task.Params();
Task1Params.instance.name = "Task1";
Task1Params.priority = 4;
Program.global.Task1 = Task.create("&Task1Commands", Task1Params);

var Task2Params = new Task.Params();
Task2Params.instance.name = "Task2";
Task2Params.priority = 2;
Task2Params.stackSize = 20480;
Program.global.Task2 = Task.create("&Task2Cmds", Task2Params);


var Task3Params = new Task.Params();
Task3Params.instance.name = "Task3";
Task3Params.priority = 5;
Task3Params.stackSize = 4096;
Program.global.Task3 = Task.create("&Task3Cmds", Task3Params);

var Task4Params = new Task.Params();
Task4Params.instance.name = "Task4";
Task4Params.priority = 5;
Task4Params.stackSize = 4096;
Program.global.Task4 = Task.create("&Task4Cmds", Task4Params);

// PCIe Task
var tskHandle_PCIeModuleManageIQDataParams = new Task.Params();
tskHandle_PCIeModuleManageIQDataParams.instance.name = "tskHandle_PCIeModuleManageIQData";
tskHandle_PCIeModuleManageIQDataParams.stackSize = 4096;
tskHandle_PCIeModuleManageIQDataParams.priority = 3;
Program.global.tskHandle_PCIeModuleManageIQData = Task.create("&tskPCIeModuleManageIQData", tskHandle_PCIeModuleManageIQDataParams);



var Hwi_PCIe_MSIParams = new Hwi.Params();
Hwi_PCIe_MSIParams.instance.name = "Hwi_PCIe_MSI";
Hwi_PCIe_MSIParams.arg = 1;
Hwi_PCIe_MSIParams.enableInt = false;
Hwi_PCIe_MSIParams.eventId = 17;
Hwi_PCIe_MSIParams.priority = 1;
Program.global.Hwi_PCIe_MSI = Hwi.create(11, "&isr_Hwi_PCIe_MSI", Hwi_PCIe_MSIParams);

  • Koray,

    1. You are using QDMA channel and want to re-trigger the same channel repeatedly, then the "Static" field in the OPT of ParamSet should be set as "1" (enable static) instead of "0". Otherwise it will disable the further transfer on that channel. Please try the following changes in your source code and see if the issue could be resolved. Please refer to "Static" field in Table 2-3 and the second issue in Table A-1 (Debug List) for more details.

        myParamSetup.option = CSL_EDMA3_OPT_MAKE(CSL_EDMA3_ITCCH_DIS, \
                                                 CSL_EDMA3_TCCH_DIS, \
                                                 CSL_EDMA3_ITCINT_DIS, \
                                                 CSL_EDMA3_TCINT_EN,\
                                                 0,CSL_EDMA3_TCC_NORMAL,\
                                                 CSL_EDMA3_FIFOWIDTH_NONE, \
                                                 CSL_EDMA3_STATIC_EN,\
                                                 /*CSL_EDMA3_STATIC_DIS, \*/
                                                 CSL_EDMA3_SYNC_AB, \
                                                 CSL_EDMA3_ADDRMODE_INCR, \
                                                 CSL_EDMA3_ADDRMODE_INCR);

    2. I do not think the PCIe MSI interrupt will cause issue on QDMA transfer. Please fix the above issue first and try again to see if the #2 issue will be resolved as well.Thanks.

    Sincerely,

    Steven

  • Hi Steven,

    Your suggestion has resolved my problems. Now I don't configure EDMA everytime and it doesn't stop after a while.

    At first we took the example EDMA code under the folder "C:\Program Files (x86)\Texas Instruments\pdk_C6678_1_0_0_17\packages\ti\csl\example\edma" as reference. That's why we kept the static parameter as CSL_EDMA3_STATIC_DIS.

    Thanks and Regards,
    Koray.

     

     

     

  • Hi,

    I am trying to develop an identical setup to that described above with EDMA executing data transfers across a PCIe link controlled by MSI interrupts.

    I have tried to include the 3 methods posted above into my code which were adapted from the functions of the EDMA test code which was also mentioned.
    I have included the correction suggested although I am still struggling to run any transfer let alone repeat transfers.

    In response to my lack of success, I tried doing simpler basic block transfers from one array to another, as performed in the test code, but I haven't seen any evidence of srcBuff being transferred to dstBuff (src initialise to the array index and dst initialised to 0).

    I then went back to the edma test code. It ran an told me all test were successful. But when I started probing it to monitor srcBuff and dstBuff at various stages I found that all the checks passed because both buffers were all 0 when the checks were made.
    Therefore I am wondering whether it is my code that is wrong or whether there is some background setup beyond the ConfigureDMA, PerformDMATransfer and CloseDMA functions,such as in a config file, in a header or in main, that was implicit above but I need for any transfer to work?

    If this is not the case then please do say, so I know that would not be causing my problems.

    Although I am going to use MSI interrupts, testing of them is in a separate project to my EDMA testing and I am not using them yet in EDMA transfers across PCIe so their configuration is not relevant.

    Thanks

    Charles

  • Hi Charles,

    Are you using cache memory?
    If yes, try to writeback and invalidate all cache after doing EDMA transfers .

    Regards,
    Koray.

  • I am using the same setup as the test code which uses the following global buffers:

    Uint8 srcBuff1[512];
    Uint8 srcBuff2[512];
    Uint8 dstBuff1[512];
    Uint8 dstBuff2[512];

    I assume that the transfers would immediately update the buffers back into DDR.

    I would also assume any writeback and caching would have happened before the verify transfer method is called but I read out both buffers before the function call and dstBuff is still all 0 but srcBuf is set non-zero.

    I also read out srcArrayPtr[loopIndex3] and dstArrayPtr[loopIndex3] in the verify transfer method and both of these are zero at the point when they are compared.

    This what has provoked my concern.

    Charles

  • Okay, I have sorted the problem now.

    You were on the right lines and I found I had to include a writeback call when I initialised the buffers.

    Therefore the data would be in DDR rather than just in cache memory when the EDMA module came to do the transfer.

    I have also included some invalidation after the transfer itself just to make sure.

    Thanks for you help

    Charles