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.

about McSPI Transmit-and-Receive Procedure Polling Method

Hi,

I want to implement SPI master and slave to transmit and receive 5 bytes data at the same time,
and I use the following three steps, but there are some questions

(DRA75x_DRA74x_SR2.0_SR1.x_NDA_TRM_vAD)

Table 24-301. MCSPI Global Initialization
Table 24-304. MCSPI Transmit-and-Receive Mode Initialization
Table 24-308. Transmit-and-Receive Procedure – Polling Method

1. in Table 24-308,

Before I put the data into MCSPI_TXx, I had to wait until SPIm.MCSPI_CHxSTAT [2: 0] = 0x3?
(Master and slave made the same program)

2. in Table 24-308,
If I have 5 bytes to transmit and receive, is the following process right? but I can't get SPIm.MCSPI_CHxSTAT [2: 0] = 0x3
(Is Master and Slave set the same?)
=>set byte 1 in MCSPI_TXx
"Wait SPIm.MCSPI_CHxSTAT [2: 0] = 0x3"
=> get byte 1 from MCSPI_RXx
=> "Wait SPIm.MCSPI_CHxSTAT [2: 0] = 0x3"
=>set byte 2 MCSPI_TXx
=>...

PS: clock is 12MHz

thanks.

  • Hi Shawn,

    I have forwarded your question to SPI expert.

    Regards,
    Yordan
  • EPOL = 1

    POL = 0
    Master, PHA = 1
    Slave, PHA = 0
    Test pattern is 0xAA 0xAB 0xAC 0xAD 0xAE

    It seems to be able to send and receive test pattern at the same time,
    but (Master or Slave) sometimes it will be wrong, as follows
    ex:
    0xAA 0xAA 0xAB 0xAC 0xAD
    or
    0xAA 0xAB 0xAB 0xAB 0xAC
    or
    0xAA 0xAA 0xAA 0xAA 0xAA

    Is there any place or flow should I modify?

    thanks.

  • Your loop is correct but not efficient. This is not a big problem for the master, but the slave is very time-sensitive since transfers happen whenever the master is ready, regardless of whether the slave is ready. The slave must somehow ensure it is always ready for a transfer.

    This means that:

    1. the slave needs to write its first transmit byte before the master does so, otherwise McSPI will simply transmit whatever was still in the transmit register (i.e. the last byte transmitted).

    2. the slave must queue the next transmit byte as soon as this is allowed. If it waits until the first byte is received, it will probably be too late and again McSPI will transmit garbage when the master starts the next transfer. It also needs to read each byte before the next transfer completes, otherwise the byte will be lost.

     

    I would recommend enabling the transmit and receive FIFOs. Then you can simply queue all transmit data, let McSPI handle the individual byte transfers for you, and read the received data at your leisure:

    #define wait_until(condition) do /*nothing*/; while(!(condition))
    
    void do_spi_tx_rx( int count, u8 *rxdata, u8 const *txdata )
    {
    	assert( count <= FIFO_SIZE / 2 );
    
    	for( int i = 0; i < count; i++ ) {
    		assert( ! MCSPI_CHxSTAT.TXFFF );
    		MCSPI_TXx = txdata[ i ];
    	}
    
    	for( int i = 0; i < count; i++ ) {
    		wait_until( ! MCSPI_CHxSTAT.RXFFE );
    		rxdata[ i ] = MCSPI_RXx;
    	}
    }

    If for whatever reason you don't want to enable the FIFOs, then use a transmit-receive loop that performs a read or write whenever one is possible without assuming a particular sequence:

    void do_spi_tx_rx( int count, u8 *rxdata, u8 const *txdata )
    {
    	int ti = 0, ri = 0;
    
    	while( ri < count ) {
    		if( ti < count && MCSPI_CHxSTAT.TXS )
    			MCSPI_TXx = txdata[ ti++ ];
    
    		if( MCSPI_CHxSTAT.RXS )
    			rxdata[ ri++ ] = MCSPI_RXx;
    	}
    }

     

    These strategies can also be used to make the master more efficient of course, but that would make the slave even more time-critical.

     

    Also, be sure to enable the TX0_UNDERFLOW and RX0_OVERFLOW irqs on the slave. Then at least you will know when a transfer got corrupted because the slave wasn't ready in time.