5 years, 3 months ago.

What is HAL_SPI_TransmitReceive purpose and how it works

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 Answer

5 years, 3 months ago.

Hi Vasileios ,

For 4-wire SPI, which means basic SPI, HAL_SPI_TransmitReceive() is the one you should use.

But for 3-wire SPI, which means only one wire for DIN/DOUT, then you should use HAL_SPI_Transmit and HAL_SPI_Receive seperately, because the data transmitting and receiving are at different time frame.

Please feel free to ask my any questions!

- Desmond, team Mbed

Accepted Answer

Thanks a lot for the info. But how should I use the uont16_t Size argument in TransmitReceive function?

posted by Vasileios Amoiridis 02 Jan 2019

I would like to update my answer.

For 4-wire SPI, HAL_SPI_TransmitReceive() and HAL_SPI_Transmit() and HAL_SPI_Receive() are all free to use, it depends on what command you use.

If you are issuing write operations, then you can use HAL_SPI_Transmit() for only sending data out.

If you are issuing read operation, then you can use HAL_SPI_Transmit() to send command or address, then use HAL_SPI_Receive() to receive the data in, or you can just use HAL_SPI_TransmitReceive(). The value of size should be filled in the length of send+receive, in your case, which should be 11.

posted by Desmond Chen 03 Jan 2019