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.

TMS320F2812: 8-bit SPI communication with EtherCAT controller

Part Number: TMS320F2812

I am using a TMS320F2812 (will refer to as DSP from here on) to communicate with an EtherCAT Slave controller that uses ET1100 chipset.

I want to establish a 8 bit SPI communication where DSP is Master and Et1100 is slave.

My problems include
1. the SPI ENABLE LINE DOES NOT WORK AS INTENDED. I want the SPI ENABLE line to become active (low) at start of communication and then go inactive (high) AFTER 8 BITS are communicated. This also leads me to the question whether after I load the TXBUF should I wait for x micro/milli seconds before loading the next TXBUF? Does this also cause the ENABLE line to not work as intended? 

The following functions are to read and write to/from the et1100.

void ESC_read(uint16_t address, void *buf, uint16_t len, void *tALevent) {
    uint16_t count = 0;
    unsigned int *ptr;
    uint16_t adr = 0;
	uint16_t i = 0;

	//adr = address;
	adr = (address<<3)+ESC_CMD_READ;
    ptr = tALevent;
    // Chip select low
    EALLOW;
    GpioDataRegs.GPFDAT.bit.GPIOF3 = 0; // Transmit Enable (SYNC)
    //SpiaRegs.SPICTL.bit.TALK = 1;
    EDIS;

    SpiaRegs.SPITXBUF = adr;
    while ( ! SpiaRegs.SPISTS.bit.INT_FLAG );
    __byte(ptr,0) = (SpiaRegs.SPIRXBUF&0x00FF);
	SpiaRegs.SPITXBUF = send_8bit(adr);
	while ( ! SpiaRegs.SPISTS.bit.INT_FLAG );
	__byte(ptr,1) = (SpiaRegs.SPIRXBUF&0x00FF);
    count = len;
    ptr = buf;

		while ((count--) > 1)
		{
			i=0;
			SpiaRegs.SPITXBUF = ESC_NEXT;
			while ( ! SpiaRegs.SPISTS.bit.INT_FLAG );
			__byte(ptr,i) = (SpiaRegs.SPIRXBUF&0x00FF);
			i++;
		}
		SpiaRegs.SPITXBUF = ESC_TERM;
		while ( ! SpiaRegs.SPISTS.bit.INT_FLAG );
		// Chip select high
	    EALLOW;
	   // SpiaRegs.SPICTL.bit.TALK = 0;
	    GpioDataRegs.GPFDAT.bit.GPIOF3 = 1; // Transmit DISable (SYNC)
	    EDIS;
		__byte(ptr,i) = (SpiaRegs.SPIRXBUF&0xFF);

}

void ESC_write(uint16_t address, void *buf, uint16_t len, void *tALevent) {
    uint16_t count;
    uint16_t dummy;
    unsigned int *ptr;
    uint16_t adr;

	
	adr = ((address<<3)+ESC_CMD_WRITE);
    ptr = tALevent;
    // Chip select low
    EALLOW;
    GpioDataRegs.GPFDAT.bit.GPIOF3 = 0; // Transmit Enable (SYNC)
 //   SpiaRegs.SPICTL.bit.TALK = 1;
    EDIS;

    SpiaRegs.SPITXBUF = adr;
    while ( ! SpiaRegs.SPISTS.bit.INT_FLAG );
    __byte(ptr,0) = (SpiaRegs.SPIRXBUF&0x00FF);
	SpiaRegs.SPITXBUF = send_8bit(adr);
	while ( ! SpiaRegs.SPISTS.bit.INT_FLAG );
	__byte(ptr,1) = (SpiaRegs.SPIRXBUF&0x00FF);
    count = len;
    ptr = buf;
    while ((count--) > 0) 
	{
		uint16_t i=0;
        SpiaRegs.SPITXBUF = send_8bit(__byte(ptr,i));
		i++;
		while ( ! SpiaRegs.SPISTS.bit.INT_FLAG );
        dummy = SpiaRegs.SPIRXBUF;
    }
    // Chip select high
    EALLOW;
 //   SpiaRegs.SPICTL.bit.TALK = 0;
    GpioDataRegs.GPFDAT.bit.GPIOF3 = 1; // Transmit DISable (SYNC)
    EDIS;

}

