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

Other Parts Discussed in Thread: TMS320DM8148

(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.



/******************************************************************************
* 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);
   }
   
}


1108.mcaspTDMModeConfig.h

  • Qiu Hong,

    I do not know which device is the one you named. Names like that are usually pre-lease when information is under NDA and should not be used in public. Please find the correct device name and edit your post above.

    I do not see any differences in your Tx and Rx data.

    Please check the errata of your device to determine if there are cautions for the target memory for McASP transfers.

    What else are you doing with EDMA channels?
    Which TC are you using for the McASP transfers?
    What else uses that same TC?

    Qiu Hong said:
    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.

    For test B, what do you do instead of calling exit(-1)?

    Regards,
    RandyP

  • First thank you for your reply.

    For device name, I select target name as TI814 in CCS 4.0.

    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,  0xe,  0x10,
    0x11,0x12,0x13,0x14,0x15,0x16,0x16,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1e,0x20,
    ......
    0x71,0x72,0x73,0x74,0x75,0x76,0x76,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7e,0x80.

    For difference of Tx and Rx, see red digital above. It is regular that the seventh digital is wrong every 8 digital.

    And the wrong num is same with the sixth digital num.

    EDMA are only used for McASP Tx and Rx.

    I use TC0 for Tx and Rx.

    For test B, I  comment the code call exit(-1). So McASP Tx and Rx should  run for forever.



  • Qiu Hong,

    I do not have CCSv4 installed anymore, and in CCSv5 I see TI814x but not TI814. Did you leave off the "x" or is this something else that we do not have in CCSv5? Even if you left off the "x", that is not a device part number. Do you know the device part number that you are using on the board? If the device is a DM8148 or a derivative in the DM814x family,  there is another E2E forum for that device family.

    In you first post, the 0xe/0x1e/0x7e do not repeat. Does this happen intermittently or does it happen differently each time you run it?

    Have you directly looked at the McASP Rx and Tx status registers to see if the overrun bit is set? The data you show above would indicate a Tx underrun, whereas a pattern of 0x6, 0x8, 0x8 would more likely indicate a receive overrun.

    Slow down the McASP clock and see if the error continues.

    How fast are you running the McASP?

    How fast is the rest of the device running?

    What else is running on the device?

    What speed and width and type is your external memory interface?

    Are you using external memory to transfer from for Tx and transfer to for Rx? If so, try moving the target memory location to internal memory such as L2 RAM (not cache) or other internal memory if your device has it.

    Regards,
    RandyP

  • Hi,

    1. I select TI814X in CCS4. And the device is DRA64X. I do not know more detailed number.

    2. In my first post, I forgot to change value of 0xe/0x1e/0x7e. The second post is correct. You can see that the error is very regular.

    3. I have open error interrupt of McASP. I do not find any error interrupt.

    4. I have slow down clock  by 4 times, but it still fail.

    5. I try to change EDMA's ping-pong buffer from external memory to internal memory. Then I find the EDMA's receive buffer's content do not change, as if EDMA do not work.

       But the callback function of EDMA  Transfer Complete is called many times. I checked the ping-pong buffer address, the address is in  internal L2 RAM. I have got the datasheet of

      the device by now. What reason can  cause this phenomenon?

    6. My McASP work on TDM mode, the frame sync is 44,1khz, the clock is 44.1khz*32, the slot size is 16bit, and slot number is 2. For every transfer(or frame), the Tx and Rx EDMA  move data of 128*16bit.

    7. The program is just do a McASP-EDMA test, so the DSP only do sending data by one channel of EDMA and reveiving data by another channel of EDMA.

    8. I have not get information about speed and width of  external memory interface. How to get this information?

    9. As you know, I send data as 0x01, 0x02,0x03,......, and expect to receive data as 0x01, 0x02,0x03,.......  For the first data in each frame of Rx EDMA, I expect to receive data as

       0x01,0x81,0x101,..... But yesterday I print out the first data in each frame of Rx EDMA, and I receive data as 0x9ffed, 0x56df, 0x01, 0x101, 0x181,0x201,0x281, 0x81,0x301,........ The first two data is wrong, the reason may be transfer is unstable at begin.  The weird phenomenon is that the received data 0x81 is in wrong order. I know the EDMA receive only have two buffer(ping buffer and pong buffer) .It is as if EDMA have some buffers to store received frames and send one frame to ping-pong buffer. Is there other buffers in EDMA internal processing?

  • Hello,

    1. The DRA64X is a special part number family that probably is not supported on the forum, but instead you may have access to an FAE or factory apps who can help you better than I can. I am not familiar with the DRA64X. But I am not trying to stop helping in what small way I can, so please download the datasheet for the TMS320DM8148 and see if the memory map summary is the same or close to that of your device. That will at least give us a common point to discuss this further. You should also try finding the other support people from TI who might be able to help you with this, or we may need to move this thread to the DM814x Forum. If you prefer we move it to that forum, let me know and I will make that request.

    Get the errata document for the DRA64X and see if there is anything in it about the loopback mode having issues.

    3. In your program in the EDMA callback function, please read the Rx and Tx status registers for a few of the buffers to see directly what the status registers indicate. The error interrupts are indirect tools to observe these bits, and reading them is a more direct way. And it avoids having to also debug the interrupt configuration to see if there is another problem with that. I prefer to reduce the number of variables, especially when trying to debug remotely like this.

    4. You have slowed down the McASP clock so the frame sync is 11kHz and still have the errors? Is that correct? If I understand this correctly, that is very different and unexpected. This means something completely different than I was thinking. Can you run the test using the actual pins and do an external connection to form the loopback instead of using the internal loopback mode? This would allow you to look at the data on an oscilloscope to compare the actual pin data with what you try to transmit and what you actually receive.

    5. Without knowing more about your device, I will just speculate that you are using the local L2 address that starts like 0x0080xxxx when you should be using the Global L2 address that starts like 0x1080xxxx. The right value for the Global L2 address will be shown in the datasheet's memory map summary.

    8. Usually, there will be a GEL script that runs automatically in CCS or that you manually run each time you connect to the board. Or if the DRA64X has an ARM core that is the master, it may be loading and running code that does the initialization, such as in the uboot process. For a start, please go to the TI Wiki Pages and search for "dsp clock speed" (no quotes); this will find the article "What is my DSP clock speed" which has a small app you can load and run on your DSP to measure the clock speed. I am assuming that your DSP is the C64x+ core. We can at least find out the speed your DSP is running. I will try to get something to you to determine your memory speed, but you will have to look at the schematic to determine the memory width. Someone should be able to tell you all of these parameters, though.

    9. If your failure signature is changing, it may be impossible to debug this with you remotely and you will need to try other boards to see if it is a manufacturing problem. I am not sure how to help if things keep moving around. This implies some major board or environment problem. The McASP is not going to be this erratic. Please look carefully at every word of your initialization settings and compare these with the initialization procedure in the McASP User's Guide or Technical Reference Manual that was supplied for this device.

    There are no EDMA buffers that could change the order of data.

    Regards,
    RandyP