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.

SPI slave not receiving data TMS570LS0432 with empty transmit shift register

Other Parts Discussed in Thread: TMS570LS0432, HALCOGEN

Greetings,

I have been trying to implement a SPI slave on the TMS570LS0432 launchpad and am unable to observe an RXBUF full interrupt when the transmit shift register has no data in it. 

Driver code is configured with HALCoGen on SPI3 with FreeRTOS.  The HALCoGen function 'spiSendData' correctly stages data in the TXBUF and transmit shift register(s).  'spiSendAndGetData' sends and receives data as long as the transmit shift register has data.  However, the interrupt stops occurring once the transmit data has been shifted out, even if all staged receive data has not been received by the slave.  For this reason, 'spiGetData' does not ever generate the RXFUL interrupt.  If I pre-load the tx shift register with a dummy word, receive interrupts are generated and everything works as expected, but since the txempty interrupt occurs when TXBUF is empty as well as when the shift register is empty, this method requires transmitting a least 2 dummy words on every data exchange with the master.

I've tested the same scenario bare metal, without freeRTOS and have the same results.

Any help would be appreciated.  The example code for spi master slave floating around only works for one exchange.

static void prvSpi3RxTask(void *pvParameters)
{
    uint16_t tx_word = 0x1234;
    uint16_t rx_word = 0x0000;
    spiDAT1_t dataconfig3_t;
    dataconfig3_t.CS_HOLD = FALSE;
    dataconfig3_t.WDEL    = TRUE;
    dataconfig3_t.DFSEL   = SPI_FMT_0;
    dataconfig3_t.CSNR    = 0xfe;
    //spiSendData(spiREG3, &dataconfig3_t, 1, &tx_word);
    for (;;)
    {

    	/**/
        // initiate SPI3 transmit receive through interrupt mode
    	if (g_release_spi3)

    	{
    		g_release_spi3 = 0;
    		
    		spiSendAndGetData(spiREG3, &dataconfig3_t, 1, &tx_word, &rx_word);

    	}
    }
}

note, 'g_release_spi3' is a global variable that is set in 'spiEndNotification' once all data has been transmitted and received.

My test setup is two tms570ls0432 launchpads, one configured as master and programmed to send and receive one word of data on a button press, the other configured as a slave.

  • Thanks for using the Hercules forum! An engineer has been notified of your question. 

  • Christopher,

    I think it's sync issue between Master and Slave.

    Help me with following question

    1) Are you using ENA pin? ( SPI in 5 pin / 4 Pin mode with ENA)? If not, then you need to make sure software is synced.. Meaning prepare slave before master transmits any data.

    2) Is variable "g_release_spi3" set in RX Interrupt notification or TX interrupt notififcation. It is better to set it in the RX interrupt notification because, by then both master and slave would have received all the programmed number of data and can start clean.

    3) Remember TX Interrupt is Enabled only in "spiSendAndGetData" API and it is disabled after last data is put in to the TX buffer.Even after TX interrupt is disabled there are still data transfers happening since there are 2 data ( since TX is 2 stage buffer ) already put in the buffer and yet to be transmitted. This is place where there are chances if you set the variable "g_release_spi3" in TX notification. I am assuming you have similar code for Master and Slave, so natuarally there are chances that they may go out of sync if TX notification is used to determine end of transfer. Try 5 Pin mode or set "g_release_spi3" in RX interrupt notification.

  • Thanks for the help.

    1) Are you using ENA pin? ( SPI in 5 pin / 4 Pin mode with ENA)? If not, then you need to make sure software is synced.. Meaning prepare slave before master transmits any data.

    I am not currently using the ENA pin, as my target hardware will not have this pin available.  The slave data is initialized before enabling interrupts for each transfer on the slave side.  I suppose this hits at the heart of my question though...  If the slave does not load data into the transmit buffer, will the rx interrupt still occur and will garbage data be transmitted?  Or will the rx interrupt fail to occur if no data is present in the tx buffer and shift register?  The later scenario is what I had been observing.

    2) Is variable "g_release_spi3" set in RX Interrupt notification or TX interrupt notififcation. It is better to set it in the RX interrupt notification because, by then both master and slave would have received all the programmed number of data and can start clean.

    The 'g_release_spi3" variable is set after both the tx and rx interrupts have been disabled after the last word transfer.  This is handled when the spi3 isr calls spi3EndNotification after the last tx and rx interrupts occur.  User code in this function sets the variable when both rx and tx report 'SPI_COMPLETE".

    I have since replaced this variable with a binary semaphore within the RTOS.

    3) Remember TX Interrupt is Enabled only in "spiSendAndGetData" API and it is disabled after last data is put in to the TX buffer.Even after TX interrupt is disabled there are still data transfers happening since there are 2 data ( since TX is 2 stage buffer ) already put in the buffer and yet to be transmitted. This is place where there are chances if you set the variable "g_release_spi3" in TX notification. I am assuming you have similar code for Master and Slave, so natuarally there are chances that they may go out of sync if TX notification is used to determine end of transfer. Try 5 Pin mode or set "g_release_spi3" in RX interrupt notification.

    5 pin mode is not currently an option, and 'g_release_spi3" is being set as suggested. 

    I have since traced the problem to the physical connections in my test setup.  Jumper capacitance was likely corrupting one or more of the signals between the master and slave.  I found that tilting the board just right would result in expected performance.  So, I shortened the connections between boards and things are looking pretty good now.  However, I am interested in finding out for sure if my suspicions are correct that data will not be shifted in or out if the tx buffer and shift register on the slave are empty.  Can you confirm that this is the case?

     

  • Christopher,

    Sounds like you got to the bottom of your issue.

    To answer your last question - it depends on whether or not you are using the SPIENA pin.

    If you don't use the SPIENA\ pin, then the master will transmit as soon as the transmit buffer is written and the slave will also make a transfer even if it has not been serviced.

    When you add the SPIENA\ pin - this acts as a hardware handshake (like a 'RDY\').  In that case, with SPIENA\ in use the slave will indicate not ready at the end of a transfer and stay in this state until it has been serviced.  If you write to the master transmit register and the master is also configured to use the SPIENA\ it will not begin shifting the new data until the handshake comes back from the slave saying it's ready again.

    This has the advantage of letting you avoid having to insert a 'maximum delay' between transfers...  If you don't use the SPIENA\ and the average time to respond on the slave is say 1ms but can be as bad as 10ms in some cases (I'm making these #'s up...)  then you would need to wait 10ms between each transfer on the master in order to avoid an overrun.

    On the other hand with SPIENA\ you can let hardware do the handshake and your average throughput will be closer to a rate determined by the 1ms it takes for the slave to respond.

    Again the #'s are just ones I made up to illustrate the point - but hopefully this makes the reason for the SPIENA\ pin more clear.