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.

TMS320F28335 SPI Slave - TXBUF problem with first byte in transmission sequence

Other Parts Discussed in Thread: TMS320F28335

Hi,

I am running into some problems with transmission when running the TMS320F28335
as an SPI slave.

I am using the SPIA port as slave, 8 bit word. LSPCLK = 75MHz. I am running the master SPICLK at
500 kHz to make sure that I am not encountering a timing issue.

1.- Reads from RXBUF are right aligned, writes to TXBUF are left aligned.
2.- RX and TX Buffers are enabled. RX FIFO level is 1, TX FIFO level is 0.
3.- When the system starts RXFFIENA is enabled, TXFFIENA is disabled

The DSP is emulating an EEPROM; When I do a read sequence I get the following
sequence of events.


<-- Master lowers #SPISTEA
<-- Master sends command byte ( SPICKL cycles 1..8 );
--> RXINT triggers in the DSP, the command is read from RXBUF and processed.

<-- Master sends address byte ( SPICKL cycles 9..16 );
--> RXINT triggers in the DSP, the adress is read from RXBUF and processed.
DSP writes 2 bytes into TXBUF and then enables the TXFFIENA

<-- Master drives SPICLK and keeps SPISTEA low ( SPICKL cycles 17..24 )

I would expect the first byte that I wrote into TXBUF to appear in the SOMI line
during SPICKL edges 17..24, but I get garbage instead (it is always the same
word)

<-- Master drives SPICLK and keeps SPISTEA low ( SPICKL cycles 25..32 )
I get the second byte that I wrote into TXBUF in the SOMI line


--> When TX int triggers I copy two new bytes to the TXBUF

(in fact my application is a read sequence of 20 bytes - master will keep the
SPICLK running - but I get 19 out, as I miss the 1st one, but it also seems that
the last byte remains in the queue, because I get it at the beginning of the
next read sequence).

---
Any idea what can be causing that the first byte is not getting transmitted?

Not enough time between the RXINT and the writing of the first byte in TXBUF?



---


Below is my configuration of the SPI

SpiaRegs.SPICCR.bit.SPISWRESET = 0;

// set SPI Configuration Control Register
SPICCR_REG shadowSPICCR;
shadowSPICCR.all = 0;
shadowSPICCR.bit.SPISWRESET = 0; // Initializes the SPI operating flags to the reset condition
shadowSPICCR.bit.CLKPOLARITY = 0; // shift clock polarity (mode 00)
shadowSPICCR.bit.SPICHAR = 0x7; // character length control bits
SpiaRegs.SPICCR.all = shadowSPICCR.all;

// set SPI Operation Control Register
SPICTL_REG shadowSPICTL;

shadowSPICTL.all = 0;
shadowSPICTL.bit.OVERRUNINTENA = 0; // enable receiver overrun interrupts
shadowSPICTL.bit.CLK_PHASE = 0; // normal SPI clocking scheme (mode polarity 0 - phase 0)
shadowSPICTL.bit.MASTER_SLAVE = 0; // SPI configured as slave
shadowSPICTL.bit.TALK = 1; // enable data transmission
shadowSPICTL.bit.SPIINTENA = 1; // enable SPI interrupts
SpiaRegs.SPICTL.all = shadowSPICTL.all;

// set SPI TX FIFO register

// Reset the Tx Fifo

SPIFFTX_REG shadowSPIFFTX;
shadowSPIFFTX.all = 0;
shadowSPIFFTX.bit.SPIRST = 1; // SPI FIFO can resume TX and RX
shadowSPIFFTX.bit.SPIFFENA = 1; // enable SPI FIFO
shadowSPIFFTX.bit.TXFIFO = 0; // enable TX FIFO
shadowSPIFFTX.bit.TXFFINTCLR = 1; // clear TX FIFO interrupt flag
shadowSPIFFTX.bit.TXFFIENA = 0; // do not enable TX FIFO interrupt, until there is something to send
shadowSPIFFTX.bit.TXFFIL = 0; // TX FIFO level
SpiaRegs.SPIFFTX.all = shadowSPIFFTX.all;

// set SPI RX FIFO register
SPIFFRX_REG shadowSPIFFRX;
shadowSPIFFRX.all = 0;
shadowSPIFFRX.bit.RXFFOVFCLR = 1; // clear RX FIFO overflow flag
shadowSPIFFRX.bit.RXFIFORESET = 1; // enable RX FIFO
shadowSPIFFRX.bit.RXFFINTCLR = 1; // clear RX FIFO interrupt flag
shadowSPIFFRX.bit.RXFFIENA = 1; // enable RX FIFO interrupt generation based on level
shadowSPIFFRX.bit.RXFFIL = 1; // RX FIFO level
SpiaRegs.SPIFFRX.all = shadowSPIFFRX.all;

// set SPI FIFO Control register
SpiaRegs.SPIFFCT.all = 0;

// set SPI Priority Control Register
SPIPRI_REG shadowSPIPRI;
shadowSPIPRI.all = 0;
shadowSPIPRI.bit.FREE = 1; // 11 mode -
shadowSPIPRI.bit.SOFT = 1; //
SpiaRegs.SPIPRI.all = shadowSPIPRI.all;

// Relinquish SPI from Reset

SpiaRegs.SPICCR.bit.SPISWRESET = 1;


SpiaRegs.SPIFFTX.bit.SPIRST = 0; // Reset the TX & RX Buffers
SpiaRegs.SPIFFTX.bit.SPIRST = 1;

