cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_SPI_Receive_IT Also Transmits

Brian H
Senior

I am using STM32F105xx family, working with HAL_SPI API.  I have discovered that the call to HAL_SPI_Receive_IT causes whatever data is in the provided buffer to be clocked out on MOSI.  This issue is also discussed to some extent in this thread, but that thread is more focused on fixing the system behavior than discussing whether it's actually a bug in HAL.  

So...am I crazy or is this a bug?  If I call a "Receive" method that only takes a receive buffer, I shouldn't expect it to transmit that data, should I?

I'm working with TI's ADS1258 ADC which has a "direct read" mode meaning no command needs to be sent to read the next conversion result (technically, it watches the first three bits of MOSI; if they are all 1s or all 0s, it ignores the rest of MOSI and continues clocking out data on MISO for 32 bits).  If there is stale data in the buffer provided to HAL_SPI_Receive_IT, and that data happens to have a first byte that the ADS1258 recognizes as a command, then my attempt to "direct read" turns into an unexpected reconfiguring of the ADC.

Why does HAL_SPI_Receive_IT clock out any data at all?  Seems to me MOSI should be left alone.  

I can observe the MOSI signal with a logic analyzer and see that it's clocking out the bits that were in the receive buffer, and I can fix my ADC issue by clearing the buffer before providing it to HAL_SPI_Receive_IT.  But...I shouldn't have to do that, right?

Is there some use case I'm not imagining where one would want the "receive" API method to transmit data?  HAL_SPI_TransmitReceive_* are the methods meant to enable full-duplex operation...

As an aside, I haven't bothered trying to find out whether HAL_SPI_Transmit_* also puts received data into the buffer it was given...but I have definitely noticed that the HAL API is not const-correct so it certainly could.

4 REPLIES 4
PGump.1
Senior III

Hi,

SPI is full-duplex. Except for a couple of odd single wire modes.

I don't use HAL. However, HAL_SPI_TransmitReceive_IT() is the function you are looking for...

Kind regards
Pedro

AI = Artificial Intelligence, NI = No Intelligence, RI = Real Intelligence.
Saket_Om
ST Employee

Hello @Brian H 

In SPI, data is always exchanged between the master and the slave. Even if you are only interested in receiving data, the master must send dummy data to generate the clock pulses required for the slave to send data back. The HAL_SPI_Receive_IT function uses the provided buffer for this purpose, which is why you see the data being clocked out on the MOSI line.

The behavior you are observing is expected due to the full-duplex nature of SPI. To avoid unintended data being sent to your ADC, you should clear the buffer before passing it to HAL_SPI_Receive_IT. This ensures that only dummy data is clocked out on the MOSI line during the receive operation.

 

If your question is answered, please close this topic by clicking "Accept as Solution".

Thanks
Omar

@Saket_Om wrote:

The HAL_SPI_Receive_IT function uses the provided buffer for this purpose, which is why you see the data being clocked out on the MOSI line.

The behavior you are observing is expected due to the full-duplex nature of SPI. To avoid unintended data being sent to your ADC, you should clear the buffer before passing it to HAL_SPI_Receive_IT. This ensures that only dummy data is clocked out on the MOSI line during the receive operation.


This should be clearly stated in the HAL_SPI_Receive_IT function documentation.

Also HAL_SPI_Receive and HAL_SPI_Receive_DMA


@Saket_Om wrote:

In SPI, data is always exchanged between the master and the slave.


Indeed.

@Brian H for a description of this standard SPI operation, see:

https://community.st.com/t5/stm32-mcus-products/how-to-perform-spi-communication-within-a-board-master-and-slave/m-p/736881/highlight/true#M264814