cancel
Showing results for 
Search instead for 
Did you mean: 

Support for ''repeated start'' in STM32 HAL I2C library

mduffy
Associate II
Posted on February 10, 2015 at 18:29

I am working with a slave I2C device (Kionix KX022 acccelerometer)  which uses a ''repeated start'' mechanism to send data requested by the master (STM32F405), e.g. to read two bytes of data (from register N and register N+1) the following sequence

Master                   Slave

---------------------    ------------------------

START

Slave Address + Write

                         ACK

N (starting register)

                         ACK

START (repeat)

Slave Address + Read

                         ACK

                         Data

ACK

                         Data

NACK

STOP

It appears the STM32F4xx HAL I2C library does not support this directly, since HAL_I2C_Master_Transmit() sends STOP after the data.

I just want to confirm this before writing some code (i.e. gluing together the HAL_I2C_Master_Transmit() and HAL_I2C_Master_Recieve() functions and removing the intervening STOP).

Thanks in advance,

Mike

#i2c-stm32f4xx
10 REPLIES 10
Posted on February 26, 2015 at 15:52

Hi Mike,

Regarding your needs, it seems that your I2C slave device have a comportment like a EEPROM memory. For this prefer to use HAL_I2C_Mem_Write or HAL_I2C_Mem_Read interface.

To give you more explanation about functionality of this interface :

1- First step of this interface is to send this sequence => START + Slave addr + R/W bit + ACK + Regvalue to write or read + ACK

2- Second step of this interface is to send this sequence => Repeated Start + Slave addr + R/W bit + ACK + DataValue to write or read on RegValue + ACK ….+ STOP

Hope that help,

Best regards,

Heisenberg.

dwheeler20874
Associate
Posted on April 22, 2015 at 23:36

I have a similar situation, using an STM32F401 to talk with an I2C device.  But I need to send a 6 or 7 byte command followed by a repeated start and a read of the response.  The HAL_I2C_MemRead function can't support this since it only works with an 8 or 16 bit address.  

What's the recommended way to use STM32Cube in this situation?

mduffy
Associate II
Posted on November 20, 2015 at 09:20

I know it's quite belated, but this turned out to be exactly the correct answer.  Thank you, Dr. Heisenberg.

mduffy
Associate II
Posted on November 20, 2015 at 09:26

David, start with the I2C memory read/write functions as Heisenberg suggested.  The code is pretty clear and you can modify it to send more bytes following the first write operation.  The read (following the repeated start in the code) should probably work without change.  There is no out-of-the-box solution for your requirement, it would appear.

Sorry for the late response to your question.  I originally glued Transmit and Receive together, but that did not work when using interrupts instead of polling.  The HAL_I2C_Mem_Read_IT interrupt version did.

LMI2
Lead
Posted on November 21, 2015 at 17:42

This is usefull. One question however.

What are the START and STOP you and Heisenberg mentioned. The functions are in stm32f2xx_hal_i2c.c file, but what do you mean by Start and Stop?

LMI2
Lead
Posted on November 22, 2015 at 00:42

I think I have an answer to my question,.but I am happy hear more about this anyway. The blocking functions I am using, do not have start and stop.

Hello,

How to use HAL_I2C_Mem_Write/Read in this case for TC74? There is no separate variable for Command and Data as shown below.

victagayun_0-1697301288043.png

 

Read (the lower picture):

 

 

uint8_t data;
HAL_I2C_Mem_Read(hi2c, DevAddress, (uint8_t)command, 1, &data, 1, timeout);

 

Write does not have repeated start so can use HAL_I2C_Master_Transmit as well. Or:

 

uint8_t data = ...;
HAL_I2C_Mem_Write(hi2c, DevAddress, command, 1, &data, 1, timeout);

 

 

Danish1
Lead II

For many peripherals, the only strict need for a repeated-start is when the peripheral is used in a multi-master system.

I2C may have more than one master. Any master may jump in while the bus is idle i.e. after a stop-condition.

If we have one master wanting to read an I2C memory, it writes the address it wants to read. Then it needs to issue an I2C-start-read to the memory. If this master were to issue a regular stop first, a second I2C master might win the bus and set up to read from a different address. So by the time the first master actually does its read, it reads from the wrong address.

For most of our systems, the only I2C master is the stm32. So that situation can never arise. And we can get away with separate reads and writes, with a stop condition between. But it might be that a particular unusual peripheral actually needs the repeated-start, so it would be necessary to double-check.

What do I personally do? I don't use HAL. I wrote my own library for the stm32 I2C peripheral that includes repeated-start.