Skip to main content
Graduate
March 13, 2024
Solved

Issues with I2C Direction Changes

  • March 13, 2024
  • 3 replies
  • 2151 views

Hello;

I am working with STM32CubeIDE, trying to connect a Nucleo-L4R5ZI board to an ADCS chip using I2C. The method of communication is very strange, requiring: [start condition] - [controller sends two bytes] - [start condition] - [controller sends one byte] - [controller reads several bytes] - [stop condition].

DeemDeem52_0-1710289722807.png

I wrote some code using the built-in HAL functions to try and accomplish this:

DeemDeem52_1-1710289820964.png

 

 

while (HAL_I2C_GetState(hi2c) != HAL_I2C_STATE_READY) {} // delay until ready

 HAL_I2C_Master_Seq_Transmit_IT(hi2c, ADCS_I2C_ADDRESS << 1, buf, sizeof(buf)/sizeof(uint8_t), I2C_FIRST_AND_NEXT_FRAME);

while (HAL_I2C_GetState(hi2c) != HAL_I2C_STATE_READY) {}

 HAL_I2C_Master_Seq_Transmit_IT(hi2c, ADCS_I2C_ADDRESS << 1, read_buf, sizeof(read_buf)/sizeof(uint8_t), I2C_FIRST_AND_NEXT_FRAME);

while (HAL_I2C_GetState(hi2c) != HAL_I2C_STATE_READY) {}

// I2C_FIRST_AND_NEXT_FRAME has start condition, no stop condition, and allows for continuing on with another I2C Seq command

 HAL_I2C_Master_Seq_Receive_IT(hi2c, ADCS_I2C_ADDRESS << 1, temp_data, data_length, I2C_LAST_FRAME);

while (HAL_I2C_GetState(hi2c) != HAL_I2C_STATE_READY) {}

 

 

This code works perfectly when trying to send data to the chip (the first four lines of code). Unfortunately, it fails to receive any data at all using the last two lines; the peripheral device seems to not even be triggered to send any data, so HAL_I2C_GetState remains in HAL_I2C_STATE_BUSY_RX indefinitely.

Can anyone think of a way to fix this?

Thank you!

    This topic has been closed for replies.
    Best answer by Andrew Neil

    @DeemDeem52 wrote:

    The method of communication is very strange


    What's so strange about it?

    As @TDK says, it's a common way to read "registers" in a slave; eg,

    AndrewNeil_0-1710334599480.png

     

    I find the ST documentation unhelpful in the way it classifies its I2C read functions as "IO" or "IO MEM" - without a clear description of the distinction between the two.

    In fact, "IO MEM" is the type to use here - the "registers" in the slave are, effectively, "memory" ...

    3 replies

    Graduate II
    March 13, 2024

    An actual part number would help to check the datasheet.

    But from the images, it looks like you can use HAL_I2C_Mem_Read_IT

    Super User
    March 13, 2024

    Doesn't this code send more than is specified in the datasheet? It sends buf and then read_buf, but the datasheet only says to send TLM ID, presumably only a single byte.

    Regardless, this is a common interface for reading/writing registers over I2C. HAL has this implemented in HAL_I2C_Mem_Read, including IT and DMA variants.

     

    Super User
    March 13, 2024

    @DeemDeem52 wrote:

    The method of communication is very strange


    What's so strange about it?

    As @TDK says, it's a common way to read "registers" in a slave; eg,

    AndrewNeil_0-1710334599480.png

     

    I find the ST documentation unhelpful in the way it classifies its I2C read functions as "IO" or "IO MEM" - without a clear description of the distinction between the two.

    In fact, "IO MEM" is the type to use here - the "registers" in the slave are, effectively, "memory" ...

    Graduate
    March 13, 2024

    That's good to know...  but in this case, the "Device Address" (0xAE the first time, and 0xAF the second time) is not the same as the actual device address (0x57). Does that change the function I need to use?

    Super User
    March 13, 2024

    The Slave Address is 0x57 - it is 7 bits.

    0xAE is a byte value with the Slave Address (0x57) in its top 7 bits, and its LSB (the R/W bit) set to 0;

    0xAF is a byte value with the Slave Address (0x57) in its top 7 bits, and its LSB (the R/W bit) set to 1.

    So, yes - they are all the same Slave Address.

     

    AndrewNeil_0-1710346832986.png

    https://www.nxp.com/docs/en/user-guide/UM10204.pdf