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.

McASP and EDMA receive one wrong word when working on loopback mode

Device: Jacinto 5
I use McASP and EDMA to transmit and receive data.
McASP work on loopback mode for verify my EDMA and McASP's configuration.
When EDMA complete a transfer, I compare the received data with sended data.

At test A, when I find the received data and sended data are different I call function exit(-1).
At first EDMA transfer,I send data as below
0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10,
0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,
......
0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,0x80

I expect to receive data same as the send data.But I receive data as below
0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x6, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10,
0x11,0x12,0x13,0x14,0x15,0x16,0x16,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,
......
0x71,0x72,0x73,0x74,0x75,0x76,0x76,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,0x80.

I enable the McASP's error interrupt and set debug breaks in error interrupt isr.
But I do not found program run into error interrupt isr.So no McASP transmit underrun or
receive overrun have happened.

At test B,when I find the received data and sended data are different I do not call function exit(-
1).Becides the result in test A, I found many times of McASP DMA error and EDMA have only done 7
times.

McASP and EDMA's configuration and init code are in the attached files.

5270.mcaspTDMModeConfig.h



/******************************************************************************
* Includes
******************************************************************************/
#include <edma3_drv.h>
//#include <edma3ResMgrBios.h>
//#include <assert.h>

/** Needed for zeroing out the eDMA & SPI Driver Objects */
#include <std.h>
//#include <edma3ResMgr.h>
#include <gio.h>
#include <pal_osWait.h>
#include<bcache.h>

// user search path include files, new include style 
#ifdef SCONS
#include "McASP_Lib/public/inc/mcaspLib.h"
#include "McASP_Lib/tests/TDMMode/private/TIC674X/mcaspTDMModeConfig.h"
#include "RM_Mem/public/inc/RM_Mem.h"
#include "RM_EDMA/public/inc/RM_EDMA.h"
#include "Trace/public/inc/Trace.h"
#else
#include "mcaspLib.h"
#include "mcaspTDMModeConfig.h"
#include "RM_Mem.h"
#include "RM_EDMA.h"
#include "Trace.h"
#endif 


/******************************************************************************
* Defines
******************************************************************************/
#define TX_DIRECTION 1
#define RX_DIRECTION 1

#define PINGPONG_BUFFER_SIZE (4 * 64)

#define AIC1_SLAVE_ADDR     (0x1BU)
#define AIC2_SLAVE_ADDR     0x1A
#define I2C_OWN_ADDR        0x10u    /* Dummy address used for testing */
#define I2C_BUS_FREQ        10000u
#define I2C_INSTANCE_2      (2U)
#define IO_EXP_SLAVE_ADDR   (0x21U)

#define RM_MEM_SWITCH


/******************************************************************************
* Local prototype definitions (to satisfy Lint)
******************************************************************************/
uint32_t txCallBack(uint32_t msgSize, uint8_t * msg, void * param);
uint32_t rxCallBack(uint32_t msgSize, uint8_t * msg, void * param);
void mainTSK(void);

/******************************************************************************
* Globals
******************************************************************************/
static SEM_Handle xmtSemHandle = NULL;
static SEM_Handle rcvSemHandle = NULL;

uint8_t * currentTXBuffer;
uint8_t * currentRXBuffer;

PSP_Handle  hEdma = NULL;

GIO_Handle  hI2C0 = NULL, hI2C2 = NULL;

extern int EMIFB; //lint -esym(526, EMIFB)
extern int IRAM; //lint -esym(526, IRAM)

// ToDo: To be removed.
#define LOWER_BOUND 7000
#define UPPER_BOUND 7100
bool initFlag = FALSE;

// Memory section .mem is external
#ifndef RM_MEM_SWITCH
uint8_t rxPingBuffer[256]; 
#pragma DATA_ALIGN(rxPingBuffer, 256)
//#pragma DATA_SECTION(rxPingBuffer, ".mem")
#pragma DATA_SECTION(rxPingBuffer, ".external")

uint8_t rxPongBuffer[256]; 
#pragma DATA_ALIGN(rxPongBuffer, 256)
//#pragma DATA_SECTION(rxPongBuffer, ".mem")
#pragma DATA_SECTION(rxPongBuffer, ".external")

uint8_t txPingBuffer[256]; 
#pragma DATA_ALIGN(txPingBuffer, 256)
//#pragma DATA_SECTION(txPingBuffer, ".mem")
#pragma DATA_SECTION(txPingBuffer, ".external")

