cancel
Showing results for 
Search instead for 
Did you mean: 

Do i need one handle per I2C slave device or per STM32 I2C interface?

Patrick Morwald
Associate II
Posted on July 17, 2017 at 17:09

Hi,

i have multiple slaves on an I2C bus on STM32F4. 

Since a 'I2C_HandleTypeDef hi2c_x;' contains also fields like 'DevAddress', do i need one HandleTypeDef per slave device on the bus or should they share one handle? Sorry if its a trivial question i just want to clarify whats the proper approach and couldnt find the answer in the HAL Driver description documents.

Thanks for your help,

Patrick

#stm32f4 #i2c
6 REPLIES 6
Posted on July 17, 2017 at 17:43

Hello!!   you don't need to have one handle per slave.

The 'DevAddress' field you mention is  filled internaly.

In every HAL_I2C...  transaction  function you can put the external device address you want to transact.

Patrick Morwald
Associate II
Posted on July 17, 2017 at 18:34

Hi,

thanks for your answer.

Does HAL take care of multiple slaves accessing the bus? I have a framework of processes which access one bus. Do i have to write myself a bus manager module which handles access in queues?

I assume my multiple processes overwrite each others I2C address in the 'DevAdress' member of their shared I2C handle 'hi2c'. Thats why i thought i maybe need a separate handle for each slave...

I also would like to learn more about the available HAL functions to coordinate such a multiple actor access, but found the UM1725 description of the HAL drivers not enough. In the I2C section many potentially useful functions are barely explained. Can you point me to better ressources?

Thanks,

Patrick

john doe
Lead
Posted on July 17, 2017 at 18:38

Your STM32F4 may have up to 3 I2C peripheral busses. I2C1, I2C2, I2C3 for example. As a naming convention, in the HAL code, they would be hi2c1, hi2c2, hi2c3. Each I2C bus can have as many slaves as your address space and pull-up resistors allow

This is how I do it, but I'm just a hobbyist not a pro.

For this discussion, let us say the I2C address is 'dev_addr'. First thing I do is make sure the device will answer

    while (HAL_I2C_IsDeviceReady(&hi2c1, (uint16_t)(dev_addr<<1), 3, 100) != HAL_OK) { }

Ok then, if we get past that, we can try to read a register

      HAL_StatusTypeDef status = HAL_OK;

      uint8_t array[24] = {0};

      status =  HAL_I2C_Mem_Read_IT(&hi2c1,                    // i2c handle

                              (uint8_t)(dev_addr<<1),        // i2c address, left aligned

                              (uint8_t)reg_addr,            // register address on the slave i want to read

                              I2C_MEMADD_SIZE_8BIT,            // random device uses 8bit register addresses. eeprom uses 16bit usually

                              (uint8_t*)(&array),            // write returned data to this variable named array

                              cnt);                            // how many bytes to expect returned

    if (status != HAL_OK)

    {

       switch (status)

         {           

            case HAL_ERROR: do error stuff; break;             

            case HAL_BUSY: do busy stuff; break;           

            case HAL_TIMEOUT: do timeout stuff; break;       

         }

   }

and dont forget to add the callback

void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c)

{

   if (hi2c->Instance = I2C1)

   {

     // do stuff when the transfer on hi2c1 is complete

   }

}

Posted on July 17, 2017 at 19:22

hello again !

By its nature every I2C transaction cannot be interrupted until finish, or else it will not be completed. (There is one bus and in your case, one master) If you are able to synchronize  the transactions between threads without interruptions  then, its ok.

 HAL_I2C functions have return values of type HAL_StatusTypeDef. OK, ERROR, BUSY, TIMEOUT are returning values for your use.

Methods of managing an ic2 bus  may include periodic transactions  and hardware interrupts initiated from devices.  

In my opinion, the best way to learn about the HAL functions is to analyze each function you want to learn  (c file)  spending probably a lot of time.

Posted on July 17, 2017 at 19:25

>Can you point me to better ressources?

STM32Cube_FW_F4_V1.16.0/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h and stm32f4xx_hal_i2c_ex.h and corresponding .c files in Src

STM32Cube_FW_F4_V1.16.0/Projects/STM32446E-Nucleo/Examples/I2C/ or whatever your board is

Posted on July 18, 2017 at 09:54

Hi,

thanks for your input. I will dig a little more into HAL source code and see how to synchronize my processes.

Thanks,

Patrick