0
\$\begingroup\$

I am using the HAL_I2C_Mem_Read library to read a register value but the last bit (8th bit) in the slave address is always 0 no matter which slave address I put. I use the Fuel Guage MAX17320 with a microcontroller STM32F105 to read and write to/from different register. The data sheet for MAX17320 https://www.analog.com/media/en/technical-documentation/data-sheets/MAX17320.pdf I want to read the register nDeviceName (121h) with slave address 0x16 but get always ACK failer because the HAL_I2C_Mem_Read() does not add 1 for the 8th bit which is needed for reading. This is the code in STM32Cube IDE

HAL_StatusTypeDef MAX30205_readTemp(uint8_t dev_address)
{
    HAL_StatusTypeDef ret;
    uint64_t tempData[2];
    // read from the register sDeviceName
    ret = HAL_I2C_Mem_Read(&hi2c1, dev_address, 0x121, 2, tempData, 2, HAL_MAX_DELAY);
    if(ret != HAL_OK)
    {
        return ret;
    }
    return HAL_OK;
}

this is how I call the function MAX30205_readTemp(uint8_t dev_address) and send the slave address:

 while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
      MAX30205_readTemp(0x16);
   /* USER CODE END 3 */
  }

Even if I do it like MAX30205_readTemp(0x16|0x01); or MAX30205_readTemp(0x16<<1|0x01); to make the last bit 1 for reading it will still be 0 and cause ACK failer. I have also decoded the I2C bus with an oscilloscope and it shows clearly that the last 8th bit is 0 instead of 1 for reading. this is the picture on the oscilloscope:

enter image description here

The picture below is to test for another slave address(0xD8)

enter image description here

I assume that something may be wrong in the configuration of I2C but do not know where and how to fix it. I use the STM32CubeIDE 1.10.1 version. It would be enormous help if someone knows how to fix it. Help Plz

\$\endgroup\$
4
  • \$\begingroup\$ An I2C Mem Read operation consists of (at least) 2 phases. First you write to the slave device to tell it what address or register you want to read from, then you read from the slave device to get the data from that address or register. So the fact that you see the initial access to your slave device with the LSbit set to 0 for a write is expected behavior. \$\endgroup\$
    – brhans
    Jul 24, 2023 at 17:02
  • \$\begingroup\$ In your 2nd scope pic you say you're testing device address 0xD8, but that's not a valid (7-bit) I2C address. What you show in that pic is an attempt to write to slave address 0x6C (with a NACK). \$\endgroup\$
    – brhans
    Jul 24, 2023 at 17:09
  • \$\begingroup\$ @brhans, I agree that it first writes to slave device to tell what address or register it should read from then it read from the slave address. As it shows it the data sheet for MAX17320 page 161. I thought that ret = HAL_I2C_Mem_Read(&hi2c1, dev_address, 0x121, 2, tempData, 2, HAL_MAX_DELAY); do all of it for me, both writing to slave device and reading from it. My question is now if some code is missing or do I need to have the HAL_I2C_Mem_Write() before HAL_I2C_Mem_read in order to read data from a register? \$\endgroup\$
    – Ali
    Jul 25, 2023 at 10:24
  • \$\begingroup\$ HAL_I2C_Mem_Read() does do the I2C write, followed by the I2C read. What you're seeing on your scope is the I2C write - as expected. That fact that you're not getting an ACK to that write is the real problem, and probably indicates that you have a hardware issue. \$\endgroup\$
    – brhans
    Jul 25, 2023 at 14:01

1 Answer 1

0
\$\begingroup\$

Of course it does not, or at least not to the place where you are looking for it.

To read data from a register, first the register address is written to the chip with write address, and then the data is transferred from the read address.

And so if it does not respond to address 0x16, there might be a hardware problem and the chip is not present on bus. The address is correct, the chip just does not acknowledge it, so STM32 HAL does not continue communication. If you bothered to check the result of HAL operation, it would indicate it did not succeed OK and error code would indicate ACK failure.

The addresd 0x16 is what you should use, not 0x17 (although it should work as the hal simply clears or sets the LSB for you), not 0x2C or not 0x2D either.

\$\endgroup\$
4
  • \$\begingroup\$ @brhans I don't know which HAL by whom you are using, but certainly the official STM32F1 HAL from ST does not left-shift the address by 1 bit. 0x17 would work because it ANDs away the LSB for writes and ORs the LSB for reads. \$\endgroup\$
    – Justme
    Jul 24, 2023 at 17:55
  • \$\begingroup\$ True - I must've been thinking of a different 'driver'. \$\endgroup\$
    – brhans
    Jul 24, 2023 at 20:57
  • \$\begingroup\$ @Justme, I understand that it has to first write to the slave device and then read it. I thought that HAL_I2C_Mem_Read() do it all for me. Do I need to have the HAL_I2C_Mem_Write before HAL_I2C_Mem_Read in order to read from the register nDeviceName (0x121) ? \$\endgroup\$
    – Ali
    Jul 25, 2023 at 10:41
  • 1
    \$\begingroup\$ @Ali Mem_Read does that for you - But the chip is not responding at all, so the Mem_Read fails at the part where it writes the register address. And if you read the data sheet, you can't give 0x121 as register address to the chip - if you want to access a register you need to give it an 8-bit register address which corresponds to register 0x121. But that is a completely separate issue. \$\endgroup\$
    – Justme
    Jul 25, 2023 at 11:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.