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