uint8_t txPongBuffer[256]; 
#pragma DATA_ALIGN(txPongBuffer, 256)
//#pragma DATA_SECTION(txPongBuffer, ".mem")
#pragma DATA_SECTION(txPongBuffer, ".external")

uint8_t txRefBuffer[256]; 
#pragma DATA_ALIGN(txRefBuffer, 256)
//#pragma DATA_SECTION(txPongBuffer, ".mem")
#pragma DATA_SECTION(txRefBuffer, ".external")

uint8_t rxDebugBuffer[256]; 
#pragma DATA_ALIGN(rxDebugBuffer, 256)
//#pragma DATA_SECTION(txPongBuffer, ".mem")
#pragma DATA_SECTION(rxDebugBuffer, ".external")
#endif

// Tx buffer first value
Int32 TxBufferFirstValue = 1;

uint32_t rxCallBack(uint32_t msgSize, uint8_t * msg, void * param)
{
   uint32_t status = MCASPLIB_OK;

   currentRXBuffer = msg;   
   
   SEM_post(rcvSemHandle);   
   
   return status;   
}


uint32_t txCallBack(uint32_t msgSize, uint8_t * msg, void * param)
{
   uint32_t status = MCASPLIB_OK;

   currentTXBuffer = msg;
  
   SEM_post(xmtSemHandle);   
   
   return status;   
}


