Electrical – STM32F103C8T6 – I2C communication with TI FuelGauge BQ78350

fuel-gaugei2csmbusstm32texas instruments

I am trying to establish communication between TI BQ78350 FuelGauge and STM32F103C8T6 using I2C/SMBus. The following is the I2C configuration used for the standard HAL I2C library.

static void MX_I2C1_Init(void)
{

  hi2c1.Instance = I2C1;
  hi2c1.Init.ClockSpeed = 100000;
  hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
  hi2c1.Init.OwnAddress1 = 0;
  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c1.Init.OwnAddress2 = 0;
  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  if (HAL_I2C_Init(&hi2c1) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

}

When I try to transmit something to FuelGauge, using the following code there is no proper acknowledgement and response. Only the address byte is getting transmitted.

 HAL_I2C_Master_Transmit(&hi2c1,11<<1,0x09, 1, 100);

This is how the waveform looks in an oscilloscope.

I2C Waveform

On the hardware side, I am using BSS138 Mosfet to level shift between 5V fuel gauge and 3.3V STM32F103. Pull-up resistor value is 3.3k.

Any pointers to the cause of this issue would be helpful. Thank you.

Best Answer

Aside from the voltage and level conversion issues already mentioned; there is no problem in the transaction itself.

The MCU performs exactly what the code tells it to do. It may not be what you want though.

It transfers one byte from MCU memory to the chip I2C address.

The data is sent from pointer that is set to point to MCU address 0x09. This address apparently holds a byte 0x00 that is sent over the bus. Most likely you want to point to a buffer or variable that holds the data to be sent - in this case you most likely want to send 0x09 which is a command to read voltage.