Part Number: PROCESSOR-SDK-AM335X
Tool/software: TI-RTOS
System Setup:
GCC: gcc-arm-none-eabi-6-2017-q1-update
BIOS: bios_6_52_00_12
NDK: ndk_2_26_00_08
PDK: pdk_am335x_1_0_9
PSDK: processor_sdk_rtos_am335x_4_02_00_09
XDC: xdctools_3_50_03_33_core
Sitara: Sitara_1_02_00_00
EDMA: edma3_lld_2_12_05_30B
Question:
I am receiving spi data continuously at 13MHz with my beagle bone black as a slave via fifo and dma. Everything works fine for about 10 minutes. But then the FIFO data seems to get corrupted. For me it looks like a bitshift. I configured FIFORX to 16 because each transfer is 16 16bit values. I am not completely closing the spi and dma channel after each transaction to increase performance. I am just calling my SpiStartTransfer function in my DMA Callback routine to trigger the next transfer. Any hints why this fails after some minutes?
UPDATE_1: Reducing baudrate to 5MHz didn't change anything. Data is sent every 200us, so time between each transfer should be sufficient there. Reducing to 5MHz is only for testing purpose in real application I need it working at 13MHz, but a first step would be to get it working with lower requirements.
code extract:
static void SpiEdmaRxParamInit()
{
/* Fill the PaRAM Set with Receive specific information.*/
/* srcAddr holds address of SPI Rx FIFO.*/
rxParam.srcAddr = SOC_SPI_1_REGS + MCSPI_CHRX(0);
/* destAddr is address of memory location named buffer.*/
rxParam.destAddr = (unsigned int) rxPtr;
/* aCnt holds the number of bytes in an array.*/
rxParam.aCnt = 2;
/* bCnt holds the number of such arrays to be transferred.*/
rxParam.bCnt = FIFORX >> 1;
/* cCnt holds the number of frames of aCnt*bBcnt bytes to be transferred.*/
rxParam.cCnt = DATALENGTH / rxParam.bCnt;
/* The srcBidx should not be incremented since it is a h/w register.*/
rxParam.srcBIdx = 0;
/* The destBidx should be incremented for every byte.*/
rxParam.destBIdx = rxParam.aCnt;
/* A sync Transfer Mode. */
/* srCIdx and destCIdx set to zero since ASYNC Mode is used.*/
rxParam.srcCIdx = 0;
/*TODO: rxtrig or 0*/
rxParam.destCIdx = FIFORX;
/* Linking transfers in EDMA3 are not used.*/
rxParam.linkAddr = 0xFFFF;
rxParam.bCntReload = rxParam.bCnt;
rxParam.opt &= 0xFFFFFFFCU;
rxParam.opt &= 0xFFFFF8FFU;
rxParam.opt |= MCSPI_EDMA3CC_OPT_SYNC_AB;
rxParam.opt &= (~MCSPI_OPT_TCC_MASK);
/* Set TCC field in OPT with the tccNum.*/
rxParam.opt |= ((EDMA3_CHA_MCSPI1_CH0_RX << MCSPI_OPT_TCC_SHIFT)
& MCSPI_OPT_TCC_MASK);
/* EDMA3 Interrupt is enabled and Intermediate Interrupt Disabled.*/
rxParam.opt |= (1 << MCSPI_OPT_TCINTEN_SHIFT);
}
static void SpiStartTransfer()
{
McSPIWordCountSet(SOC_SPI_1_REGS, DATALENGTH);
/* Write Rx param set */
EDMA3_DRV_setPaRAM((EDMA3_DRV_Handle) rxEdmaHandle,
EDMA3_CHA_MCSPI1_CH0_RX,
&rxParam);
/* Program the RX side */
EDMA3_DRV_enableTransfer((EDMA3_DRV_Handle) rxEdmaHandle,
EDMA3_CHA_MCSPI1_CH0_RX,
EDMA3_DRV_TRIG_MODE_EVENT);
/* Enable McSPI DMA for transaction
* MCSPI_CH(chNum)CONF -> DMAR bit for receive DMA
*/
McSPIDMAEnable((uint32_t) (SOC_SPI_1_REGS), ((uint32_t) MCSPI_DMA_RX_EVENT),
MCSPI_CH_NUM);
/* Enable the channel */
McSPIChannelEnable((uint32_t) (SOC_SPI_1_REGS), MCSPI_CH_NUM);
}