Other Parts Discussed in Thread: TMS320C6657
I have been trying to get the SPI + EDMA3 to work on the TMS320C6657 and I have been working off this form that is 2 years old. My issue is that my code seems to stop on a single lane the second time around when I try to transmit over the SPI peripheral. Below is the line of code that I am getting stuck at when I try to transmit something the second time. Is there some piece of code that I am missing that will allow me to transmit over the SPI more than once.
while(!(((CSL_SpiRegsOvly) CSL_SPI_REGS)->SPIFLG & 0x00000100)); <--- I get stuck here
/*
* ======== main.c ========
*/
#include <xdc/std.h>
#include <xdc/runtime/Error.h>
#include <xdc/runtime/System.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Clock.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/csl/tistdtypes.h>
#include <ti/csl/cslr_spi.h>
#include <ti/csl/soc.h>
#include <ti/csl/tistdtypes.h>
#include <ti/csl/csl_chip.h>
#include <ti/csl/csl_types.h>
#include <ti/csl/csl_edma3.h>
#include <ti/csl/csl_edma3Aux.h>
#include <stdio.h>
#include "spi_common.h"
#define TEST_ACNT 2
#define TEST_BCNT 1024
#define TEST_CCNT 1
#define TEST_SYCTYPE_AB 1
#define TEST_SYCTYPE_A 0
#define BUF_SIZE TEST_BCNT
#define BUF_NUM 5
#pragma DATA_SECTION(dstBuf, ".gem1_data")
#pragma DATA_ALIGN(dstBuf, 8)
Uint16 dstBuf[BUF_NUM][BUF_SIZE];
#pragma DATA_SECTION(srcBuf, ".gem0_data")
#pragma DATA_ALIGN(srcBuf, 8)
Uint16 srcBuf[BUF_NUM][BUF_SIZE];
CSL_Uint64 profileTxStart;
CSL_Uint64 profileTxStop;
CSL_Uint64 profileRxStart;
CSL_Uint64 profileRxStop;
CSL_Uint64 profileTx;
CSL_Uint64 profileRx;
Uint32 global_address (Uint32 addr)
{
Uint32 corenum;
corenum = CSL_chipReadReg(CSL_CHIP_DNUM);
addr = addr + (0x10000000 + corenum*0x1000000);
return addr;
}
void Enable_Edma_Channels(void)
{
// Trigger channel
CSL_edma3HwChannelControl(hChannel0,CSL_EDMA3_CMD_CHANNEL_ENABLE,NULL);
// Trigger channel
CSL_edma3HwChannelControl(hChannel1,CSL_EDMA3_CMD_CHANNEL_ENABLE,NULL);
}
void Setup_Edma_Init ()
{
// EDMA Module Initialization
CSL_edma3Init(NULL);
// EDMA Module Open
hModule = CSL_edma3Open(&moduleObj,CSL_TPCC_2,NULL,&EdmaStat);
// SPI Tx Channel Open - Channel 2 for Tx (SPIXEVT)
chParam.regionNum = CSL_EDMA3_REGION_GLOBAL;
chSetup.que = CSL_EDMA3_QUE_0;
chParam.chaNum = CSL_EDMA3_CHA_30;
//This might have to change to CSL_TPCC_2
hChannel0 = CSL_edma3ChannelOpen(&ChObj0, CSL_TPCC_2, &chParam, &EdmaStat);
chSetup.paramNum = chParam.chaNum; //CSL_EDMA3_CHA_30;
CSL_edma3HwChannelSetupParam(hChannel0,chSetup.paramNum);
// SPI Rx Channel Open - Channel 3 for Rx (SPIREVT)
chParam.regionNum = CSL_EDMA3_REGION_GLOBAL;
chSetup.que = CSL_EDMA3_QUE_0;
chParam.chaNum = CSL_EDMA3_CHA_31;
hChannel1 = CSL_edma3ChannelOpen(&ChObj1, CSL_TPCC_2, &chParam, &EdmaStat);
chSetup.paramNum = chParam.chaNum; //CSL_EDMA3_CHA_31;
CSL_edma3HwChannelSetupParam(hChannel1,chSetup.paramNum);
Enable_Edma_Channels();
}
void Setup_Edma_Params (Uint32 srcBuf, Uint32 dstBuf){
// Parameter Handle Open
// Open all the handles and keep them ready
paramHandle0 = CSL_edma3GetParamHandle(hChannel0,CSL_EDMA3_CHA_30,&EdmaStat);
paramHandle1 = CSL_edma3GetParamHandle(hChannel1,CSL_EDMA3_CHA_31,&EdmaStat);
paramSetup.aCntbCnt = CSL_EDMA3_CNT_MAKE(TEST_ACNT,(TEST_BCNT));
paramSetup.srcDstBidx = CSL_EDMA3_BIDX_MAKE(TEST_ACNT,0 );
paramSetup.srcDstCidx = CSL_EDMA3_CIDX_MAKE(0,0);
paramSetup.cCnt = TEST_CCNT;
paramSetup.option = CSL_EDMA3_OPT_MAKE(FALSE,FALSE,FALSE,TRUE,CSL_EDMA3_CHA_30,CSL_EDMA3_TCC_NORMAL, \
CSL_EDMA3_FIFOWIDTH_NONE,FALSE,CSL_EDMA3_SYNC_A,CSL_EDMA3_ADDRMODE_INCR,CSL_EDMA3_ADDRMODE_INCR);
if( ((Uint32)srcBuf & 0xFFF00000) == 0x00800000)
paramSetup.srcAddr = (Uint32)(global_address((Uint32)srcBuf));
else
paramSetup.srcAddr = (Uint32)(srcBuf);
#ifdef _BIG_ENDIAN
paramSetup.dstAddr = ((Uint32)&(((CSL_SpiRegsOvly) CSL_SPI_REGS)->SPIDAT0)) + (4-TEST_ACNT);
#else
paramSetup.dstAddr = (Uint32)&(((CSL_SpiRegsOvly) CSL_SPI_REGS)->SPIDAT0);
#endif
paramSetup.linkBcntrld = CSL_EDMA3_LINKBCNTRLD_MAKE(CSL_EDMA3_LINK_NULL,0);
CSL_edma3ParamSetup(paramHandle0,¶mSetup);
CSL_edma3ParamSetup(paramHandle0_reload,¶mSetup);
paramSetup.aCntbCnt = CSL_EDMA3_CNT_MAKE(TEST_ACNT,TEST_BCNT);
paramSetup.srcDstBidx = CSL_EDMA3_BIDX_MAKE(0,TEST_ACNT );
paramSetup.srcDstCidx = CSL_EDMA3_CIDX_MAKE(0,0);
paramSetup.cCnt = TEST_CCNT;
paramSetup.option = CSL_EDMA3_OPT_MAKE(FALSE,FALSE,FALSE,TRUE,CSL_EDMA3_CHA_31,CSL_EDMA3_TCC_NORMAL, \
CSL_EDMA3_FIFOWIDTH_NONE,FALSE,CSL_EDMA3_SYNC_A,CSL_EDMA3_ADDRMODE_INCR,CSL_EDMA3_ADDRMODE_INCR);
#ifdef _BIG_ENDIAN
paramSetup.srcAddr = ((Uint32)&(((CSL_SpiRegsOvly) CSL_SPI_REGS)->SPIBUF)) + (4 -TEST_ACNT);
#else
paramSetup.srcAddr = (Uint32)&(((CSL_SpiRegsOvly) CSL_SPI_REGS)->SPIBUF);
#endif
if( ((Uint32)dstBuf & 0xFFF00000) == 0x00800000)
paramSetup.dstAddr = (Uint32)(global_address((Uint32)dstBuf));
else
paramSetup.dstAddr = (Uint32)dstBuf;
paramSetup.linkBcntrld = CSL_EDMA3_LINKBCNTRLD_MAKE(CSL_EDMA3_LINK_NULL,0);
CSL_edma3ParamSetup(paramHandle1,¶mSetup);
CSL_edma3ParamSetup(paramHandle1_reload,¶mSetup);
}
void Test_Edma(void)
{
// Wait for interrupt
regionIpr.region = CSL_EDMA3_REGION_GLOBAL;
regionIpr.intr = 0;
regionIpr.intrh = 0;
do{
CSL_edma3GetHwStatus(hModule,CSL_EDMA3_QUERY_INTRPEND,®ionIpr);
}while ((regionIpr.intr & (1<<31)) != (1<<31)); //channel_31
//profileTxStop = CSL_tscRead();
do{
CSL_edma3GetHwStatus(hModule,CSL_EDMA3_QUERY_INTRPEND,®ionIpr);
}while ((regionIpr.intr & (1<<30)) != (1<<30)); //channel_30
//profileRxStop = CSL_tscRead();
/* Clear pending interrupt */
CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_INTRPEND_CLEAR, ®ionIpr);
}
void Close_Edma()
{
CSL_FINST(hModule->regs->TPCC_SECR,TPCC_TPCC_SECR_SECR2,RESETVAL);
CSL_FINST(hModule->regs->TPCC_SECR,TPCC_TPCC_SECR_SECR3,RESETVAL);
CSL_edma3ChannelClose(hChannel0);
CSL_edma3ChannelClose(hChannel1);
CSL_edma3Close(hModule);
}
void Initiate_Buffers(Uint16 aCnt, Uint16 bCnt, Uint16 cCnt, Int16 srcBIdx, Int16 dstBIdx, Int16 srcCIdx, Int16 dstCIdx,Uint32 srcBuff,Uint32 dstBuff, Bool abSync)
{
Uint8* srcArrayPtr = (Uint8*)srcBuff;
Uint8* dstArrayPtr = (Uint8*)dstBuff;
Uint8* srcFramePtr = (Uint8*)srcBuff;
Uint8* dstFramePtr = (Uint8*)dstBuff;
Uint8 cnt = 0;
int i,j,k;
for (i = 0; i < cCnt; i++)
{
for (j = 0; j < bCnt ;j++)
{
for (k = 0;k < aCnt;k++)
{
srcArrayPtr[k] = cnt++;
dstArrayPtr[k] = 0;
}
srcArrayPtr = srcArrayPtr + srcBIdx;
dstArrayPtr = dstArrayPtr + dstBIdx;
}
if (abSync) {
srcFramePtr = srcFramePtr + srcCIdx;
srcArrayPtr = srcFramePtr;
dstFramePtr = dstFramePtr + dstCIdx;
dstArrayPtr = dstFramePtr;
} else
{
srcFramePtr = srcArrayPtr + srcCIdx - srcBIdx;
srcArrayPtr = srcFramePtr;
dstFramePtr = dstArrayPtr + dstCIdx - dstBIdx;
dstArrayPtr = dstFramePtr;
}
}
}
void Setup_SPI_Init ()
{
//enable_spi();
/* Reset SPI */
((CSL_SpiRegsOvly) CSL_SPI_REGS)->SPIGCR0=
CSL_SPI_SPIGCR0_RESET_IN_RESET<<CSL_SPI_SPIGCR0_RESET_SHIFT;
/* Take SPI out of reset */
((CSL_SpiRegsOvly) CSL_SPI_REGS)->SPIGCR0=
CSL_SPI_SPIGCR0_RESET_OUT_OF_RESET<<CSL_SPI_SPIGCR0_RESET_SHIFT;
/* Configure SPI as master */
((CSL_SpiRegsOvly) CSL_SPI_REGS)->SPIGCR1=
CSL_SPI_SPIGCR1_CLKMOD_INTERNAL<<CSL_SPI_SPIGCR1_CLKMOD_SHIFT|
CSL_SPI_SPIGCR1_MASTER_MASTER<<CSL_SPI_SPIGCR1_MASTER_SHIFT;
/* Configure SPI in 4-pin SCS mode */
((CSL_SpiRegsOvly) CSL_SPI_REGS)->SPIPC0=
CSL_SPI_SPIPC0_SOMIFUN_SPI<<CSL_SPI_SPIPC0_SOMIFUN_SHIFT|
CSL_SPI_SPIPC0_SIMOFUN_SPI<<CSL_SPI_SPIPC0_SIMOFUN_SHIFT|
CSL_SPI_SPIPC0_CLKFUN_SPI<<CSL_SPI_SPIPC0_CLKFUN_SHIFT|
CSL_SPI_SPIPC0_SCS0FUN0_SPI<<CSL_SPI_SPIPC0_SCS0FUN0_SHIFT;
/* Put SPI in Lpbk mode*/
((CSL_SpiRegsOvly) CSL_SPI_REGS)->SPIGCR1 |=
CSL_SPI_SPIGCR1_LOOPBACK_ENABLE<<CSL_SPI_SPIGCR1_LOOPBACK_SHIFT;
/* Chose SPIFMT0 */
((CSL_SpiRegsOvly) CSL_SPI_REGS)->SPIDAT1=
CSL_SPI_SPIDAT1_DFSEL_FORMAT0<<CSL_SPI_SPIDAT1_DFSEL_SHIFT;
/* Configure add a delay,SHIFTDIR=MSB,POLARITY=HIGH,PHASE=IN,CHARLEN=16*/
((CSL_SpiRegsOvly) CSL_SPI_REGS)->SPIFMT[0]=
CSL_SPI_SPIFMT_WAITENA_DISABLE<<CSL_SPI_SPIFMT_WAITENA_SHIFT|
CSL_SPI_SPIFMT_SHIFTDIR_MSB<<CSL_SPI_SPIFMT_SHIFTDIR_SHIFT|
CSL_SPI_SPIFMT_POLARITY_LOW<<CSL_SPI_SPIFMT_POLARITY_SHIFT|
CSL_SPI_SPIFMT_PHASE_NO_DELAY<<CSL_SPI_SPIFMT_PHASE_SHIFT|
0x1<<CSL_SPI_SPIFMT_PRESCALE_SHIFT|
0x10<<CSL_SPI_SPIFMT_CHARLEN_SHIFT;
((CSL_SpiRegsOvly) CSL_SPI_REGS)->SPIINT0 =
CSL_SPI_SPIINT0_ENABLEHIGHZ_ENABLE<<CSL_SPI_SPIINT0_ENABLEHIGHZ_SHIFT|
CSL_SPI_SPIINT0_OVRNINTENA_ENABLE<<CSL_SPI_SPIINT0_OVRNINTENA_SHIFT|
CSL_SPI_SPIINT0_BITERRENA_ENABLE<<CSL_SPI_SPIINT0_BITERRENA_SHIFT|
CSL_SPI_SPIINT0_DESYNCENA_ENABLE<<CSL_SPI_SPIINT0_DESYNCENA_SHIFT|
CSL_SPI_SPIINT0_PARERRENA_ENABLE<<CSL_SPI_SPIINT0_PARERRENA_SHIFT|
CSL_SPI_SPIINT0_TIMEOUTENA_ENABLE<<CSL_SPI_SPIINT0_TIMEOUTENA_SHIFT|
CSL_SPI_SPIINT0_DLENERRENA_ENABLE<<CSL_SPI_SPIINT0_DLENERRENA_SHIFT;
}
void SPI_DMA_Request(void){
/* Enable communication */
((CSL_SpiRegsOvly) CSL_SPI_REGS)->SPIGCR1|=
CSL_SPI_SPIGCR1_ENABLE_ENABLE<<CSL_SPI_SPIGCR1_ENABLE_SHIFT;
((CSL_SpiRegsOvly) CSL_SPI_REGS)->SPIINT0 |=
CSL_SPI_SPIINT0_DMAREQEN_ENABLE<<CSL_SPI_SPIINT0_DMAREQEN_SHIFT;
while(!(((CSL_SpiRegsOvly) CSL_SPI_REGS)->SPIFLG & 0x00000200));
//profileTxStart = CSL_tscRead();
while(!(((CSL_SpiRegsOvly) CSL_SPI_REGS)->SPIFLG & 0x00000100));
//profileRxStart = CSL_tscRead();
((CSL_SpiRegsOvly) CSL_SPI_REGS)->SPIGCR1|=
CSL_SPI_SPIGCR1_ENABLE_DISABLE<<CSL_SPI_SPIGCR1_ENABLE_SHIFT;
((CSL_SpiRegsOvly) CSL_SPI_REGS)->SPIINT0 |=
CSL_SPI_SPIINT0_DMAREQEN_DISABLE<<CSL_SPI_SPIINT0_DMAREQEN_SHIFT;
}
Bool Verify_Transfer(Uint16 aCnt, Uint16 bCnt, Uint16 cCnt, Int16 srcBIdx, Int16 dstBIdx, Int16 srcCIdx, Int16 dstCIdx,Uint32 srcBuff,Uint32 dstBuff, Bool abSync)
{
Uint8* srcArrayPtr = (Uint8*)srcBuff;
Uint8* dstArrayPtr = (Uint8*)dstBuff;
Uint8* srcFramePtr = (Uint8*)srcBuff;
Uint8* dstFramePtr = (Uint8*)dstBuff;
int i,j,k;
for (i = 0; i < cCnt; i++)
{
for (j = 0; j < bCnt ;j++)
{
for (k = 0;k < aCnt;k++)
{
if (srcArrayPtr[k] != dstArrayPtr[k])
{
return FALSE;
}
}
srcArrayPtr = srcArrayPtr + srcBIdx;
dstArrayPtr = dstArrayPtr + dstBIdx;
}
if (abSync) {
srcFramePtr = srcFramePtr + srcCIdx;
srcArrayPtr = srcFramePtr;
dstFramePtr = dstFramePtr + dstCIdx;
dstArrayPtr = dstFramePtr;
} else
{
srcFramePtr = srcArrayPtr + srcCIdx - srcBIdx;
srcArrayPtr = srcFramePtr;
dstFramePtr = dstArrayPtr + dstCIdx - dstBIdx;
dstArrayPtr = dstFramePtr;
}
}
return TRUE;
}
/*
* ======== main ========
*/
Void main()
{
volatile Uint32 failFlag = FALSE;
int i = 0;
//Initiate src/dst buffers
for (i=0; i<BUF_NUM; i++)
{
Initiate_Buffers(TEST_ACNT,TEST_BCNT, TEST_CCNT,TEST_ACNT ,TEST_ACNT, TEST_ACNT*TEST_BCNT, TEST_ACNT*TEST_BCNT,(Uint32)srcBuf[i],(Uint32)dstBuf[i], CSL_EDMA3_SYNC_A);
}
//Initialize EDMA for SPI transfer
Setup_Edma_Init();
//Configure SPI in loopback mode and enable DMA interrupt support
Setup_SPI_Init();
//CSL_tscEnable();
for(i=0;i<BUF_NUM;i++){
//Enable EDMA for SPI transfer
Setup_Edma_Params((Uint32)srcBuf[i],(Uint32)dstBuf[i]);
//Enable SPI DMA Request
SPI_DMA_Request();
//Check EDMA transfer completion status
Test_Edma();
//Verify src/dst buffers after transfer
failFlag = Verify_Transfer(TEST_ACNT,TEST_BCNT, TEST_CCNT,TEST_ACNT ,TEST_ACNT, TEST_ACNT*TEST_BCNT, TEST_ACNT*TEST_BCNT,(Uint32)srcBuf[i],(Uint32)dstBuf[i], CSL_EDMA3_SYNC_A);
if (failFlag == TRUE){
System_printf("data verification passed\n");
}
else
System_printf("data verification failed\n");
}
System_printf("end of test\n");
BIOS_exit(0);
//BIOS_start(); /* enable interrupts and start SYS/BIOS */
}