1
\$\begingroup\$

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?

\$\endgroup\$
1
  • \$\begingroup\$ SPI is bidirectional, the unidirectional functions throw away half of the opportunity. You should be able to sort out which to use from that, of course you can always use the bidirectional one and do your own discarding of receive data or providing of dummy send data. \$\endgroup\$ Dec 26, 2018 at 22:55

2 Answers 2

1
\$\begingroup\$

SPI is a very specific interface and slave can only transmit if the master transmits. You have to transmit dummy data in order to receive something.

So you cant send 4 bytes and receive 7. You will need send as much data as it is needed.

On every byte sent by the master slave sends one byte too. If slave starts to send valuable data after 4 bytes received and you expect to receive 7 form the slave you need to send 11 bytes.

\$\endgroup\$
1
  • \$\begingroup\$ So in scenario 2 how many data shall I send-receive \$\endgroup\$
    – vamoirid
    Dec 27, 2018 at 2:30
1
\$\begingroup\$

An interesting observation from STM32Cube created HAL files for stm32f103: if SPI is configured as Master, HAL_SPI_Receive itself uses HAL_SPI_TransmitReceive. It sends garbage bytes in pData (buffer to receive bytes from the other end) as dummy bytes.

HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
  uint32_t tickstart;
  HAL_StatusTypeDef errorcode = HAL_OK;

  if ((hspi->Init.Mode == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES))
  {
    hspi->State = HAL_SPI_STATE_BUSY_RX;
    /* Call transmit-receive function to send Dummy data on Tx line and generate clock on CLK line */
    return HAL_SPI_TransmitReceive(hspi, pData, pData, Size, Timeout);
  }

 // ....
}

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.