volatile uint32_t edam_rx_cnt = 0;
void mainTSK(void)
{
   Int32 status     = MCASPLIB_OK;
   Int32 i;
   
   Int32* txBufferPoint = NULL;
   Int32* rxBufferPoint = NULL;
   MCASPHandle mcaspRxHandle;
   MCASPHandle mcaspTxHandle;
   MCASPChannelHandle xmtChannelHandle = NULL;
   MCASPChannelHandle rcvChannelHandle = NULL;

#ifdef RM_MEM_SWITCH
   Uint8* rxPingBuffer = NULL;
   Uint8* rxPongBuffer = NULL;   
   Uint8* txPingBuffer = NULL;
   Uint8* txPongBuffer = NULL;
   Uint8* txRefBuffer   = NULL;
   Uint8* rxDebugBuffer = NULL;

   status = RM_Mem(&IRAM, &EMIFB);
   assert(status == ePIAF_EOK);   

   // Buffer alignment of 128 is necessary to be cache aligned:
   rxPingBuffer = 
      (Uint8*)RM_Mem_alloc(sizeof(Uint32)*64, ePIAF_EXTERNAL, 256);
   rxPongBuffer = 
      (Uint8*)RM_Mem_alloc(sizeof(Uint32)*64, ePIAF_EXTERNAL, 256);

   txPingBuffer = 
      (Uint8*)RM_Mem_alloc(sizeof(Uint32)*64, ePIAF_EXTERNAL, 256);
   txPongBuffer = 
      (Uint8*)RM_Mem_alloc(sizeof(Uint32)*64, ePIAF_EXTERNAL, 256);

   txRefBuffer = 
      (Uint8*)RM_Mem_alloc(sizeof(Uint32)*64, ePIAF_EXTERNAL, 256);
   rxDebugBuffer = 
      (Uint8*)RM_Mem_alloc(sizeof(Uint32)*64, ePIAF_EXTERNAL, 256);
   
#endif
  
   xmtSemHandle = SEM_create(0, NULL);
   rcvSemHandle = SEM_create(0, NULL);
   
#if RX_DIRECTION    
   status = mcaspLib_create(&mcaspRxHandle, drvRxConfig.mcaspInstanceId, NULL);
   assert(status == MCASPLIB_OK);
#endif

#if TX_DIRECTION  
   //status = mcaspLib_create(&mcaspTxHandle, 2, NULL);
   //assert(status == MCASPLIB_OK);
#endif 
  
   status = RM_EDMA_init();
   assert(status == ePIAF_EOK);      
   hEdma = RM_EDMA_getHandle();

#if TX_DIRECTION    
   // Assign EDMA handle for TX driver
   //drvTxConfig.hEdma = hEdma;

   //status = mcaspLib_initialize(mcaspTxHandle, &drvTxConfig);
   //assert(status == MCASPLIB_OK);
#endif

#if RX_DIRECTION    
   // Assign EDMA handle for RX driver
   drvRxConfig.hEdma = hEdma;

   status = mcaspLib_initialize(mcaspRxHandle, &drvRxConfig);
   assert(status == MCASPLIB_OK);
#endif
   
#if TX_DIRECTION   
   // Assign ping-pong buffers for transmit channel
   xmtChannelConfig.tdmModeContext.bufferStartAddress[0] = txPongBuffer; 
   xmtChannelConfig.tdmModeContext.bufferStartAddress[1] = txPingBuffer; 
#endif 

#if RX_DIRECTION 
   // Assign ping-pong buffers for receive channel
   rcvChannelConfig.tdmModeContext.bufferStartAddress[0] = rxPingBuffer; 
   rcvChannelConfig.tdmModeContext.bufferStartAddress[1] = rxPongBuffer; 
#endif        

   // Clear TX\RX buffers
   rxBufferPoint = (Int32*) rxPingBuffer;
   for(i=0; i<64; i++)
	 rxBufferPoint[i] = 0x5a5a;
   txBufferPoint = (Int32*) txPingBuffer;
   for(i=0; i<64; i++)
   	txBufferPoint[i] = 0x7a7a;
   
   txBufferPoint = (Int32*) txPongBuffer;
   rxBufferPoint = (Int32*) rxPongBuffer;
   for(i=0; i<64; i++)
   {
	 txBufferPoint[i] = 0x5a5a;
	 rxBufferPoint[i] = 0x5a5a;
   }   
   // Init First TX buffer as [1,2,3,......,64]
   txBufferPoint = (Int32*) xmtChannelConfig.tdmModeContext.bufferStartAddress[0];
   rxBufferPoint = (Int32*) txRefBuffer;
   for(i=0; i<64; i++)
   {
	 //txBufferPoint[i] = TxBufferFirstValue;
	 //rxBufferPoint[i] = TxBufferFirstValue;
	 //TxBufferFirstValue ++;
	 
	 //txBufferPoint[i] = 0x2222 | (TxBufferFirstValue<<16);
	 //rxBufferPoint[i] = 0x2222 | (TxBufferFirstValue<<16);
	 //TxBufferFirstValue ++;

	 txBufferPoint[i] = ((TxBufferFirstValue+1)<<16) | TxBufferFirstValue;
	 rxBufferPoint[i] = ((TxBufferFirstValue+1)<<16) | TxBufferFirstValue;
	 TxBufferFirstValue += 2;
	 
   }

#if TX_DIRECTION   
   if(status == MCASPLIB_OK)
   {
      status = mcaspLib_registerChannel(mcaspRxHandle, //mcaspTxHandle,
                                        &xmtChannelConfig,
                                        NULL, 
                                        &xmtChannelHandle,
                                        txCallBack);
   }
#endif

#if RX_DIRECTION  
   if(status == MCASPLIB_OK)
   { 
      status = mcaspLib_registerChannel(mcaspRxHandle,
                                        &rcvChannelConfig,
                                        NULL, 
                                        &rcvChannelHandle,
                                        rxCallBack);
   }
#endif 



#if RX_DIRECTION
   if(status == MCASPLIB_OK)
   {
      status = mcaspLib_startChannel(rcvChannelHandle);
   }
#endif

#if TX_DIRECTION
   if(status == MCASPLIB_OK)
   {
      status = mcaspLib_startChannel(xmtChannelHandle);
   }
#endif
// Configuration ends here.



   while(1)
   {
         (void) SEM_pend(rcvSemHandle, SYS_FOREVER);
         (void) SEM_pend(xmtSemHandle, SYS_FOREVER);
	  	 
         BCACHE_inv(currentRXBuffer, PINGPONG_BUFFER_SIZE, TRUE);
         memcpy(rxDebugBuffer, currentRXBuffer, PINGPONG_BUFFER_SIZE);
         edam_rx_cnt ++;		 
	  BCACHE_wb(rxDebugBuffer, PINGPONG_BUFFER_SIZE, TRUE);	 

	  // Validate McBsp transfers
#if 0         
	  if(!memcmp(currentRXBuffer, txRefBuffer, 64 * 4 /*in bytes*/))
		printf("\nTEST PASSED\n");
	  else
	  {	
	      printf("\nTEST FAILED\n");
	      exit(-1);
	  }
#endif	  

	  // Update tx buffer data
	  txBufferPoint = (Int32*) currentTXBuffer;
         rxBufferPoint = (Int32*) txRefBuffer;
        for(i=0; i<64; i++)
        {
	 	 txBufferPoint[i] = ((TxBufferFirstValue+1)<<16) | TxBufferFirstValue;
	 	rxBufferPoint[i] = ((TxBufferFirstValue+1)<<16) | TxBufferFirstValue;
	 	TxBufferFirstValue += 2;
        }  
        BCACHE_wb(currentTXBuffer, PINGPONG_BUFFER_SIZE, TRUE);
   }
   
}