SpiaRegs.SPIFFTX.bit.TXFIFO = 1; // Enable the FIFO

  • I suspect your phase and polarity settings may not be the same as you have configured on your master.  Pay particularly close attention to the waveforms in the user's guide.  The definitions of clock phase and polarity varies between manufacturers.  This can cause all of your bits to shift by 1, hence losing a bit at the beginning.

    Kris

  • Thanks Kris,

      I suspected polarity / phases issues as well. I believe it should be 0.0, but I tried all the other combinations just in case; Please note that the bits seem to be aligned, the problem is I am losing a full byte. I write the byte into the FIFO but get garbage in the SOMI line instead.

     

  • Okay, agreed if it is only one byte then it does not seem to be a phase/polarity issue.

    I think the problem may be a timing issue related to not writing to SPITXBUF soon enough.  Is it possible to have the master insert a break between the first 16 bits and the second 16 bits?  It sounds like it is one continuous clock, and I'm not sure you are processing your address and writing the data soon enough- as you indicated.  However, I would expect the first word to be delayed and see it on the following sequence.  If the FIFO were not setup correctly though, it is possible you are overwriting that data and losing that bit.  Can you verify the TXFIFO level after writing both byes into the SPITXBUF?

    In the setup you indicate that you have TXFFIENA disabled, but then you mention reloading SPITXBUF in the TX ISR.  Or are you just checking the flag?

  • Hi Kris,

     I did as you suggested and verified the levels in the queues, I was also playing with the contents of the loaded words and I think what I see confirms that problem is related to timing (i.e. there is not enough time to load the first byte into the shift register). I would try to explain what I see in case it may be helpful for others.

     1.- I can say with 99% confidence that what is happening is that SPI is shifting out only the 7 MSBits of the first byte that I load into the SPITXBUF, the rest of the bytes in my sequence are shifted properly. 

     2.- When I write the first word into SPITXBUF it goes directly into the SPIDAT register (i.e. I check the level of the TXFIFO before and after the "write SPITXBUF instruction" and the level is zero in both cases. When I write my second word into SPITXBUF the level of the FIFO is 1 as expected.

     3.- It seems that between the reception of the SPIRXINT and the time I write the SPITXBUF, SPIDAT has already shifted one bit into the SOMI, thus only 7 more bits from my first byte are shifted before my second byte gets loaded into SPIDAT.

    From my understanding of the data-sheet this behavior should not be possible; i.e. no word should be loaded from SPITXBUF into SPIDAT until the previous byte transmission has finished (Table 2-8: Serial Transmit Buffer Register (SPITXBUF) Field Descriptions - SPI Reference Guide). Maybe we are hitting a race condition here, but I have tried changing the speed of the LSPCLK ( tried with dividers 2 and 18 ) and in both cases I see the same behavior. I have also tried changing the PHASE, but I see the same.

    I am going to concentrate now in your suggestion of using a discontinuous SPI clock to allow for some time to process the address and copy the data into the Buffer. I will post if this fixes the problem.

  • Manuel,

    Thanks for the update.  It certainly sounds like a race condition may be happening, and if this is the case I agree it is not expected behavior for the SPIDAT to be loaded mid-transaction.  Let's see if we can isolate this down a bit further.

    Using a continuous master SPICLK, in the RX ISR where you load the TX buffer, can you toggle an IO before and after your writes to SPITXBUF and scope out this signal with respect to SPICLK?  This will help us better understand where the loads are actually occurring with the respect to transaction boundaries.  I am also interested to see what your expected data on the SOMI line is compared with the actual data.

    Kris

  • Thanks Kris, 

    Marking the writes into TXBUF with a GPIO toggle is a good very idea, I will give it a try and send you the results.

    Just to let you know, we have discontinued the SPICLK as you suggested and we can read all the bytes from the queue - including the first - We are currently working at 500 kHz SPICLK ( we transmit 8 CLKs and then keep the clock line at zero for the equivalent of 8 SPICLKs)... we are also trying to see how fast the SPICLK can get before we hit the problem.

  • The image attached shows the 8th of the address word (please note that the clock has been extended - I don't have a continous clock now) in D3,

    D15 is the toggling GPIO it is toggled before and after any write into TXBUF - note that I write 3 bytes every time. I have compiled the image in Release mode (optimization level 3) and I have disconnected the debugger.

    It seems it takes 2.9 usec from the RXINT till I start writing into the TXBUF (in a continuous clock scenario I would have spent one clock cycle already), I will follow this post with another one with a continuous clock.

  • And the image below corresponds to a continuous clock; the first marker is in the rising edge of the 8th clock, the second marker is in the toggled GPIO before the first write into the FIFO. As you can see there is another clock rising edge in between, so the data in SPIDAT has started being shifted.

  • Manuel,

    Not sure the attachments / images came through.  Can you try uploading again?  Let me know if you see them when you view the thread, may just be a browser issue.

    Kris

  • Hi Kris,

    The pictures were uploaded as links to my scope; I am uploading them as attachments now.

    Discontinuous clock

    Continuous clock

  • Hi,

    I'm following the discussion because I'm having a very similar problem with the communication between the F28335 configured as slave (using RX & TX FIFOs) and a Gumstix processor as a master over SPI protocol.

    I would really appreciate to know if the trouble was solved and how.

  • Hi,

      The problem in our case was that the ISR has not enough time to process the input and put a valid output in the RX register in a single cycle of the SPI CLK (@5MHz). By the time ISR writes into the TX register the SPI has started sifting the next byte.

     The solution was, as suggested by Kris, to discontinue the SPI CLK, i.e. we have 8 pulses of the clock at 5MHz and then we keep the clock low for a couple of micro seconds before the next 8 pulses, this gives enough time to the software to write into the register.

     I guess the alternative, if you can not control the clock, is to slow down the SPI CLK in the master side. 

     Hope it helps.