Skip to main content
Explorer II
September 28, 2021
Question

I2C_HandleTypeDef structure for STM32F722ZETx doesn't have Device Address Anymore

  • September 28, 2021
  • 9 replies
  • 4703 views

Would anyone knows why the STM32F7xx

in stm32f7xx_hal_i2c.h structure I2C_HandleTypeDef doesn't have

 __IO uint32_t       Devaddress;   /*!< I2C Target device address        */

 __IO uint32_t       Memaddress;   /*!< I2C Target memory address        */

 __IO uint32_t       MemaddSize;   /*!< I2C Target memory address size     */

Is there any substitute function to query for the I2C device address?

    This topic has been closed for replies.

    9 replies

    Super User
    September 28, 2021

    By doesn't have one, do you mean the value is 0?

    Do you initialize this value anywhere in your code? It's your choice what you put here, it's not something inherent in the chip hardware.

    On second look, these fields are populated when you use the memory read/write functions. Otherwise, they are not applicable. Are you using those functions?

    Jtron.11Author
    Explorer II
    September 28, 2021

    These are the members of the I2C_HandleTypeDef struct that was auto generated code.

    The structure is defined in \Drivers\STM32F7xx_HAL_Driver\Inc\stm32f7xx_hal_i2c.h or \Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_i2c.h.

    These members are missing from the structure which was defined in STM32F7xx. I wonder if this is STM32 bug from auto generated code. I am using CubeIDE version 1.7.0.

    I was able to use the Devaddress member in STM32F4xx, but when I transfer the code to STM32F7xx, compiler complained there was no Devaddress, and that is why I know STM32F7xx is missing the members in the structure.

    Super User
    September 29, 2021

    Indeed in the F7 version of I2C_HandleTypeDef there's no such members.

    Note that struct I2C_HandleTypeDef is not a generated code. It is defined in the "static" part of the HAL library which is called by the generated code.

    It looks like F7 version of the library does not store the target address etc in the I2C controller state.

    Instead, it immediately sends this onto the wire.

    Jtron.11Author
    Explorer II
    September 29, 2021

    Thanks Pavel.

    Does it mean I can modify the structure? Without the info of the target address, if I have more than one slaves on the bus, and using the I2C TX/RX callbacks, I will not be able to determent which devices' instance the callback is for.

    In the STM32F4 I was utilized the device address to confirm the callback from which slaves so I can manipulate the next data in queues.

    Super User
    September 29, 2021

    Yes, you can modify the structure. But IMHO this is not a good idea. Better keep the current target address somewhere else.

    Jtron.11Author
    Explorer II
    September 29, 2021

    I don't want to touch the structure honestly. But I didn't find a way to figure out from what slave the STM32F7 got the HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef* hi2c) package from. I was trying to see if the I2C_TypeDef *Instance would carry some information from the slave address but I didn't find it yet.

    Super User
    September 29, 2021

    Store it in a global variable when you make the call that ends up triggering HAL_I2C_MasterRxCpltCallback. You can only be talking to one slave at a time.

    Jtron.11Author
    Explorer II
    September 29, 2021

    Thank you TDK. Meaning my bus will be locked until the the slave is answering the STM32 read command.

    Super User
    September 29, 2021
    Sort of. The master always controls the bus, except in the case of clock stretching. It’s never sitting there idle waiting for the slave to send a message.
    Jtron.11Author
    Explorer II
    September 29, 2021

    Agree the master not sitting there and wait for the message. My context discussion focus on the I2C bus only. And if we have to one slave to return the message from the master, it will defeat the purpose using interrupt method

    Super User
    September 29, 2021

    > it will defeat the purpose using interrupt method

    Not at all. The callback receives the I2C instance as parameter.

    If you run two master operations on two host controllers in parallel, just keep separate instances of slave address per controller.

    Jtron.11Author
    Explorer II
    September 29, 2021

    Pavel and TDK,

    May be I don't understand the operation correctly. Please correct me if I am wrong.

    Let say I am using STM32 as the master, I2C1 bus has 3 slaves sensors, and if I am using HAL_I2C_Mem_Read_IT() to read back the data from three sensors.

    The logic I check for the bus is HAL_I2C_STATE_READY then I use the Read_IT() to read sensor 1, then sensor 2, then sensor 3.

    What are you and TDK saying is my callback will in turn execute as sequence the data receiving back from sensor 1, sensor 2, and sensor 3?

    The bus will not be READY if I didn't receiving back data from any sensor hence the callback will not be called?

    Super User
    October 1, 2021

    > What are you and TDK saying is my callback will in turn execute as sequence the data receiving back from sensor 1, sensor 2, and sensor 3?

    I guess it is so, because only one slave (the addressed one) can be active at any time. The master always knows which slave it talks to.

    > The bus will not be READY if I didn't receiving back data from any sensor hence the callback will not be called?

    Well, if some I2C device does not respond, you need to think on the recovery. Try to poll it again, try send N zero bytes to flush the bus... this can get complicated.