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.

EDMA3 Peripheral Example?

Are there any examples using the CSL to setup and use the EDMA3 to setup a peripheral (like SPI, TWI, or UART) on a keystone multicore device?  I currently have tried setting it up for the 6670, but am not quite sure what is wrong. 

CSL_Edma3Handle hModule;
CSL_Edma3ParamHandle paramHandle0;
CSL_Edma3ParamHandle paramHandle1;
CSL_Edma3ChannelAttr chParam;
CSL_Edma3ChannelObj ChObj0,ChObj1;
CSL_Edma3ChannelHandle hChannel0,hChannel1;
CSL_Edma3HwDmaChannelSetup chSetup;
CSL_Edma3ParamSetup paramSetup;
CSL_Edma3Obj moduleObj;
CSL_Edma3CmdIntr regionIntr;
CSL_Edma3ChannelErr chErrClear;
CSL_Status EdmaStat;

#define TEST_ACNT 4
#define TEST_BCNT 16
#define TEST_CCNT 1

bool ti_spi_edma_transfer(void *src, void *dest, uint32 transLen) {
int i;

// Module Initialization
CSL_edma3Init(NULL);

// Module Open
hModule = CSL_edma3Open(&moduleObj,2,NULL,&EdmaStat);

// Channel Open
chParam.regionNum = CSL_EDMA3_REGION_GLOBAL;
chSetup.que = CSL_EDMA3_QUE_0;
chParam.chaNum = CSL_TPCC2_SPIXEVT;
hChannel0 = CSL_edma3ChannelOpen(&ChObj0,
2,
&chParam,
&EdmaStat);

// Channel Setup
chSetup.paramNum = CSL_TPCC2_SPIXEVT;
CSL_edma3HwChannelSetupQue(hChannel0,chSetup.que);
CSL_edma3HwChannelSetupParam(hChannel0,chSetup.paramNum);

chParam.regionNum = CSL_EDMA3_REGION_GLOBAL;
chSetup.que = CSL_EDMA3_QUE_0;
chParam.chaNum = CSL_TPCC2_SPIREVT;
hChannel1 = CSL_edma3ChannelOpen(&ChObj1,
2,
&chParam,
&EdmaStat);

// Channel Setup
chSetup.paramNum = CSL_TPCC2_SPIREVT;
CSL_edma3HwChannelSetupQue(hChannel1,chSetup.que);
CSL_edma3HwChannelSetupParam(hChannel1,chSetup.paramNum);

// Parameter Handle Open
// Open all the handles and keep them ready
paramHandle0 = CSL_edma3GetParamHandle(hChannel0,CSL_TPCC2_SPIXEVT,NULL);
paramHandle1 = CSL_edma3GetParamHandle(hChannel1,CSL_TPCC2_SPIREVT,NULL);

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,TRUE,FALSE,TRUE,
CSL_TPCC2_SPIXEVT,
CSL_EDMA3_TCC_NORMAL,
CSL_EDMA3_FIFOWIDTH_NONE,
FALSE, CSL_EDMA3_SYNC_A,
CSL_EDMA3_ADDRMODE_INCR,
CSL_EDMA3_ADDRMODE_INCR);
paramSetup.srcAddr = (Uint32)src;
paramSetup.dstAddr = (Uint32)&(SPI_REGS->SPIDAT1);
paramSetup.linkBcntrld = CSL_EDMA3_LINKBCNTRLD_MAKE(CSL_EDMA3_LINK_NULL,0);

CSL_edma3ParamSetup(paramHandle0,&paramSetup);

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,TRUE,FALSE,TRUE,
CSL_TPCC2_SPIREVT,
CSL_EDMA3_TCC_NORMAL,
CSL_EDMA3_FIFOWIDTH_NONE,
FALSE, CSL_EDMA3_SYNC_A,
CSL_EDMA3_ADDRMODE_INCR,
CSL_EDMA3_ADDRMODE_INCR);
paramSetup.srcAddr = (Uint32)&(SPI_REGS->SPIBUF);
paramSetup.dstAddr = (Uint32)dest;
paramSetup.linkBcntrld = CSL_EDMA3_LINKBCNTRLD_MAKE(CSL_EDMA3_LINK_NULL,0);

CSL_edma3ParamSetup(paramHandle1,&paramSetup);

/* clear the EDMA error registers */
chErrClear.missed = TRUE;
chErrClear.secEvt = TRUE;
CSL_edma3HwChannelControl (hChannel0, CSL_EDMA3_CMD_CHANNEL_DISABLE, NULL);
CSL_edma3HwChannelControl (hChannel1, CSL_EDMA3_CMD_CHANNEL_DISABLE, NULL);
CSL_edma3HwChannelControl (hChannel0, CSL_EDMA3_CMD_CHANNEL_CLEARERR,
&chErrClear);
CSL_edma3HwChannelControl (hChannel1, CSL_EDMA3_CMD_CHANNEL_CLEARERR,
&chErrClear);
CSL_edma3HwChannelControl (hChannel0, CSL_EDMA3_CMD_CHANNEL_CLEAR, NULL);
CSL_edma3HwChannelControl (hChannel1, CSL_EDMA3_CMD_CHANNEL_CLEAR, NULL);


// Trigger channel
CSL_edma3HwChannelControl(hChannel0,CSL_EDMA3_CMD_CHANNEL_ENABLE,NULL);
// Trigger channel
CSL_edma3HwChannelControl(hChannel1,CSL_EDMA3_CMD_CHANNEL_ENABLE,NULL);



/* Start I2C */
SPI_REGS->SPIDAT1 |= (1 << 28); // Hold CS Line
SPI_REGS->SPIGCR1 |= (1 << 24); // SPI enable bit (should only be set to 1 when ready to enable)

// Wait for interrupt
regionIntr.region = CSL_EDMA3_REGION_GLOBAL;
regionIntr.intr = 0;
regionIntr.intrh = 0;

do{
CSL_edma3GetHwStatus(hModule,CSL_EDMA3_QUERY_INTRPEND,&regionIntr);
for(i=0; i < 1000; i++) asm("nop");
}while (!(regionIntr.intr & 0xC000));// channel 30 & 31


/* Stop the transmission */
SPI_REGS->SPIGCR1 &= ~(1 << 24); // SPI enable bit (should only be set to 1 when ready to enable)
SPI_REGS->SPIDAT1 &= ~(1 << 28); // Hold CS Line

