Skip to main content
craig239955_stm1_st
Associate III
April 26, 2016
Question

HAL_I2C_Slave_Receive_IT() with varying length

  • April 26, 2016
  • 12 replies
  • 5747 views
Posted on April 26, 2016 at 17:00

I've got an STM32F0 based I2C slave device which I'd like to send simple commands to, as well as updates containing additional bytes of data. 

HAL_I2C_Slave_Receive_IT() seems to require you to directly set the number of bytes you are waiting for however, so all received data must be the same length. Is there any way around this using the HAL system?

#!i2c #i2c-slave #no-hablo-hal #!stm32
This topic has been closed for replies.

12 replies

craig239955_stm1_st
Associate III
June 26, 2016
Posted on June 26, 2016 at 16:39

Still looking for a way to do this. Would really appreciate some input.

Tesla DeLorean
Guru
June 26, 2016
Posted on June 26, 2016 at 17:42

The protagonists for HAL really don't show up to support other users.

The I2C is not a high bandwidth connection, I suggest you process the bytes as received in a state machine to manage the stream and auto-increment the internal register count, etc.

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
Luca R
Associate II
August 28, 2017
Posted on August 28, 2017 at 12:28

Hi,

your thread is 1 year old, and maybe you already fixed everything.

I need to implement such a functionality, and I thought to use the HAL_I2C_Slave_Sequential_Receive_IT ,specifying '1' as lenght, and iterating it until the STOP condition is detected.

L

Harvey White
Senior III
August 28, 2017
Posted on August 28, 2017 at 22:07

Whether or not this will work for you depends on the I2C hardware implemented in your chip.  It does work for an L432.

I2C protocol can handle a variable length message.  The HAL software sets the stop condition after the number of bytes, so the slave terminates the transmission. 

However, the result is an AF error because the slave software did not know how much to receive.  Your message is there, it's fine, it just has that particular error.  Make a decision on whether or not the interface is busy and if you have any error other than an AF error.  If not busy and an AF error, then your message is good.  Set the maximum slave receive length to the length of the slave buffer.  Set the slave buffer length to more than any message you expect to receive.

This has been verified on 90 or so byte messages sent from an F446 to an L432.  Transmission from the L432 to the F446 has known length messages.  Worked for over 24 hours, 2.5 million transactions.

Please note that the AF error is at the slave end, the master should not show any errors.

Luca R
Associate II
August 29, 2017
Posted on August 29, 2017 at 16:33

If the master wants to write some data, it works, and the transaction is completed with AF error at the slave end.

Instead, if the master wants to read some data, I still don't know how to let it work: how can the slave know when all the requested data have been sent out to the master?

Harvey White
Senior III
August 29, 2017
Posted on August 29, 2017 at 17:12

OK, this requires you to have commands that you can define, written to the slave.  It also requires master read from slave capability.  This is for talking to processors, not hardware devices.

1) write variable length command to slave (your choice, mine by definition are...) get AF error in slave, ignore that.

all commands to slave are variable length.

2) write command to slave to return message byte count, read integer from slave (known length)

3) write command to slave (if desired) to read data.  Master now knows how much to read.  You could have just read from the slave, but this makes most everything a command/response scenario, which is easier to manage. 

Note that the only variable length message is to the slave which is handled by the slave.  All other transactions are of known length, which is required by the HAL read routines.

The command/response scenario closely duplicates the board to board demo, and is reliable.

ayarema
Associate II
August 30, 2017
Posted on August 30, 2017 at 20:38

Not sure if you still need an answer but why not do 2 transfers? First transfer is always say 2 bytes and that will be the size. Second transfer will be right after with the real data and now the size from transfer 1.

Sandro G
Visitor II
May 9, 2018
Posted on May 09, 2018 at 11:20

Use this:

void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c){

    // not enough bytes received causes an error, process the data anyway

    HAL_I2C_SlaveRxCpltCallback( hi2c );

}

I don't know how to find out how much data was actually received though. I use the first byte as a length indicator, so I don't need to know. Also, I guess this Error Callback could be triggered by other errors, so you probably should find out if the 'Error' is a stop condition.