Summarizing - My primary concern is the SPI does not work as intended.

Also attaching the SPI initialization. 

static void spi_init(void)
{
	EALLOW;
	   GpioMuxRegs.GPFMUX.all=0x000F;	// Select GPIOs to be SPI pins
	 									// Port F MUX - x000 0000 0000 1111
	   EDIS;
	   DINT;

	   // Initialize SPI FIFO registers
	       SpiaRegs.SPIFFTX.all=0xA040;
	       SpiaRegs.SPIFFRX.all=0x2040;
	       SpiaRegs.SPIFFCT.all=0x0;

	   SpiaRegs.SPICCR.all =0x0047;	             	// Reset on, (clk pol=1 : Falling edge), 8-bit char bits
	   	SpiaRegs.SPICTL.all =0x0006;    		     // Enable master mode, normal phase,
	                                                    // enable talk, and SPI int disabled.
	   	SpiaRegs.SPIBRR =0x007F;						//  150 MHz/4/(127+1)=  292.3 KHz
	       SpiaRegs.SPICCR.all =0x00C7;		         // Relinquish SPI from Reset
	       SpiaRegs.SPIPRI.bit.FREE = 1;                // Set so breakpoints don't disturb xmission
}

  • Raghu,
    the timing with ET1100 SPI is very tight in my experience. Can you refer to the TI Design SW (www.ti.com/.../TIDM-DELFINO-ETHERCAT), we have HAL for SPI and EMIF on Delfino devices. An update will be pushed this week to the SW HAL.

    if I understand correctly the GPIO are working fine, but the read/writes are not?

    Best Regards
    Santosh Athuru
  • To be very precise, (DSP is master and ET1100 is slave) MOSI, the CLK lines work fine. The SPI SEL lines also "seem" to work fine. I will attach the captured signals tomorrow morning from work. I say seem to work fine because the SPI SEL line go low (active) earlier than (maybe by half a clock cycle) the CLK lines. The ET1100 (MISO) does not reply to the MOSI bits as expected. That is precisely the problem. Because of that ofcourse read and writes don't work. So your understanding is correct but I am unable to say with 100% confidence what is causing the problem.
    I personally think the problem is because of timing (95% sure) but I cannot be sure. I have broken my head for so long. 
    More help from TI would be greatly appreciated. 
    But your reference looks interesting. I will read through the code. It seems like it has been recently updated. Also what is this SW HAL update that you plan to realise this week?? 

  • Try slowing down the SPI on MCU. The HAL SW, I was referring to is the F2837x MCU and ET1100 PDI SW that is released with the TI Design, the example supports EMIF (16 bit) and SPI PDI. It is for F2837x MCU but should be portable to F2812 or should provide a good reference. The SW can be downloaded from the page that I linked above or by below link. I made few more changes to the HAL after testing with CTT the updates will be pushed to web this week most likely.

    www.ti.com/.../tidcc35

    Best Regard
    Santosh Athuru
  • Raghu,

    One side note is to not use the INT_FLAG when using FIFO mode. This bit will be cleared when the SPIDAT register is copied to SPIRXBUF, if your software misses this event, there is a chance that it will hang in the polling loop for the INT_FLAG to be set.

    Thanks,
    Mark
  • Ok, so I should wait for the update or the existing code is good enough to look at? (I assume CTT is some sort of conformance tests)

    ALso about the SPI - How do I slow down the SPI on the MCU(I assume MCU is microcontroller Unit or the DSP)? The SPI_SEL line (GpioDataRegs.GPFDAT.bit.GPIOF3 = 1 or 0) is not software controllable. It works solely on the TXBUF register's content and the SPICCR char bits (state control). I had to change my code from what I have given here in the start of this post/thread. So whatever I do in the software, the SPI_SEL line goes low half a clock cycle (or maybe one full clock cycle) before the CLK (and the TX bits) are transmitted and then the SPI_SEL goes back high just after the CLK and TX bits are transmitted - meaning not software controlled.
    Due to this, I don't understand clearly what you mean by slowing down the SPI and how that's going to help.
  • The new code looks like this (Similarly for ESC_read)

    void ESC_write(uint16_t address, void *buf, uint16_t len, void *tALevent) {
        uint16_t count;
        uint16_t dummy;
        unsigned int *ptr;
        uint16_t adr;
    
        
        adr = ((address<<3)+ESC_CMD_WRITE);
        ptr = tALevent;
    
    
        SpiaRegs.SPITXBUF = adr;
        while ( ! SpiaRegs.SPISTS.bit.INT_FLAG );
        __byte(ptr,0) = (SpiaRegs.SPIRXBUF&0x00FF);
        SpiaRegs.SPITXBUF = send_8bit(adr);
        while ( ! SpiaRegs.SPISTS.bit.INT_FLAG );
        __byte(ptr,1) = (SpiaRegs.SPIRXBUF&0x00FF);
        count = len;
        ptr = buf;
        while ((count--) > 0) 
        {
            uint16_t i=0;
            SpiaRegs.SPITXBUF = send_8bit(__byte(ptr,i));
            i++;
            while ( ! SpiaRegs.SPISTS.bit.INT_FLAG );
            dummy = SpiaRegs.SPIRXBUF;
        }
    
    
    }

  • I agree with the INT_FLAG in FIFO mode. For now I am only using one register for TX and one for RX. No fifo :)
    Also this bit will clear when the RXBUF is read (not when SPIDAT is copied to RXBUF). I have checked that working and it's fine. You probably mean that the bit is SET when copying from SPIDAT to the RXBUF. But thank you anyways :)
  • Raghu,

    Please see the following post regarding SPI_INT Flag usage with FIFO enabled. Even if you are only using one word of the FIFO, the FIFO is still enabled and operating.
    e2e.ti.com/.../563115

    I believe that Santosh is referring to physically slowing down the SPI CLK frequency, but it appears that you are already operating at 292.3KHz? Is that correct?

    Can you share any screen captures of an oscilloscope showing the behavior? From my understanding, the SPI is operating as it should. If you load a single word into the SPITXBUF, the SPISTE signal will go active (low) until the full transfer is complete as long as there is no more data to transmit. You can do your own experiment here to verify that this is true by first just endlessly filling the fifo, and then adding delay in between each word. The SPISTE will toggle appropriately.

    -Mark
  • Questions - 

    1. Is my initialization correct? I am currently using ClockPolarity = 1 and ClockPhase =0 on my DSP. But the corresponding SPI mode on the Et1100 is as shown in the picture below. 

    2. The SPI read/write does not work as intended. I personally think THIS IS BECAUSE OF THE TIMINGS of the SPI.

    3. Is there some delay that I need to add in between the read/write. (The read/write functions are already provided). 

    4. Is there something that I might be missing? I have almost given up on this. Also from the oscilloscope I notice the SPI_CLK frequency fluctuating slightly. But I also understand that this protocol is Async and so it shouldn't matter as much. 

    Please help me understand what's going wrong (or atleast what might be going wrong).

    The picture below indicate the SPI mode I currently use of the ET1100. 

    The following picture below describes the Et1100 timing diagram. 

    The following picture below shows the actual timing diagram. Please note that the MISO (Et1100 to DSP) communication appears to be working but it's just a continuous pattern that does not make any informational sense)

    Thank you and sorry for all the spam. I am totally stuck and desperately need help. 

  • Hi Mark,

    Ok, I will read about the the SPI_INT flag and make the necessary update.

    Yes I am already using the lowest value which is indeed 292.3KHz. I am not using FIFO.

    I have just sent a message and hopefully that clears my questions/current state.
  • Raghu,

    yeah, the current code is good enough to refer, it works. Can you check the SPI initializations you have against the TI example code? The sysclk on F2837x for which the TI Design is for is 200MHz, the LOSPCP and SPI registers should be similar between your device and the reference design.

    Best Regards

    Santosh Athuru