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