/* close instance of EDMA */
CSL_edma3ChannelClose(hChannel0);
CSL_edma3ChannelClose(hChannel1);
CSL_edma3Close(hModule);
}


  • Here's a little more info as to what I'm actually having issues with:

    I’ve actually gotten the edma working for memory to memory transfers (DDR3 <-> L2, DDR3 <-> DDR3, etc.) using the example for the 6678 in the pdk w/o any issues.   I have tried to use the evm6474 i2c edma example for the 6474 to work on the 6670, however there seems to be slight differences (the code in my previous post is my attempt to adapt the 6474 code to the 6670).  The main issue I think I am having is how to determine which set of edma channels I am actually setting up.  Off of the 6670 datasheet, there are event target channels for tpcc1 and tpcc2 that correspond to using the SPI, however, I couldn’t find any documentation on where I am actually setting up which tpcc (0, 1, or 2) and triggering the actual transfer.

    I have looked at sprugs5a section 3.4, however it only really shows the parameter block setup.

    Any help on this would be greatly appreciated, thanks!

  • Ok, after stepping through the code, it looks like setting the dma instance in the csl to 2 (like I had been doing in my code) was the right way for it to setup the dma for tpcc2.  It still doesn't quite seem to be working right yet though/

    Another question I had was is there a difference when setting up for the SPI to use the dma for using TPCC2  channels 30 and 31 vs using TPCC1 and channels 2 and 3.  They both are for the SPIXEVT/SPIREVT events, so I'm not quite sure what the difference in the 2 are.

  • Erick, can you clarify what you mean by "doesn't seem to be working right yet"? Details would be helpful.

    The C6678 gives the user the flexibility to map SPI events to either EDMACC1 or 2. The two sets of SPI events behave exactly the same. You may have already done this but I did not find it in your post - Did you enable DMA requests for SPI module by setting DMAREQEN to 1 in the SPINT0 register?

  • Aditya,

    Thanks for your response "doesn't seem to be working right yet" means I don't see data going out of the spi, or data coming in from the spi.  And it gets stuck in the loop (in my function from my first post):

    	do{
    CSL_edma3GetHwStatus(hModule,CSL_EDMA3_QUERY_INTRPEND,&regionIntr);
    for(i=0; i < 1000; i++) asm("nop");
    }while (!(regionIntr.intr & 0xC000));// channel 30 & 31

    Yes I do enable DMAREQEN in SPIINT0: here is my setup fucntion which I call before trying to do the dma transfer (SPI_REGS is defined as ((CSL_SpiRegs *)CSL_SPI_BASE))

    void spi_setup(void) {
    uint i;

    debug_spi_printf("SPI Initialization\n");

    SPI_REGS->SPIGCR0 = (0 << 0); // Reset SPI
    SPI_REGS->SPIGCR0 = (1 << 0); // Take SPI out of reset
    // SPI Global Control Register 1
    SPI_REGS->SPIGCR1 =
    (0 << 24) | // SPI enable bit (should only be set to 1 when ready to enable)
    (0 << 16) | // Loop back Mode Disabled
    (0 << 8) | // SPI is active (0)
    (3 << 0); // Master Mode
    // SPI Interrupt Register
    SPI_REGS->SPIINT0 =
    (1 << 16) | // SPI DMA Request enable
    (0 << 9) | // SPI TX Interrupt
    (0 << 8) | // SPI RX Interrupt
    (0 << 6) | // SPI Overrun Interrupt
    (0 << 4); // SPI Bit Error Interrupt

    	SPI_REGS->SPILVL = 0;		// Map all Interrupts to SPI0

    // SPI Pin Control Register 0
    SPI_REGS->SPIPC0 =
    (1 << 11) | // SPI Slave Out, Master In
    (1 << 10) | // SPI Slave in, Master Out
    (1 << 9) | // SPI Clock pin function
    // (1 << 1) | // SPI Chip Select pin 1
    // (0 << 0); // SPI Chip Select pin 0
    (0 << 1) | // SPI Chip Select pin 1
    (1 << 0); // SPI Chip Select pin 0
    // SPI Default Chip Select Register
    SPI_REGS->SPIDEF =
    (1 << 0); // Value CS set to when no transfer is performed
    // SPI Data Format Register
    for(i=0; i<4; i++) {
    SPI_REGS->SPIFMT[i] =
    (2 << 24) | // WDELAY - delay between transactions, # of clk cycles + 2 (6-bits)
    (1 << 20) | // Shift Direction (0-MSB first, 1-LSB first)
    (0 << 18) | // Disable CS timers
    (1 << 17) | // Polarity (state of inactive clock signal)
    (0 << 16) | // Phase
    (SPI_PRESCALE << 8) | // Prescale (valid 0-0xFF) define SPI_CLK_FREQ to change value
    (SPI_DATA_SIZE << 0); // Data Word Value in bits (2-16 valid)
    }
    // SPI Delay Register
    SPI_REGS->SPIDELAY =
    (4 << 24) | // CS to Active Delay
    (4 << 16); // Transmit End to CS disable Delay
    // SPI Default Chip Select Register
    SPI_REGS->SPIDEF =
    (1 << 0); // CS state when no transmissions are happening

    }
    
    

    I've also tried using EDMACC1 channels 2 & 3 w/ the same result (polling bits 2&3 instead of 30 & 31) any more clues as to what I am doing wrong would be greatly appreciated.

    Thanks,

    Erick

  • Erick, sorry this thread dropped off my radar for a while. I will address this issue middle of next week.

  • Thanks, I have tried a few different things, like setting the Interrupt register to 0, then enabling the DMA bit after the SPI was enabled, and trying the different dma channels and associated with the different controllers, however it is still giving me issues, as in It does not look like the transfers are happening because of the status bits.  Any help on this would be greatly appreciated.

    Erick

  • Any Updates on this Aditya?

  • Erick,

    I was out of office the whole of last week, sorry for the delay. I will update this thread by tomorrow with what I find.

  • Any updates on this issue?

  • My apologies, unfortunately I was not able to prioritize this. I will get back on this later this week or early next week.

  • Thank you Aditya, and I am looking forward to your good news!

  • Any update here? I am having the similar issue. Really appreciate if you can figure out why.

    Thanks,

  • Hello, Aditya,

    Did you get some time to look at this threads? I have tried a few different setting, but the SPI + EDMA still not working. Could you please give us an update or a new solution to set up this, thanks!

  • I haven't had time to go back and look at it myself either, been working on other things as well, but it is also still an outstanding issue for me too.  Working on other things I did realize that I didn't have the correct interrupt bits set for the channels specified, however the transfer never actually did happen which leads me to think that even if they were set properly it would have exited the function but the transfer still wouldn't have happened.  I'm still stuck on trying to figure out if the transfer settings are correct or not also.

    Erick

  • Erick,

    I am taking a look at this issue today. I am creating an EDMA-SPI example to try locally on an EVM here. In the meantime, as a basic test have you tried the test with SPI configured for internal loopback?

  • Hello,  Aditya ,

    Great to know you start looking at this issue. For your knowledge, we have SPI works in loopback mode as well as communicating with a SPI slave with CPU interrupt.

    SPI+EDMA doesn't work. Thanks.

    Xinwei

  • Aditya,

    I have not done an internal loop back, however we have a custom board and we do have SPI working back and forth w/ a different processor with a protocol that is interrupt driven.  However in our final project, we would like to use the EDMA to drive the SPI to take the load off of the Cores on long transfers.

    Erick

  • Xinwei, Erick,

    Thanks. I am trying to get a working project ready for you. At the moment am facing some issues with EDMA missed events on transmit side. I will post a working project once I have it ready. Please be assured that we want to get you a working project as soon as possible.

  • Hello, Aditya

    How is it going for this project? We really need a working version of SPI+DMA right now.  Please update us the progress and the version you have right now.

    Xinwei

  • I attached one SPI+EDMA example test case below, which is based on C6670 CSL.

    The SPI is configured in internal loopback mode and Channel 2 and Channel 3 of EDMA3_CC1 are being used for SPIXEVT and SPIREVT (Table 7-36 in C6670 data manual).

    The source buffer is located in CorePac0 L2 SRAM and being sent to SPI by EDMA. After loopback, the data is received by SPI and being sent to destination buffer located in CorePac1 L2 SRAM by EDMA as well.

    Please take a look and let us know if you need any more info about this. Thanks.

    4670.edma_spi.zip

  • Thank you very much, Steven. I really appreciate it. I have your example build and run well on the C6678 evm board. I have one more question: the src and dst buffer in your example is located in the L2SRAM, can I adapt this example to have my receiving dst buffer in the DDR? I want to have a bigger buffer.

    Looking forward your reply!!

    Xinwei

  • Xinwei,

    Sure. You can define the src/dst anywhere you prefer.

    For example, currently the dst buffer is in ".gem1_data"

    #pragma DATA_SECTION(dstBuf, ".gem1_data")
    #pragma DATA_ALIGN(dstBuf, 8)
    Uint16 dstBuf[BUF_SIZE];

    You can change to DDR SRAM as

    #pragma DATA_SECTION(dstBuf, ".ddrData")
    #pragma DATA_ALIGN(dstBuf, 8)
    Uint16 dstBuf[BUF_SIZE];

    And in the "example.cmd" file, you will see ".ddrData" is pointed to the DDR3_DATA_MEM. In this way, dstBuf is located in DDR SRAM.

    Alternately, you can use pointers of src/dst buffers, instead of pre-allocating them.

    Then you can give the actually memory location to those buffer pointers in the source code.

    But please pay attention to the memory allocation, that the buffers should be overlapped with others.

    Hope it helps.

  • Thank you, Steve. Yes, it definitely helps. I have make the DDR+SPI happened in the loopback mode. I have another two questions:

    1) I change the main in the example to a function spidmatest, and I call it in my main before everything start. It works for the first time when I called. The second time, just following the first call, it hangs at Setup_SPI() because the last while loop in this function. Could you please explain why? How to rescue it when I want the DMA happen more than once. (I have it working only once in the SPI working (non-loopback) mode also).

    2) I used the Oscilloscope to measure the time for transfering 350bytes data via SPI working at 50MHZ using the DMA, it takes around 97us. Is that reasonable? I expect it to be shorter.

    Thank you very much!

    Xinwei

  • Xinwei,

    1. The following example attached demonstrates how to trigger the SPI-EDMA transfer for multiple times. Basically, we need to setup reload paramSet for EDMA channels for the continuous peripheral support (refer to section 3.4.3 in EDMA user guide).

    And we can disable/enable the DMAREQEN bit in the SPIINT0 register to re-trigger the TX/RX DMA request.

    2. The throughput calculation is embedded in the attached example as well. If SPI is running at 66MHz the throughput is about 57Mbps. Please take a look at the following document for reference:Throughput Performance Guide for C66x KeyStone Devices (Rev. A)

    0410.edma_spi.zip

  • Thank you, Steve. I will look at the new code shortly. Before I got your new example, I had looked the EDMA registers and figured out one way for continuous firing SPI+DMA:. This is what I did:

    1) disable the complete interrupt bit by seting the fourth parameter False in the paramSetup.option call;

    2)write to register ' EDMA1_CH2SECR            *( volatile Uint32* ) (0x02720000 + 0x1040) '  0x4 to clear the ECR bit.

    Yes,  I stop the transfer by seting SPINT0 to 0.

    It works well so far. Could you please let me know if this way is proper? Anything I should be cautions of?

    Thanks.

    Xinwei

  • If you do not need EDMA generate interrupt at the completion of transfer, you can disable that and clear the secondary event bit as you did.

    Or you can still let EDMA generate interrupt and clear the interrupt pending in ICR (Interrupt Clear Register, offset 0x1070), as shown in the second example.

    I think either way should be fine, as long as it works for your scenario.

  • Thank you, Steve. Yes, your code works well.

    What I am currently doing is to receive data from SPI and put them in a large DDR buffer. But it seems 20% slower than using a buffer in L2 SRAM.

    So I am thinking to use L2SRAM buffer and use an DMA completion interrupt so that the ISR can do another DMA from L2SRAM to DDR. Do you think this will be faster? I really appreciate  if you can share the example code of setting up the DMA complete interrupt. Thanks,

    Xinwei

  • Hey Steve,

    Thanks for the example, I haven't had a chance to test it out yet, but it looks like it's what I need to get it going

    Erick

  • Hi,

      I tried the same code on c6657. I appreciate if anyone can advise on this problem. 

    Regards,

    Hari

    
    #include <ti/csl/soc.h>
    #include <ti/csl/tistdtypes.h>
    #include <ti/csl/csl_chip.h>
    #include <ti/csl/csl_edma3.h>
    #include <ti/csl/csl_edma3Aux.h>
    #include <ti/csl/cslr_spi.h>
    
    #include "spi_common.h"
    #include <stdio.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)
    {
       	// Enable channel
       	CSL_edma3HwChannelControl(hChannel0,CSL_EDMA3_CMD_CHANNEL_ENABLE,NULL);
    
       	// Enable channel
       	CSL_edma3HwChannelControl(hChannel1,CSL_EDMA3_CMD_CHANNEL_ENABLE,NULL);
    
    }
    
    
    void Setup_Edma_Init (void)
    {
    
        // 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_2;
    
    	hChannel0 = CSL_edma3ChannelOpen(&ChObj0, CSL_TPCC_2, &chParam, &EdmaStat);
    	chSetup.paramNum   = chParam.chaNum; //CSL_EDMA3_CHA_2;
        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_3;
    
    	hChannel1 = CSL_edma3ChannelOpen(&ChObj1, CSL_TPCC_2, &chParam, &EdmaStat);
    	chSetup.paramNum = chParam.chaNum; //CSL_EDMA3_CHA_3;
        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_2,&EdmaStat);
      	paramHandle1            = CSL_edma3GetParamHandle(hChannel1,CSL_EDMA3_CHA_3,&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_2,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);
    	paramSetup.dstAddr      = (Uint32)&(((CSL_SpiRegsOvly) CSL_SPI_REGS)->SPIDAT0);
    
    	//paramSetup.linkBcntrld  = CSL_EDMA3_LINKBCNTRLD_MAKE(CSL_EDMA3_LINK_NULL,0);
    	paramSetup.linkBcntrld  = CSL_EDMA3_LINKBCNTRLD_MAKE(paramHandle0_reload,0);
    
    	CSL_edma3ParamSetup(paramHandle0,&paramSetup);
    	CSL_edma3ParamSetup(paramHandle0_reload,&paramSetup);
    
        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_3,CSL_EDMA3_TCC_NORMAL, \
    	      CSL_EDMA3_FIFOWIDTH_NONE,FALSE,CSL_EDMA3_SYNC_A,CSL_EDMA3_ADDRMODE_INCR,CSL_EDMA3_ADDRMODE_INCR);
    	paramSetup.srcAddr      = (Uint32)&(((CSL_SpiRegsOvly) CSL_SPI_REGS)->SPIBUF);
    
    	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);
    	paramSetup.linkBcntrld  = CSL_EDMA3_LINKBCNTRLD_MAKE(paramHandle1_reload,0);
    
    	CSL_edma3ParamSetup(paramHandle1,&paramSetup);
    	CSL_edma3ParamSetup(paramHandle1_reload,&paramSetup);
    
    	//Enable_Edma_Channels();
    }
    
    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,&regionIpr);
    	}while ((regionIpr.intr & 0x08) != 0x08);	//channel_3
    
    	profileTxStop = CSL_tscRead();
    
    	do{
    		CSL_edma3GetHwStatus(hModule,CSL_EDMA3_QUERY_INTRPEND,&regionIpr);
    	}while ((regionIpr.intr & 0x04) != 0x04);	//channel_2
    
    	profileRxStop = CSL_tscRead();
    
    	/* Clear pending interrupt */
    	CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_INTRPEND_CLEAR, &regionIpr);
    
    }
    
    
    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 Setup_SPI_Init (void)
    {
        /* 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 for WAITEN=YES,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_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;
    
        /* Enable communication */
        ((CSL_SpiRegsOvly) CSL_SPI_REGS)->SPIGCR1|=
            CSL_SPI_SPIGCR1_ENABLE_ENABLE<<CSL_SPI_SPIGCR1_ENABLE_SHIFT;
    
    }
    
    void SPI_DMA_Request (void)
    {
    	/* Disable DMA Request */
    	((CSL_SpiRegsOvly) CSL_SPI_REGS)->SPIINT0 &=\
    		~(CSL_SPI_SPIINT0_DMAREQEN_ENABLE<<CSL_SPI_SPIINT0_DMAREQEN_SHIFT);
    
        /* Enable DMA Request */
    	((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();
    }
    
    
    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;
    }
    
    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 main (void)
    {
    	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)
    	   		printf("data verification of buffer[%d] passed\n", i);
    	   	else
    	   		printf("data verification of buffer[%d] failed\n", i);
    
    		profileTx = (Uint32)(profileTxStop - profileTxStart);
    	    profileRx = (Uint32)(profileRxStop - profileRxStart);
    
    	    printf("data buffer[%d] TX throughput is %f Mbps\n",i, TEST_ACNT*TEST_BCNT*8*1000/(float)profileTx);
    	    printf("data buffer[%d] RX throughput is %f Mbps\n",i, TEST_ACNT*TEST_BCNT*8*1000/(float)profileRx);
    	    printf("\n");
    	}
    
    
    	//Close EDMA channels/module                                        */
    	Close_Edma();
    
    	printf("end of test\n");
    
    }
    

    I got first problem where CSL_TPCC_1 is not defined.  I see it defines CSL_TPCC_2. I tried replacing with values 1 or 2. 

    Compilation is fine, But I get struck @ 

    while(!(((CSL_SpiRegsOvly) CSL_SPI_REGS)->SPIFLG & 0x00000100));
    profileRxStart = CSL_tscRead();

  • Harikrishna.

    Using TPCC_2 instead of TPCC_1 requires using different edma channels as the SPI is setup for specific channels, so when CSL_EDMA3_CHA_2 is used, that is specific for TPCC_1, so you need to use CSL_TPCC2_SPIXEVT instead (lines 74, 77, 97, and 104). Same thing goes for CSL_EDMA3_CHA_3, you should replace those references with CSL_TPCC2_SPIREVT.

    Lines 167/168 are also specific to edma channels 2 and 3, you'll have to use the defines for those specific channels. and lines 149 and 147 check to see if the the channel 2 and channel 3 bits are also done.

    Hope that helps,

    Erick

  • Hello, Steve,

    Thank you for all your effort on this thread. With your example code, I have SPI+EDMA works well on core 0. Now I want to have the code running one core 1 and have core 0 mainly run the TCP/IP code. Then I found out the SPI+EDMA stop working.

    What is the necessary changes for have SPI working one core1? Thanks,

    Xinwei

  • Xinwei,

    I do not see any changes needed to run the test on Core1.

    Is there any resource conflict in your two-core testing (e.g. EDMA resource)?

    Or have you tested the SPI-EDMA example on Core1 only (Core0 or other cores are NOT running any code) please?

    If it is still not passing in Core1 standalone mode, please elaborate how the test stops working or where it stops. Thanks.

  • Hi Erick,

      Could you please help me. I tried with your suggestions. It still stops at 

    while(!(((CSL_SpiRegsOvly) CSL_SPI_REGS)->SPIFLG & 0x00000100));

    Regards,

    Hari

    
    #include <ti/csl/soc.h>
    #include <ti/csl/tistdtypes.h>
    #include <ti/csl/csl_chip.h>
    #include <ti/csl/csl_edma3.h>
    #include <ti/csl/csl_edma3Aux.h>
    #include <ti/csl/cslr_spi.h>
    
    #include "spi_common.h"
    #include <stdio.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
    
    #pragma DATA_SECTION(dstBuf, ".gem1_data")
    #pragma DATA_ALIGN(dstBuf, 8)
    Uint16 dstBuf[BUF_SIZE];
    
    #pragma DATA_SECTION(srcBuf, ".gem0_data")
    #pragma DATA_ALIGN(srcBuf, 8)
    Uint16 srcBuf[BUF_SIZE];
    
    
    
    Uint32 global_address (Uint32 addr)
    {
    	Uint32 corenum;
    	corenum = CSL_chipReadReg(CSL_CHIP_DNUM);
    
    	addr = addr + (0x10000000 + corenum*0x1000000);
    	return addr;
    }
    
    void Trigger_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 (Uint32 srcBuf,Uint32 dstBuf)
    {
    
        // 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_TPCC2_SPIXEVT;
    
    	hChannel0 = CSL_edma3ChannelOpen(&ChObj0, CSL_TPCC_2, &chParam, &EdmaStat);
    	chSetup.paramNum   = chParam.chaNum; //CSL_EDMA3_CHA_2;
        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_TPCC2_SPIREVT;
    
    	hChannel1 = CSL_edma3ChannelOpen(&ChObj1, CSL_TPCC_2, &chParam, &EdmaStat);
    	chSetup.paramNum = chParam.chaNum; //CSL_EDMA3_CHA_3;
        CSL_edma3HwChannelSetupParam(hChannel1,chSetup.paramNum);
    
    	// Parameter Handle Open
    	// Open all the handles and keep them ready
    	paramHandle0            = CSL_edma3GetParamHandle(hChannel0,CSL_TPCC2_SPIXEVT,&EdmaStat);
      	paramHandle1            = CSL_edma3GetParamHandle(hChannel1,CSL_TPCC2_SPIREVT,&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,FALSE,CSL_TPCC2_SPIXEVT,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);
    	paramSetup.dstAddr      = (Uint32)&(((CSL_SpiRegsOvly) CSL_SPI_REGS)->SPIDAT0);
    	paramSetup.linkBcntrld  = CSL_EDMA3_LINKBCNTRLD_MAKE(CSL_EDMA3_LINK_NULL,0);
    
    	CSL_edma3ParamSetup(paramHandle0,&paramSetup);
    
        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,FALSE,CSL_TPCC2_SPIREVT,CSL_EDMA3_TCC_NORMAL, \
    	      CSL_EDMA3_FIFOWIDTH_NONE,FALSE,CSL_EDMA3_SYNC_A,CSL_EDMA3_ADDRMODE_INCR,CSL_EDMA3_ADDRMODE_INCR);
    	paramSetup.srcAddr      = (Uint32)&(((CSL_SpiRegsOvly) CSL_SPI_REGS)->SPIBUF);
    
    	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,&paramSetup);
    	Trigger_Edma_Channels();
    }
    
    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,&regionIpr); /* check CSL_EDMA3_QUERY_INTRPEND is correct TBD_HARI */
    	}while ((regionIpr.intr & 0x08) != 0x08);	//channel_3 ---> Need to check.. TBD
    
    
    	do{
    		CSL_edma3GetHwStatus(hModule,CSL_EDMA3_QUERY_INTRPEND,&regionIpr);
    	}while ((regionIpr.intr & 0x04) != 0x04);	//channel_2 --> Need to check.. TBD
    
    }
    
    
    void Close_Edma()
    {
        CSL_FINST(hModule->regs->TPCC_SECR,TPCC_TPCC_SECR_SECR2,RESETVAL); /* check TPCC_TPCC_SECR_SECR2/TPCC_TPCC_SECR_SECR3 is correct TBD_HARI */
      	CSL_FINST(hModule->regs->TPCC_SECR,TPCC_TPCC_SECR_SECR3,RESETVAL);
    
     	CSL_edma3ChannelClose(hChannel0);
     	CSL_edma3ChannelClose(hChannel1);
     	CSL_edma3Close(hModule);
    }
    
    /******************************************************************************
     * 
     * Function:    spi_claim  
     *
     * Description: This function claims the SPI bus in the SPI controller 
     *
     * Parameters:  Uint32 cs       - Chip Select number for the slave SPI device
     *              Uint32 freq     - SPI clock frequency  
     *
     * Return Value: error status
     * 
     ******************************************************************************/
    SPI_STATUS 
    spi_claim
    (
        uint32_t      cs,
        uint32_t      freq
    )
    {
        uint32_t scalar;
    
        PLIBSPILOCK()
    
        /* Enable the SPI hardware */
        SPI_SPIGCR0 = CSL_SPI_SPIGCR0_RESET_IN_RESET;
        spi_delay (2000);
        SPI_SPIGCR0 = CSL_SPI_SPIGCR0_RESET_OUT_OF_RESET;
    
        /* Set master mode, powered up and not activated */
        SPI_SPIGCR1 =   (CSL_SPI_SPIGCR1_MASTER_MASTER << CSL_SPI_SPIGCR1_MASTER_SHIFT)   |
                        (CSL_SPI_SPIGCR1_CLKMOD_INTERNAL << CSL_SPI_SPIGCR1_CLKMOD_SHIFT);
        
        
        /* CS0, CS1, CLK, Slave in and Slave out are functional pins */
        if (cs == 0) 		{
            SPI_SPIPC0 =    (CSL_SPI_SPIPC0_SCS0FUN0_SPI << CSL_SPI_SPIPC0_SCS0FUN0_SHIFT) |
                            (CSL_SPI_SPIPC0_CLKFUN_SPI << CSL_SPI_SPIPC0_CLKFUN_SHIFT)     |
                            (CSL_SPI_SPIPC0_SIMOFUN_SPI << CSL_SPI_SPIPC0_SIMOFUN_SHIFT)   |
                            (CSL_SPI_SPIPC0_SOMIFUN_SPI << CSL_SPI_SPIPC0_SOMIFUN_SHIFT);
        } else if (cs == 1)  {
            SPI_SPIPC0 =    ((CSL_SPI_SPIPC0_SCS0FUN1_SPI << CSL_SPI_SPIPC0_SCS0FUN1_SHIFT) |
                            (CSL_SPI_SPIPC0_CLKFUN_SPI << CSL_SPI_SPIPC0_CLKFUN_SHIFT)     |
                            (CSL_SPI_SPIPC0_SIMOFUN_SPI << CSL_SPI_SPIPC0_SIMOFUN_SHIFT)   |
                            (CSL_SPI_SPIPC0_SOMIFUN_SPI << CSL_SPI_SPIPC0_SOMIFUN_SHIFT)) & 0xFFFF;
    	} else if (cs == 2)  {
            SPI_SPIPC0 =    ((CSL_SPI_SPIPC0_SCS0FUN0_SPI << CSL_SPI_SPIPC0_SCS0FUN0_SHIFT) |
            				(CSL_SPI_SPIPC0_CLKFUN_SPI << CSL_SPI_SPIPC0_CLKFUN_SHIFT)     |
            				(CSL_SPI_SPIPC0_SIMOFUN_SPI << CSL_SPI_SPIPC0_SIMOFUN_SHIFT)   |
            				(CSL_SPI_SPIPC0_SOMIFUN_SPI << CSL_SPI_SPIPC0_SOMIFUN_SHIFT)) & 0xFFFF;
    	}
        
        /* setup format */
        scalar = ((SPI_MODULE_CLK / freq) - 1 ) & 0xFF;
    
        if ( cs == 0) {
            SPI_SPIFMT0 =   (8 << CSL_SPI_SPIFMT_CHARLEN_SHIFT)               |
                            (scalar << CSL_SPI_SPIFMT_PRESCALE_SHIFT)                      |
                            (CSL_SPI_SPIFMT_PHASE_DELAY << CSL_SPI_SPIFMT_PHASE_SHIFT)     |
                            (CSL_SPI_SPIFMT_POLARITY_LOW << CSL_SPI_SPIFMT_POLARITY_SHIFT) |
                            (CSL_SPI_SPIFMT_SHIFTDIR_MSB << CSL_SPI_SPIFMT_SHIFTDIR_SHIFT);
         }else if ( cs == 1) {
            SPI_SPIFMT0 =   (16 << CSL_SPI_SPIFMT_CHARLEN_SHIFT)               |
                            (scalar << CSL_SPI_SPIFMT_PRESCALE_SHIFT)                      |
                            (CSL_SPI_SPIFMT_PHASE_NO_DELAY << CSL_SPI_SPIFMT_PHASE_SHIFT)     |
                            (CSL_SPI_SPIFMT_POLARITY_LOW << CSL_SPI_SPIFMT_POLARITY_SHIFT) |
                            (CSL_SPI_SPIFMT_SHIFTDIR_MSB << CSL_SPI_SPIFMT_SHIFTDIR_SHIFT);
       }else if ( cs == 2) {
            SPI_SPIFMT0 =   (8 << CSL_SPI_SPIFMT_CHARLEN_SHIFT)               |
                            (scalar << CSL_SPI_SPIFMT_PRESCALE_SHIFT)                      |
                            (3 << CSL_SPI_SPIFMT_WDELAY_SHIFT) |
                            (CSL_SPI_SPIFMT_PHASE_DELAY << CSL_SPI_SPIFMT_PHASE_SHIFT)     |
                            (CSL_SPI_SPIFMT_POLARITY_HIGH << CSL_SPI_SPIFMT_POLARITY_SHIFT) |
                            (CSL_SPI_SPIFMT_SHIFTDIR_MSB << CSL_SPI_SPIFMT_SHIFTDIR_SHIFT);
        }
        
        /* hold cs active at end of transfer until explicitly de-asserted */
        if ((cs == 0) || (cs == 1))
    	{
    		data1_reg_val = (CSL_SPI_SPIDAT1_CSHOLD_ENABLE << CSL_SPI_SPIDAT1_CSHOLD_SHIFT) |
                        (0x02 << CSL_SPI_SPIDAT1_CSNR_SHIFT);
    	}
    	else
    	{
        	data1_reg_val =  /* (CSL_SPI_SPIDAT1_CSHOLD_ENABLE << CSL_SPI_SPIDAT1_CSHOLD_SHIFT) | */
        				/* (CSL_SPI_SPIDAT1_WDEL_ENABLE << CSL_SPI_SPIDAT1_WDEL_SHIFT) | */
                        (0x02 << CSL_SPI_SPIDAT1_CSNR_SHIFT);
    	}
         if (cs == 0) {
             SPI_SPIDAT1 =   (CSL_SPI_SPIDAT1_CSHOLD_ENABLE << CSL_SPI_SPIDAT1_CSHOLD_SHIFT) |
                             (0x02 << CSL_SPI_SPIDAT1_CSNR_SHIFT);
         } 
    
        /* including a minor delay. No science here. Should be good even with
        * no delay
        */
        if (cs == 0) {
            SPI_SPIDELAY =  (8 << CSL_SPI_SPIDELAY_C2TDELAY_SHIFT) |
                            (8 << CSL_SPI_SPIDELAY_T2CDELAY_SHIFT);
            /* default chip select register */
            SPI_SPIDEF  = CSL_SPI_SPIDEF_RESETVAL;        
        } else if (cs == 1) {    
            SPI_SPIDELAY =  (6 << CSL_SPI_SPIDELAY_C2TDELAY_SHIFT) |
                            (3 << CSL_SPI_SPIDELAY_T2CDELAY_SHIFT);
        } else if (cs == 2) {    
            SPI_SPIDELAY =  (0 << CSL_SPI_SPIDELAY_C2TDELAY_SHIFT) |
                            (0 << CSL_SPI_SPIDELAY_T2CDELAY_SHIFT);
            SPI_SPIDEF  = 0x7;
        }
        
        /* no interrupts */
        SPI_SPIINT0 = CSL_SPI_SPIINT0_RESETVAL;
        SPI_SPILVL  = CSL_SPI_SPILVL_RESETVAL;
        return SPI_EOK;
    }
    
    
    void enable_spi()
    {
        /* enable SPI */
        SPI_SPIGCR1 |= ( CSL_SPI_SPIGCR1_ENABLE_ENABLE << CSL_SPI_SPIGCR1_ENABLE_SHIFT );
    #if 0
        {
            uint32_t scalar;
            SPI_SPIDAT0 = 1 << 15;
            spi_delay (10000);
            /* Read SPIFLG, wait untill the RX full interrupt */
            if ( (SPI_SPIFLG & (CSL_SPI_SPIFLG_RXINTFLG_FULL<<CSL_SPI_SPIFLG_RXINTFLG_SHIFT)) ) {
                /* Read one byte data */
                scalar = SPI_SPIBUF & 0xFF;
                /* Clear the Data */
                SPI_SPIBUF = 0;
            }
            else {
                /* Read one byte data */
                scalar = SPI_SPIBUF & 0xFF;
                //return SPI_EFAIL;
            }
        }
    #endif
    
    #if 1
          SPI_SPIINT0 |=
      		CSL_SPI_SPIINT0_DMAREQEN_ENABLE<<CSL_SPI_SPIINT0_DMAREQEN_SHIFT;
    #endif
    	while(!(((CSL_SpiRegsOvly) CSL_SPI_REGS)->SPIFLG & 0x00000200));
    
    	while(!(((CSL_SpiRegsOvly) CSL_SPI_REGS)->SPIFLG & 0x00000100));
    
    }
    
    
    void Setup_SPI (void)
    {
        /* 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_SCS0FUN1_SHIFT;
    
    #if 1
    	/* Put SPI in Lpbk mode */
    	((CSL_SpiRegsOvly) CSL_SPI_REGS)->SPIGCR1 |=
    		CSL_SPI_SPIGCR1_LOOPBACK_ENABLE<<CSL_SPI_SPIGCR1_LOOPBACK_SHIFT;
    #endif
        /* Chose SPIFMT0 */
        ((CSL_SpiRegsOvly) CSL_SPI_REGS)->SPIDAT1=
            CSL_SPI_SPIDAT1_DFSEL_FORMAT0<<CSL_SPI_SPIDAT1_DFSEL_SHIFT;
        /* Configure for WAITEN=YES,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_DELAY<<CSL_SPI_SPIFMT_PHASE_SHIFT|
            0x40<<CSL_SPI_SPIFMT_PRESCALE_SHIFT|
            0x08<<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;
    
        /* 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));
    
    	while(!(((CSL_SpiRegsOvly) CSL_SPI_REGS)->SPIFLG & 0x00000100));
    
    }
    
    
    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;
    }
    
    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;
    		}
    	}
    }
    
    extern void mainspi();
    extern void enable_spi();
    extern void enable_spi2();
    void main (void)
    {
    	volatile Uint32 failFlag = FALSE;
    
    	//Initiate src/dst buffers
    	Initiate_Buffers(TEST_ACNT,TEST_BCNT, TEST_CCNT,TEST_ACNT ,TEST_ACNT, TEST_ACNT*TEST_BCNT, TEST_ACNT*TEST_BCNT,(Uint32)srcBuf,(Uint32)dstBuf, CSL_EDMA3_SYNC_A);
       	//Setup EDMA for SPI transfer
       	Setup_Edma((Uint32)srcBuf,(Uint32)dstBuf);
    
    	spi_claim(2, 1000000);
    	enable_spi();
    
    	//Check EDMA transfer completion status
        Test_Edma();
    
    	//Close EDMA channels/module                                        */
    	Close_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,(Uint32)dstBuf, CSL_EDMA3_SYNC_A);
    
    	if (failFlag == TRUE)
    		printf("data verification passed\n");
    	else
    		printf("data verification failed\n");
    	printf("end of test\n");
    }
    

  • Hi Steven/Erick,

       I think the moment I enable the 

    /* Enable communication */
    ((CSL_SpiRegsOvly) CSL_SPI_REGS)->SPIGCR1 |=
    CSL_SPI_SPIGCR1_ENABLE_ENABLE<<CSL_SPI_SPIGCR1_ENABLE_SHIFT;

    The SPIFLG reads 01000200 

    It goes in infinite loop. this happens just before setting CSL_SPI_SPIINT0_DMAREQEN_ENABLE and before CSL_SPI_SPIGCR1_ENABLE_ENABLE. Before setting these I am enable EDMA and Setting all the SPI registers. Looks some simple configuration. Pl. advise. 

    0x20bf0000:  00000001 01000003 0101005F 00000000
    0x20bf0010:  01000200 01010E01 

    Pl. advise. 

  • Hi,

       Can anyone advise. 

    Regards,

    Hari

  • Hari,

    I think you want to port the SPI-EDMA example to C6657 device. We need to do the following changes regarding to the EDMA and interrupt difference:

    CSL_TPCC_1 (6670) --> CSL_TPCC_2 (6657)
    SPIXEVT: CSL_EDMA3_CHA_2 (6670) --> CSL_EDMA3_CHA_30 (6657)
    SPIREVT: CSL_EDMA3_CHA_3 (6670) --> CSL_EDMA3_CHA_31 (6657)
    EDMA IPR check bit 3 and 2 (6670) --> check bit 31 and 30 (6657)

    I attached the example file for C6657 as well. Hope it works for you.

    
    #include <ti/csl/soc.h>
    #include <ti/csl/tistdtypes.h>
    #include <ti/csl/csl_chip.h>
    #include <ti/csl/csl_edma3.h>
    #include <ti/csl/csl_edma3Aux.h>
    #include <ti/csl/cslr_spi.h>
    
    #include <spi_common.h>
    #include <stdio.h>
    
    #include <psc_util.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
    
    #pragma DATA_SECTION(dstBuf, ".gem1_data")
    #pragma DATA_ALIGN(dstBuf, 8)
    Uint16 dstBuf[BUF_SIZE];
    
    #pragma DATA_SECTION(srcBuf, ".gem0_data")
    #pragma DATA_ALIGN(srcBuf, 8)
    Uint16 srcBuf[BUF_SIZE];
    
    void enable_spi(void)
    {
    		if (enable_module(emif25_spi_pdctl,emif25_spi_mdctl) != 1)
        	{
        		printf ("SPI enable failed\n");
       		}
    
    }
    
    Uint32 global_address (Uint32 addr)
    {
    	Uint32 corenum;
    	corenum = CSL_chipReadReg(CSL_CHIP_DNUM);
    
    	addr = addr + (0x10000000 + corenum*0x1000000);
    	return addr;
    }
    
    void Trigger_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 (Uint32 srcBuf,Uint32 dstBuf)
    {
    
        // 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;
    
    	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);
    
    	// 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);
    	paramSetup.dstAddr      = (Uint32)&(((CSL_SpiRegsOvly) CSL_SPI_REGS)->SPIDAT0);
    	paramSetup.linkBcntrld  = CSL_EDMA3_LINKBCNTRLD_MAKE(CSL_EDMA3_LINK_NULL,0);
    
    	CSL_edma3ParamSetup(paramHandle0,&paramSetup);
    
        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);
    	paramSetup.srcAddr      = (Uint32)&(((CSL_SpiRegsOvly) CSL_SPI_REGS)->SPIBUF);
    
    	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,&paramSetup);
    	Trigger_Edma_Channels();
    }
    
    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,&regionIpr);
    	}while ((regionIpr.intr & (1<<31)) != (1<<31));	//channel_31
    
    
    	do{
    		CSL_edma3GetHwStatus(hModule,CSL_EDMA3_QUERY_INTRPEND,&regionIpr);
    	}while ((regionIpr.intr & (1<<30)) != (1<<30));	//channel_30
    
    }
    
    
    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 Setup_SPI (void)
    {
    	//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 for WAITEN=YES,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_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;
    
        /* 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));
    
    	while(!(((CSL_SpiRegsOvly) CSL_SPI_REGS)->SPIFLG & 0x00000100));
    
    }
    
    
    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;
    }
    
    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 main (void)
    {
    	volatile Uint32 failFlag = FALSE;
    
    	//Initiate src/dst buffers
    	Initiate_Buffers(TEST_ACNT,TEST_BCNT, TEST_CCNT,TEST_ACNT ,TEST_ACNT, TEST_ACNT*TEST_BCNT, TEST_ACNT*TEST_BCNT,(Uint32)srcBuf,(Uint32)dstBuf, CSL_EDMA3_SYNC_A);
    
       	//Setup EDMA for SPI transfer
       	Setup_Edma((Uint32)srcBuf,(Uint32)dstBuf);
    
    	//Configure SPI in loopback mode and enable DMA interrupt support
    	Setup_SPI();
    
    	//Check EDMA transfer completion status
        Test_Edma();
    
    	//Close EDMA channels/module                                        */
    	Close_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,(Uint32)dstBuf, CSL_EDMA3_SYNC_A);
    
    	if (failFlag == TRUE)
    		printf("data verification passed\n");
    	else
    		printf("data verification failed\n");
    
    	printf("end of test\n");
    
    }
    

  • I get the same problem with your code too. (I am working on c6657 EVB provided by TI, TMDXE VM6657) And is there any dependency on DIP Switch settings? I am working on Big Endian mode). 

    ------------------------------------------------------

    Data Buffers: 


    srcbuf[] address is 0x00809e30

    dstbuf[] address is 0x0080A630

    ------------------------------------------------------

    /* Enable communication */

    ((CSL_SpiRegsOvly) CSL_SPI_REGS)->SPIGCR1|=
    CSL_SPI_SPIGCR1_ENABLE_ENABLE<<CSL_SPI_SPIGCR1_ENABLE_SHIFT;

    /* HERE SPIFLG is 0x01000200 And thus it gets struck at second while loop */

    ((CSL_SpiRegsOvly) CSL_SPI_REGS)->SPIINT0 |=
    CSL_SPI_SPIINT0_DMAREQEN_ENABLE<<CSL_SPI_SPIINT0_DMAREQEN_SHIFT;

    while(!(((CSL_SpiRegsOvly) CSL_SPI_REGS)->SPIFLG & 0x00000200));

    while(!(((CSL_SpiRegsOvly) CSL_SPI_REGS)->SPIFLG & 0x00000100)); /* GETS STRUCK HERE */

    ------------------------------------------------------

    Regards,

    Hari

  • Hi.

     Any suggestions? 

    Regards,

    Hari

  • Hi Steven,

          This program does not work in Big Endian mode but runs in Little Endian Mode. I tried to run the EDMA second time, but the data is zero and fails the comparision. Looking for help on how to make it working in Big Endian and multiple times. 

    Regards,

    Hari

  • Hi Steven,

      So I am using your 6657 example and it works.  Now I am trying to tie the edma receive interrupt to global interrupt #5 which will jump to the function

    edmaSpiRecvHandler. below is a snippit of my intc setup:

     

    CpIntc_mapSysIntToHostInt(0, 24, 40);      CICO secondary interrupt event 24 is EDMA3)CC individual completion interrupt.  I am using CICO40 for primary

    CpIntc_dispatchPlug(24, &edmaSpiRecvHandler, NULL, TRUE);

    CpIntc_enableHostInt(0, 40);

    eventId = CpIntc_getEventId(40);

    Hwi_Params_init(&params);

    params.arg = 40;                                      

    // required to be the host interrupt #

    params.eventId = eventId;

    params.enableInt = TRUE;

    Hwi_create(5, &CpIntc_dispatch, &params, NULL);

    Hwi_enableInterrupt(5);

  • System interrupt #24 is EDMA3_CC interrupt completion for Shadow region 0. If you intend to use shadow region interrupt, please ensure that the bit corresponding to the TCC code 
    is enabled in IER/IERH and in the corresponding shadow region's DMA region access registers (DRAE/DRAEH) in your application.

    Please take a look at the section 2.9 EDMA Interrupts in EDMA user guide for details.

    If you are using Global region for the EDMA setup, you should choose the system interrupt #22, which is for the global EDMA_CC interrupt completion.

  • Hi Steven,

      I just saw that a minute ago.  I replaced the number 24 with 22 but I still don't see any global interrupts pending and the software is not interrupting in the funciton.  I check the EDMA registers and I see the Secondary Event Register bit is set for the transmit along with the interrupt pending for the receive.  Am I still missing something?

    THanks,

    Will

  • Also,

    I have a scope on the spi output so I know that at least the transmit is working correctly. Is there a way to see the param table for the spi so I can check the count value for the receive side. 

    Will

  • Hi Steven,

      I found my issue.  I did not have the edma interrupt enabled for the receive channel (31). 

    Will

  • Hi, all

    I have a question here. In the purpose of porting this SPI + EDMA3 example into my platform, EVMK2H by using CSL library,


    I tried compile it in CCS5.5 successfully with c6678 pdk package, and debug it in the simulation mode. I don't have a EVM on C6657,

    so check this program is suit for me in the software simulation. But here is something when I run this program. This program is pause at

    while(!(((CSL_SpiRegsOvly) CSL_SPI_REGS)->SPIFLG & 0x00000200));
    while(!(((CSL_SpiRegsOvly) CSL_SPI_REGS)->SPIFLG & 0x00000100));

    but when the SPI in the reset status, the SPIFLG = 0x0, so there must be a endless loop.

     

    Does this thread can be run on Simulation mode?

     

    ---------------------------------------------

    Regards,

    xiaop