cancel
Showing results for 
Search instead for 
Did you mean: 

Problem with STM32H7 HAL SPI Slave - How to deal with unknown message length and reception time

ASmith
Associate II

Hello all,

I am using an STM32H7 and STM HAL drivers V1.2.0, SPI slave in interrupt mode.

My requirements are as follows:

  1. Receive messages of unknown size
  2. Receive messages at any time
  3. Ability to transmit at any time

So far I am having the following issues with the HAL SPI slave implementation:

  1. HAL expects a known fixed size for receptions
  2. To receive a message I need to call HAL_SPI_Receive_IT

I have tried continuously calling the HAL_SPI_Receive_IT with a fixed buffer size (pending on a completed reception via the RxCallback). This did enable me to populate and parse a ring buffer for messages. The issue I am seeing with this is that the receive function is setting the HAL_SPI_STATE_BUSY_RX state variable which prevents HAL_SPI_Transmit_IT from executing. Meaning, I can receive successfully but I cannot transmit while I have a receive queued.

Is there a way to tailor the HAL SPI implementation to fit my requirements, or would I need to write my own?

Thank you!

5 REPLIES 5
Bob S
Principal

not tested but *should* work 🙂 When you decide you have a complete incoming message call SPI_Abort_IT(), then call SPI_Transmit_IT() to send your response message.

ASmith
Associate II

Hey Bob, thanks for the response!

Your suggestion definitely helps as you've added another tool to our belt.

My problem is that I am essentially queue-ing a large buffer to be received which prevents the transmit from executing. The slave needs to receive much less frequently than it needs to transmit - the master is only transmitting roughly once every 2 minutes while the slave is continuously needing to transmit. This means that if I queue a reception, the slave is waiting on those bytes to come through which is hindering its ability to transmit.

Hope that makes sense. Unfortunately, my inter-processor SPI communication protocol does not always follow the request-response format which is why I am running into this issue.

Hey Bob, thanks for the response!

Your suggestion definitely helps as you've added another tool to our belt.

My problem is that I am essentially queue-ing a large buffer to be received which prevents the transmit from executing. The slave needs to receive much less frequently than it needs to transmit - the master is only transmitting roughly once every 2 minutes while the slave is continuously needing to transmit. This means that if I queue a reception, the slave is waiting on those bytes to come through which is hindering its ability to transmit.

Hope that makes sense. Unfortunately, my inter-processor SPI communication protocol does not always follow the request-response format which is why I am running into this issue.

Bob S
Principal

So is it something like this: Master sends you a message, you start sending data. Some time later the master sends another message, etc.? Is there no slave select or framing signal to tell you when to stop sending data and start receiving a message from the master?

If there is no framing or slave select that helps, does it matter WHAT you send to the master when the master is sending you a message? Can you continue to send data? If so, how about something like this:

Use HAL_SPI_TransmitReceive_IT() to send your data instead of Just the "transmit" version. Check the Rx buffer for start of (and possible all of) a message from the master. This presumes that the messages, specifically the first byte of a message, is different than what the master sends while receiving data (or that the master tri-states the MOSI line when receiving data).

Without more details of your protocol, it is difficult to go much further.

The slave is always sending and it asserts a GPIO to notify the master that it has something to send. The master then begins shifting 00s until the complete message is received. There is no SS or framing signal coming from the master which tells the slave to start receiving, it should always be ready to receive. The protocol does have start and end delimiters for each message (both non-zero).

It does not matter what is sent during the reception of a message, the master will not listen to it because the GPIO is not asserted.

I do like the idea of incorporating the TransmitReceive function instead of the Transmit. I may end up just calling the Abort function (for the Rx) if a Tx is requested by the slave and then call TransmitReceive to catch any potentially remaining bytes, however I am unsure of the masters behavior if it gets interrupted during a transmit. Will need to test this tomorrow.

Appreciate your willingness to help!