cancel
Showing results for 
Search instead for 
Did you mean: 

What is HAL_SPI_TransmitReceive purpose and how it works

Vasileios Amoiridis
Associate II

I am trying to understand how does this function works even though there are so many people complaining about it. My questions are these:

1) What is the difference between using this in my code:

HAL_SPI_Transmit (SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
HAL_SPI_Receive (SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)

and this:

HAL_SPI_TransmitReceive (SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)

I mean, if I use the Transmit function first and then immediately after it, I use the Receive function what's the difference with using only the TransmitReceive ?

The only problem I can think of is that of receiving while sending. For example let's say that I want to send 4 bytes to the Slave and receive from it 7 bytes. Then there are 2 scenarios:

1st Scenario: If my Slave device sends data only after the Master has sent all its data, which means that the Slave is going to wait the Master to send 4 bytes and then it (Slave) will start to send its data then the code that should work is the

HAL_SPI_Transmit(&hspi1,txData,4,TIMEOUTVALUE);
HAL_SPI_Receive(&hspi1,rxData,7,TIMEOUTVALUE);

because as far as I can think of, the TransmitReceive will start to receive from the beginning, so the first 4 receive bytes are going to be trash and the last 3 received are going to be the first 3 transmitted from the Slave?

2nd Scenario: If my Slave device sends data after the Master has sent only the first byte of its data, which means that the Slave is going to wait the Master to send 1 byte and then it (Slave) will start to send its data then the code that should work is the

HAL_SPI_TransmitReceive(&hspi1,txData,rxData,12,TIMEOUTVALUE);

(12 = 4 + 7 + one byte which is the first received byte, which is a dummy one because the Slave starts transmitting after the 1st byte is sent by the Master).

2) How does uint16_t Size variable used in the TransmitReceive function? If I want to send 4 bytes and simultaneously receive 7 am I going to use 11 in the function variable?

1 ACCEPTED SOLUTION

Accepted Solutions
Bob S
Principal

1st scenario is OK for separate tx and rx calls. If your slave starts sending data after it receives all 4 bytes from the master, then HAL_SPI_TransmitReceive() should be given a length of (4 + 7) = 11. And both tx and rx buffers should be at least 11 bytes long. You then ignore the first 4 bytes in the rx buffer and using rxBuffer[4] through [10] as the 7 received bytes (not 3 bytes that you mentioned). Note that this will send 11 bytes to the slave, not just the intended 4 bytes. Hopefully the slave ignores incoming data while transmitting.

2nd is not quite.

If your slave starts sending data after the 1st byte sent by master, and the master sends 4 bytes of actual data, and the slave sends 7 bytes, you have (1 master Tx byte + 7 slave Tx bytes) = 8 bytes total. The 2nd, 3rd and 4th bytes sent from the master occur at the same time as the 1st 3 bytes received from the slave. Ignore the 1st received byte and use the next 7.

View solution in original post

2 REPLIES 2
Bob S
Principal

1st scenario is OK for separate tx and rx calls. If your slave starts sending data after it receives all 4 bytes from the master, then HAL_SPI_TransmitReceive() should be given a length of (4 + 7) = 11. And both tx and rx buffers should be at least 11 bytes long. You then ignore the first 4 bytes in the rx buffer and using rxBuffer[4] through [10] as the 7 received bytes (not 3 bytes that you mentioned). Note that this will send 11 bytes to the slave, not just the intended 4 bytes. Hopefully the slave ignores incoming data while transmitting.

2nd is not quite.

If your slave starts sending data after the 1st byte sent by master, and the master sends 4 bytes of actual data, and the slave sends 7 bytes, you have (1 master Tx byte + 7 slave Tx bytes) = 8 bytes total. The 2nd, 3rd and 4th bytes sent from the master occur at the same time as the 1st 3 bytes received from the slave. Ignore the 1st received byte and use the next 7.

That was a very informative answer! I understood perfectly what you wanted to say and I feel that I am ready to use it! Thank you very much!