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.

TM4C1294NCPDT: EK-TM4C1294XL SSI Wait states are inserted at every byte transfer

Part Number: TM4C1294NCPDT
Other Parts Discussed in Thread: EK-TM4C1294XL

Hi,

I'm trying to optimize the SPI timing and my goal is to have a continuous clock frame without any pause between bytes.
I use  EK-TM4C1294XL to do my tests.

The SSI is configured as a master by using the following function:

   
    SSIConfigSetExpClk(SSI0_BASE, 120000000, SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, 1000000, 8);


My component need the SSI_FRF_MOTO_MODE_0 (Idle clock low and capture on first edge of clock)
I use SSI0 and it is configured at 1MHz clock.

To test it after configuration I write to SPI FIFO 4 bytes to be sure to not have any pause between bytes:

HWREG(SPI0_BASE + SSI_O_DR) = 0;
HWREG(SPI0_BASE + SSI_O_DR) = 0;
HWREG(SPI0_BASE + SSI_O_DR) = 0;
HWREG(SPI0_BASE + SSI_O_DR) = 0;


I have a scope plugged on the CLK pin to observe byte stream:



As you can see on the capture, there is a one clock pause between each bytes.

However If I change the format to SSI_FRF_MOTO_MODE_1 or  SSI_FRF_MOTO_MODE_3 then there is no pause between every bytes:



After discovering this I tryed all the mode and it seem that when Phase is 1, then there is a pause of one SPI clock between every bytes:
To resume:

  • SSI_FRF_MOTO_MODE_0 and  SSI_FRF_MOTO_MODE_2 have a pause between each bytes
  • SSI_FRF_MOTO_MODE_1 and  SSI_FRF_MOTO_MODE_3 DO NOT have a pause between each bytes


In the documentation it is not specified that there is a pause between every bytes.
The only part which say that there is a pause is in datasheet at 17.3.8 DMA Operation:

Note: Wait states are inserted at every byte transfer when using Bi- or Quad-SSI modes as a master with the μDMA at SSICLK frequencies greater than 1/6 of the system clock

However I do not use DMA here.
Note I also tryed with DMA and the same behavior is present.

Do you have an idea why there is a 1 SPI clock pause in the stream when Phase is 1?

Regards.

  • Hi,

    After discovering this I tryed all the mode and it seem that when Phase is 1, then there is a pause of one SPI clock between every bytes:
    To resume:

    • SSI_FRF_MOTO_MODE_0 and  SSI_FRF_MOTO_MODE_2 have a pause between each bytes
    • SSI_FRF_MOTO_MODE_1 and  SSI_FRF_MOTO_MODE_3 DO NOT have a pause between each bytes

    The gap is inherent to the design for mode 0 and mode 2. What type of slave device and application are you targeting? Normally, a slave device will wait for the SPICLK from the master to synchronize/stream the transaction. I wonder what type of slave will not work if a small gap exists. 

    There is a Frame Hold feature, not sure if this will help your slave device. It will keep the CS active throughout the transactions. Of course, you can also manually use a GPIO to assert/control the CS signal. 

  • Hi,

    My device is working correctly, it is an SPI ETHERNET chip (NCN26010), which can be drived with a clock up to 25MHz.
    For now I drive it at 1MHz to test.

    After looking at the SPI clock I saw the gap and it is suboptimal in terms of tranfert times.
    Here in this mode I lost "time" compared to other mode:

    For example, here, the gap let time for another bit to be tranfered instead of the pause.

    So when I transfert a full Ethernet packets of about 1500bytes it mean that with the pause of one bits every bytes, 1499 bits was lost in terms of "times" pause  between each bytes.

    It's about 12.5% of the time lost because of this...

    So I will be forced to increase by about 12.5% my clock speed for "nothing" to get the same througoutput on the ETHERNET chip compared to if no pause was present...

    You said that "The gap is inherent to the design for mode 0 and mode 2", where is it specified?
    The same chip is drived by a Raspberry and there is no gap in the SPI clock, so is it a TIVA SPI limitation?

    Do you have a solution to optimize it?

    Regards

  • Hi,

      Now I understand the rationale to remove the gap in order to obtain max throughput. 

      Here is one long post with the same discussion. Peter in this post (close to the end of thread) has some code snippet using the QSSI Advance Mode to remove gaps. Please note that his code is only to remove a 24-bit stream that consists of three bytes. See if you can reference his method for the entire 1500 bytes. The Frame Hold feature I mentioned in my last reply is also employed in his code.

    https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/663485/tm4c129encpdt-qssi-hold-ssinfss-low-for-continuous-24-bit-transfer
  • Thank you very much to point to this thread.
    I have looked everywhere in datasheet, read and reread it so many times without any clue!

    The solution worked for me now the transfert is efficient.

    To resume:

    It's a sort of hack, it works but is not a defined behavior in datasheet.

    You must use manual CS if using DMA, because you need to end transfert with a special register settled on the last byte of the transfert in order to deassert the CS and DMA cannot do that automatically.

    The solution reside in this 2 lines of code (using advanced mode):

        SSIAdvFrameHoldEnable(SSI1_BASE);
        SSIAdvModeSet(SSI1_BASE, SSI_ADV_MODE_WRITE);

    However there is an errata which say that:



    So maybe with SSI1 it's not working correctly so better use SSI0 or SSI2 or SSI3.

    Regards.