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.

TM4C123GH6PGE: Why does the SSI rx fifo need to be flushed for every transaction?

Part Number: TM4C123GH6PGE

Hi,

Hopefully a simple question and apologies if it has been answered somewhere else on the forum, but I couldn't find it.

SSI1 is configured as master and the function below sends txlen bytes from txdata buffer and stores the received bytes in rxdata buffer.

The function works perfectly! However if I miss out the line which flushes the rx fifo, the next time the function is called the received data contains some bytes from the previous exchange and I would like to understand why. Anyone know?

void SSI1exchange(uint8_t txlen, uint32_t *txdata)
{
	uint32_t flush;
	static uint32_t rxdata[256];
	
	while(ROM_SSIDataGetNonBlocking(SSI1_BASE, &flush)) ;	//flush SSI1 rx fifo
	
	for(i=0;i<txlen;i++) {
		ROM_SSIDataPut(SSI1_BASE, txdata[i]);	//send bytes out of SSI1
		ROM_SSIDataGet(SSI1_BASE, &rxdata[i]);	//store the bytes coming back
	}
}

  • Hi Richard,
    What might have happened is that the SSI1exchanged() is called when there is still uncompleted transmission on the bus. How is the SSI1exchanged called? Is it called by the interrupt ISR? Which interrupt source? Can you try to wait for the end-of-transmission interrupt? The end-of-transmission indicates that the data has been transmitted completely. Since the transmitted data and received data complete at exactly the same time, the end-of-transmission interrupt can also indicate that the read data is ready immediately.
  • Hi Charles, thanks for your reply.
    The SSIDataGet() is a blocking function that will wait until it has a word to pick up from the rx fifo. This ensures that the DataPut must have finished before we carry on. I have checked this by putting a while(ROM_SSIBusy(SSI1_BASE)) ; after the DataPut, and it makes no difference.
    The SSI1exchange() is called rarely in my code and always with a long gap between calls. I do a rx fifo flush during initialisation as that makes sense, but I don't see why it is needed before every transaction. It infers that something is changing the fifo pointers or counters that the DataGet() uses. Or maybe I am misunderstanding the mechanism??
  • Hi Richard,
    I agree that the blocking SSIDataGet() after the SSIDataPut() should clear the RX fifo if you do truly empty the TX FIFO first. Do you know what was still remaining in the RX FIFO. I will suggest for debugging purpose you will not flush the FIFO but instead store the data in a buffer and see if you can relate that data to something that might have come in that you didn't completely read out by the CPU earlier.

    Before you call the SSI1exchanged () what was the RIS register indicating? One more thing as I asked in my prior post, are you in interrupt mode or polling?
  • Richard Bland said:
    This ensures that the DataPut must have finished before we carry on.    I have checked this by putting a while(ROM_SSIBusy(SSI1_BASE)) ;   after the DataPut, and it makes no difference.

    I was intrigued by this issue - and by your (logical) attempt at a solution.      I've no access to any of our TM4C boards at this time - but DO have a SWAG or two - to offer up...

    In particular - I have a "hunch" that your REPLACING that "ROM_SSIBusy()" - with a standard (& sufficient) "Time Delay" (sandwiched between DataPut & DataGet - just as you noted) may resolve.    I am asking for an "Expanded Guard-Band" - exceeding that provided by  "ROM_SSIBusy()" alone.     (my parole officer advises that I (should) be "humored.")

    You further state, "The next time the function is called [but minus the flush function] the received data contains some bytes from the previous exchange - and I [fairly] - would like to understand why."   

    Me too!     Let the interrogation begin:

    • With the "flush" function - absent/removed - do those "previous bytes"  ALWAYS appear?     (i.e. each/every time?)     If not - please detail.
    • What number (even percentage, too) of  "bytes received" are the (unwanted/illegal "previous bytes?")
    • What is the typical length (in bytes) of your data transfer?    (i.e. "txlen")       What results if you limit "txlen" to 8 bytes or less?     (so it fits entirely w/in the "FIFO")
    • Is it assured that you are NOT reporting a (dreaded) ... "Single Board Anomaly?"     (bane of Diagnostic crüe - always!)
    • Have you reduced the speed of the SPI clock (i.e. cut in half) and observed if the issue persists - or changes in (any) manner?
    • Is your board "vendor supplied?"     Is it adequately powered & "rich" in power pin bypass caps?
    • Are there, "Aspects of your code" (say intense (almost) inescapable program loops) and/or:  close proximity to RF, High Currents or Noise Sources - which may cause/contribute to this issue?

    Should those "magnificent seven" (above) not resolve - would it not prove instructive to,  Provide a "Sequence of Incrementing Bytes" - via "DataPUT()" - so that  you may "more easily recognize" any "Positional Bias" - revealed by the location of these "previous bytes" - w/in your data stream.      (we thus far have minimal "clues" - my attempt is to "Tease out" MORE!)

  • Hi cb1,
    Thanks for your magnificent seven things to investigate!
  • Hi Charles,

    You DO ... read thru my postings!    Let the record show that the final paragraph was "excised" from the earlier appearing group - so that a past "movie title" - could be (almost) seamlessly, "worked in."   (i.e. "magnificent eight" ... Not so much - even the parole officer/drinking partner noted!)

    And to think that "LIKE" has been banned here.   Pity!      (Big Brother proves "not especially" inspired...)