<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://devzone.nordicsemi.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Read a register of MAX17260 using TWI</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/112257/read-a-register-of-max17260-using-twi</link><description>Hi, 
 I&amp;#39;m working on a custom board with an nRF52840 MCU and a MAX17260 fuel gauge IC interfaced via I2C. The goal is to read the voltage of a battery using the MAX17260. I&amp;#39;ve verified that my I2C communication is functional, as I&amp;#39;m able to read default</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Fri, 21 Jun 2024 05:02:48 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/112257/read-a-register-of-max17260-using-twi" /><item><title>RE: Read a register of MAX17260 using TWI</title><link>https://devzone.nordicsemi.com/thread/489836?ContentTypeID=1</link><pubDate>Fri, 21 Jun 2024 05:02:48 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:22b3099a-e433-487c-be01-aad58866a07b</guid><dc:creator>Mit Patel</dc:creator><description>&lt;p&gt;Thank you for support.&amp;nbsp;&lt;br /&gt; I will check with analogue device support team.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Read a register of MAX17260 using TWI</title><link>https://devzone.nordicsemi.com/thread/489778?ContentTypeID=1</link><pubDate>Thu, 20 Jun 2024 13:31:45 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:fc4f7be2-0ba1-47fe-8ad6-bfa3f5ee5547</guid><dc:creator>Sigurd</dc:creator><description>&lt;p&gt;Hi!&lt;/p&gt;
&lt;p&gt;If you are reading the correct values for the other register, then I don&amp;#39;t see why&amp;nbsp;MAX1726X_AVGVCELL_REG should be wrong. Maybe you can check with&amp;nbsp;analog devices support team:&amp;nbsp;&lt;span&gt;&lt;a href="https://www.analog.com/en/support.html"&gt;https://www.analog.com/en/support.html&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Read a register of MAX17260 using TWI</title><link>https://devzone.nordicsemi.com/thread/489676?ContentTypeID=1</link><pubDate>Thu, 20 Jun 2024 10:26:56 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:ec5ba1ee-ca29-465a-bd79-2404c0ef3429</guid><dc:creator>Mit Patel</dc:creator><description>&lt;p&gt;Hi Sigurd,&lt;br /&gt;I have followed the initialization and configuration process as per attached document.&amp;nbsp;&lt;a href="https://www.analog.com/media/en/technical-documentation/user-guides/modelgauge-m5-host-side-software-implementation-guide.pdf"&gt;https://www.analog.com/media/en/technical-documentation/user-guides/modelgauge-m5-host-side-software-implementation-guide.pdf&lt;/a&gt;&lt;br /&gt;I successfully read the design capacity register, which returns 3000 (0xbb8), matching the datasheet and confirming that my I2C read function is working correctly.&lt;br /&gt;As suggested I have read MAX1726X_AVGVCELL_REG register (0x19) returns &lt;strong&gt;47600(47600 *0.000078125 = 3.718)&lt;/strong&gt; as well as the MAX1726X_VCELL_REG voltage register (0x09) returns &lt;strong&gt;47596 (47596 *0.000078125 = 3.718).&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Issue:&lt;br /&gt;Using a multimeter, the voltage across the Vin and GND pins of the battery measures &lt;strong&gt;4.115V&lt;/strong&gt;, still does not match the data read via I2C. same as previously discussed.&lt;br /&gt;&lt;br /&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;
/**
 * Copyright (c) 2015 - 2021, Nordic Semiconductor ASA
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form, except as embedded into a Nordic
 *    Semiconductor ASA integrated circuit in a product or a software update for
 *    such product, must reproduce the above copyright notice, this list of
 *    conditions and the following disclaimer in the documentation and/or other
 *    materials provided with the distribution.
 *
 * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
 *    contributors may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * 4. This software, with or without modification, must only be used with a
 *    Nordic Semiconductor ASA integrated circuit.
 *
 * 5. Any software provided in binary form under this license must not be reverse
 *    engineered, decompiled, modified and/or disassembled.
 *
 * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA &amp;quot;AS IS&amp;quot; AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */
/** @file
 * @defgroup tw_sensor_example main.c
 * @{
 * @ingroup nrf_twi_example
 * @brief TWI Sensor Example main file.
 *
 * This file contains the source code for a sample application using TWI.
 *
 */

#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;string.h&amp;gt;

#include &amp;quot;app_error.h&amp;quot;
#include &amp;quot;app_util_platform.h&amp;quot;
#include &amp;quot;boards.h&amp;quot;
#include &amp;quot;nrf_delay.h&amp;quot;
#include &amp;quot;nrf_drv_twi.h&amp;quot;

#include &amp;quot;nrf_log.h&amp;quot;
#include &amp;quot;nrf_log_ctrl.h&amp;quot;
#include &amp;quot;nrf_log_default_backends.h&amp;quot;

/* TWI instance ID. */
#define TWI_INSTANCE_ID 0
#define MAX17260_ADDRESS 0x36

#define MAX1726X_STATUS_REG 0x00
#define MAX1726X_VALRTTH_REG 0x01
#define MAX1726X_TALRTTH_REG 0x02
#define MAX1726X_SALRTTH_REG 0x03
#define MAX1726X_ATRATE_REG 0x04
#define MAX1726X_REPCAP_REG 0x05
#define MAX1726X_REPSOC_REG 0x06
#define MAX1726X_AGE_REG 0x07
#define MAX1726X_TEMP_REG 0x08
#define MAX1726X_VCELL_REG 0x09
#define MAX1726X_CURRENT_REG 0x0A
#define MAX1726X_AVGCURRENT_REG 0x0B
#define MAX1726X_QRESIDUAL_REG 0x0C
#define MAX1726X_MIXSOC_REG 0x0D
#define MAX1726X_AVSOC_REG 0x0E
#define MAX1726X_REMCAP_REG 0x0F

#define MAX1726X_FULLCAPREP_REG 0x10
#define MAX1726X_TTE_REG 0X11
#define MAX1726X_QRTABLE00_REG 0x12
#define MAX1726X_FULLSOCTHR_REG 0x13
#define MAX1726X_RCELL_REG 0x14
//                             reserved for 0x15
#define MAX1726X_AVGTA_REG 0x16
#define MAX1726X_CYCLES_REG 0x17
#define MAX1726X_DESIGNCAP_REG 0x18
#define MAX1726X_AVGVCELL_REG 0x19
#define MAX1726X_MAXMINTEMP_REG 0x1A
#define MAX1726X_MAXMINVOLT_REG 0x1B
#define MAX1726X_MAXMINCURR_REG 0x1C
#define MAX1726X_CONFIG_REG 0x1D
#define MAX1726X_ICHGTERM_REG 0x1E
#define MAX1726X_AVCAP_REG 0x1F

#define MAX1726X_TTF_REG 0X20
#define MAX1726X_DEVNAME_REG 0x21
#define MAX1726X_QRTABLE10_REG 0x22
#define MAX1726X_FULLCAPNOM_REG 0x23
//                             reserved for 0x24
//                             reserved for 0x25
//                             reserved for 0x26
#define MAX1726X_AIN_REG 0x27
#define MAX1726X_LEARNCFG_REG 0x28
#define MAX1726X_FLITERCFG_REG 0x29
#define MAX1726X_RELAXCFG_REG 0x2A
#define MAX1726X_MISCCFG_REG 0x2B
#define MAX1726X_TGAIN_REG 0x2C
#define MAX1726X_TOFF_REG 0x2D
#define MAX1726X_CGAIN_REG 0x2E
#define MAX1726X_COFF_REG 0x2F

//                             reserved for 0x30
//                             reserved for 0x31
#define MAX1726X_QRTABLE20_REG 0x32
//                             reserved for 0x33
#define MAX1726X_DIETEMP_REG 0x34
#define MAX1726X_FULLCAP_REG 0x35
//                             reserved for 0x36
//                             reserved for 0x37
#define MAX1726X_RCOMP0_REG 0x38
#define MAX1726X_TEMPCO_REG 0x39
#define MAX1726X_VEMPTY_REG 0x3A
//                             reserved for 0x3B
//                             reserved for 0x3C
#define MAX1726X_FSTAT_REG 0x3D
#define MAX1726X_TIMER_REG 0x3E
#define MAX1726X_SHDNTIMER_REG 0x3F

//                             reserved for 0x40
//                             reserved for 0x41
#define MAX1726X_QRTABLE30_REG 0x42
#define MAX1726X_RGAIN_REG 0x43
//                             reserved for 0x44
#define MAX1726X_DQACC_REG 0x45
#define MAX1726X_DPACC_REG 0x46
//                             reserved for 0x47
//                             reserved for 0x48
#define MAX1726X_CONVGCFG_REG 0x49
#define MAX1726X_VFREMCAP_REG 0x4A
//                             reserved for 0x4B
//                             reserved for 0x4C
#define MAX1726X_QH_REG 0x4D
//                             reserved for 0x4E
//                             reserved for 0x4F

#define MAX1726X_MODELDATA0_START_REG 0x80
#define MAX1726X_MODELDATA1_START_REG 0x90

#define MAX1726X_STATUS2_REG 0xB0
#define MAX1726X_POWER_REG 0xB1
#define MAX1726X_ID_USERMEM2_REG 0xB2
#define MAX1726X_AVGPOWER_REG 0xB3
#define MAX1726X_IALRTTH_REG 0xB4
#define MAX1726X_TTFCFG_REG 0xB5
#define MAX1726X_CVMIXCAP_REG 0xB6
#define MAX1726X_CVHALFIME_REG 0xB7
#define MAX1726X_CGTEMPCO_REG 0xB8
#define MAX1726X_CURVE_REG 0xB9
#define MAX1726X_HIBCFG_REG 0xBA
#define MAX1726X_CONFIG2_REG 0xBB
#define MAX1726X_VRIPPLE_REG 0xBC
#define MAX1726X_RIPPLECFG_REG 0xBD
#define MAX1726X_TIMERH_REG 0xBE
//                             reserved for 0xBF

#define MAX1726X_RSENSE_USERMEM3_REG 0xD0
#define MAX1726X_SCOCVLIM_REG 0xD1
#define MAX1726X_VGAIN_REG 0xD2
#define MAX1726X_SOCHOLD_REG 0xD3
#define MAX1726X_MAXPEAKPOWER_REG 0xD4
#define MAX1726X_SUSPEAKPOWER_REG 0xD5
#define MAX1726X_PACKRESISTANCE_REG 0xD6
#define MAX1726X_SYSRESISTANCE_REG 0xD7
#define MAX1726X_MINSYSVOLTAGE_REG 0xD8
#define MAX1726X_MPPCURRENT_REG 0xD9
#define MAX1726X_SPPCURRENT_REG 0xDA
#define MAX1726X_MODELCFG_REG 0xDB
#define MAX1726X_ATQRESIDUAL_REG 0xDC
#define MAX1726X_ATTTE_REG 0xDD
#define MAX1726X_ATAVSOC_REG 0xDE
#define MAX1726X_ATAVCAP_REG 0xDF

#define MAX1726X_SERIALNUM0 0xD4
#define MAX1726X_SERIALNUM1 0xD5
#define MAX1726X_SERIALNUM2 0xD9
#define MAX1726X_SERIALNUM3 0xDA
#define MAX1726X_SERIALNUM4 0xDC
#define MAX1726X_SERIALNUM5 0xDD
#define MAX1726X_SERIALNUM6 0xDE
#define MAX1726X_SERIALNUM7 0xDF

#define MAX1726X_VFOCV_REG 0xFB
#define MAX1726X_VFSOC_REG 0xFF

#define BAT_DESIGN_CAPACITY 0xBB8         // 3000
#define BAT_EMPTY_VOLTAGE 0xA561          // 3.3 emplty voltage and 3.88 Recovery voltage
#define MODEL_CONFIG_VALUE 0x8400         // Model ID 0, Charge voltage higher than 4.2
#define CHG_TERMINATION_CURRENT 0x0640    // 250mA

/* Indicates if operation on TWI has ended. */
static volatile bool m_xfer_done = false;

/* TWI instance. */
static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE_ID);

/* Monitor Fuel Gauge Structure */
typedef struct Fuel_Gauge_Monitor {
  uint16_t voltage;
  uint16_t avg_voltage;
  uint16_t design_cap;
} Fuel_Gauge_Monitor;

typedef struct {
  uint16_t designcap;
  uint16_t ichgterm;
  uint16_t modelcfg;
  uint16_t vempty;
} max1726x_ez_config_t;

#define SWAP_BYTE(data) ((data &amp;lt;&amp;lt; 8) &amp;amp; 0xff00) | ((data &amp;gt;&amp;gt; 8) &amp;amp; 0x00ff)

typedef int (*interface_read_fn)(uint8_t device_addr, uint8_t* data, uint8_t len);
typedef int (*interface_write_fn)(uint8_t device_addr, uint8_t const* data, uint8_t len);

/* Fuel gauge Interface Structure */
typedef struct Fuel_Gauge_Interface {
  interface_read_fn MAX17260_Read_Data;
  interface_write_fn MAX17260_Write_Data;
} Fuel_Gauge_Interface;

/* ----------------------------- Global Variables -------------------------------------*/
Fuel_Gauge_Interface gInterface = {0};

/**
 * @brief TWI events handler.
 */
static void twi_handler(nrf_drv_twi_evt_t const* p_event, void* p_context) {
  switch (p_event-&amp;gt;type) {
  case NRF_DRV_TWI_EVT_DONE:
    //    NRF_LOG_INFO(&amp;quot;NRF_DRV_TWI_EVT_DONE\r\n&amp;quot;);
    m_xfer_done = true;
    break;
  case NRF_DRV_TWI_EVT_ADDRESS_NACK:
    //    NRF_LOG_INFO(&amp;quot;NRF_DRV_TWI_EVT_ADDRESS_NACK\r\n&amp;quot;);
    break;
  case NRF_DRV_TWI_EVT_DATA_NACK:
    //    NRF_LOG_INFO(&amp;quot;NRF_DRV_TWI_EVT_DATA_NACK\r\n&amp;quot;);
    break;
  default:
    //    NRF_LOG_INFO(&amp;quot;default\r\n&amp;quot;);
    break;
  }
}
/**
 * @brief UART initialization.
 */
void twi_init(void) {
  ret_code_t err_code;

  const nrf_drv_twi_config_t twi_lm75b_config = {.scl = 4,    // ARDUINO_SCL_PIN,
      .sda                                            = 5,    // ARDUINO_SDA_PIN,
      .frequency                                      = NRF_DRV_TWI_FREQ_400K,
      .interrupt_priority                             = APP_IRQ_PRIORITY_HIGH,
      .clear_bus_init                                 = false};

  err_code = nrf_drv_twi_init(&amp;amp;m_twi, &amp;amp;twi_lm75b_config, twi_handler, NULL);
  APP_ERROR_CHECK(err_code);

  nrf_drv_twi_enable(&amp;amp;m_twi);
}

int I2C_Write_Data(uint8_t device_addr, uint8_t* data, uint8_t len) {
  ret_code_t err_code;

  // Write register address to the MAX17260
  err_code = nrf_drv_twi_tx(&amp;amp;m_twi, MAX17260_ADDRESS, &amp;amp;device_addr, 1, true);
  nrf_delay_ms(100);
  APP_ERROR_CHECK(err_code);
  // while (m_xfer_done == false);
  // Read register data
  err_code = nrf_drv_twi_rx(&amp;amp;m_twi, MAX17260_ADDRESS, data, 2);

  nrf_delay_ms(100);
  NRF_LOG_FLUSH();

  return NRF_SUCCESS;
}

int I2C_Read_Data(uint8_t device_addr, uint8_t* data, uint8_t len) {
  ret_code_t err_code;

  err_code = nrf_drv_twi_tx(&amp;amp;m_twi, MAX17260_ADDRESS, &amp;amp;device_addr, 1, true);
  nrf_delay_ms(100);
  APP_ERROR_CHECK(err_code);

  err_code = nrf_drv_twi_rx(&amp;amp;m_twi, MAX17260_ADDRESS, data, len);
  APP_ERROR_CHECK(err_code);

  nrf_delay_ms(100);
  // NRF_LOG_FLUSH();
  return NRF_SUCCESS;
}

/**
 * @brief       MAX17260_Init.
 *              This function intialize interface of fuel gauge.
 * @param[in]   Structure of interface functions.
 * @return      void
 */
void MAX17260_Init(Fuel_Gauge_Interface interface) {
  memcpy(&amp;amp;gInterface, &amp;amp;interface, sizeof(Fuel_Gauge_Interface));
}

/**
 * @brief Writes to a register and verifies the write operation by reading back the value.
 *
 * @param[in] reg_addr The register address to write to.
 * @param[in] reg_data Pointer to the data to write.
 * @return 0 NRF_SUCCESS on success, otherwise an error code.
 */
uint8_t MAX17260_Write_And_Verify_Reg(uint8_t reg_addr, uint16_t* reg_data) {
  uint8_t i2c_data[2];
  uint16_t readback_data;
  int8_t retry   = 3;
  ret_code_t ret = NRF_SUCCESS;

  while (retry &amp;gt; 0) {
    ret = gInterface.MAX17260_Write_Data(reg_addr, (uint8_t*)reg_data, sizeof(uint16_t));
    if (ret != NRF_SUCCESS) {
      return 1;    // error
    }

    // Delay to ensure the write operation completes
    nrf_delay_ms(100);    // about 10ms

    // Read back the written register
    ret = gInterface.MAX17260_Read_Data(reg_addr, (uint8_t*)&amp;amp;readback_data, sizeof(uint16_t));
    if (ret != NRF_SUCCESS) {
      return 1;    // error
    }

    NRF_LOG_INFO(&amp;quot;Write and read back register: %d : %d&amp;quot;, readback_data, *reg_data);

    // Verify the written data
    if (readback_data == (*reg_data)) {
      return 0;    // no error
    } else {
      retry--;
    }
  }
  return 1;    // error
}

/**
 * @brief Checks if a power-on reset (POR) has occurred.
 *
 * @return 0 if no power-on reset, 1 if power-on reset, or NRF_SUCCESS on success, otherwise an error code.
 */
uint8_t MAX17260_Check_POR(void) {
  ret_code_t ret  = NRF_SUCCESS;
  uint16_t status = 0;

  ret = gInterface.MAX17260_Read_Data(MAX1726X_STATUS_REG, (uint8_t*)&amp;amp;status, sizeof(uint16_t));
  if (ret != NRF_SUCCESS) {
    return ret;
  }

  if ((status &amp;amp; 0x0002) == 0x0000) {
    return 0;    // No power on reset
  } else {
    return 1;    // Power on reset
  }
}

/**
 * @brief Clears the power-on reset (POR) flag.
 *
 * @return 0 if successful, 1 if an error occurs.
 */
uint8_t MAX17260_Clear_POR (void) {
  ret_code_t ret  = NRF_SUCCESS;
  uint16_t status = 0;

  ret = gInterface.MAX17260_Read_Data(MAX1726X_STATUS_REG, (uint8_t*)&amp;amp;status, sizeof(uint16_t));
  if (ret != NRF_SUCCESS) {
    return 1;    // error
  }

  status &amp;amp;= 0xFFFD;    // Clear the POR flag

  return MAX17260_Write_And_Verify_Reg(MAX1726X_STATUS_REG, &amp;amp;status);
}

/**
 * @brief Waits for the data to be ready after power up.
 */
void MAX17260_Wait_Data_Ready_After_Power_Up(void) {
  ret_code_t ret  = NRF_SUCCESS;
  uint16_t status = 0;

  ret = gInterface.MAX17260_Read_Data(MAX1726X_FSTAT_REG, (uint8_t*)&amp;amp;status, sizeof(uint16_t));
  if (ret != NRF_SUCCESS) {
    return;    // error, handle as needed
  }

  while ((status &amp;amp; 0x0001) == 0x0001) {
    nrf_delay_ms(100);    // about 100ms
    ret = gInterface.MAX17260_Read_Data(MAX1726X_FSTAT_REG, (uint8_t*)&amp;amp;status, sizeof(uint16_t));
    if (ret != NRF_SUCCESS) {
      return;    // error, handle as needed
    }
  }
}

/**
 * @brief Stores the original Hibernate Configuration value.
 *
 * @param[out] hibernate_config Pointer to the variable where the Hibernate Configuration value will be stored.
 * @return NRF_SUCCESS on success, otherwise an error code.
 */
ret_code_t MAX17260_Store_Original_HibCFG(uint16_t* hibernate_config) {
  ret_code_t ret = gInterface.MAX17260_Read_Data(MAX1726X_HIBCFG_REG, (uint8_t*)hibernate_config, sizeof(uint16_t));
  if (ret != NRF_SUCCESS) {
    return ret;
  }
  return NRF_SUCCESS;
}

/**
 * @brief Exits Hibernate mode.
 *
 * @return NRF_SUCCESS on success, otherwise an error code.
 */
ret_code_t MAX17260_Exit_Hibernate_Mode(void) {
  ret_code_t ret    = NRF_SUCCESS;
  uint16_t tempdata = 0x0090;

  ret = gInterface.MAX17260_Write_Data(0x60, (uint8_t*)&amp;amp;tempdata, sizeof(tempdata));
  if (ret != NRF_SUCCESS) {
    return ret;
  }

  tempdata = 0x0000;
  ret      = gInterface.MAX17260_Write_Data(MAX1726X_HIBCFG_REG, (uint8_t*)&amp;amp;tempdata, sizeof(tempdata));
  if (ret != NRF_SUCCESS) {
    return ret;
  }

  ret = gInterface.MAX17260_Write_Data(0x60, (uint8_t*)&amp;amp;tempdata, sizeof(tempdata));
  if (ret != NRF_SUCCESS) {
    return ret;
  }

  return NRF_SUCCESS;
}

/**
 * @brief Writes the configuration settings to the appropriate registers.
 *
 * @param[in] config Pointer to the configuration structure.
 * @return NRF_SUCCESS on success, otherwise an error code.
 */
ret_code_t MAX17260_Write_Configuration(const max1726x_ez_config_t* config) {
  ret_code_t ret = NRF_SUCCESS;

  ret = gInterface.MAX17260_Write_Data(MAX1726X_DESIGNCAP_REG, (uint8_t*)&amp;amp;config-&amp;gt;designcap, sizeof(uint16_t));
  if (ret != NRF_SUCCESS) {
    return ret;
  }

  ret = gInterface.MAX17260_Write_Data(MAX1726X_ICHGTERM_REG, (uint8_t*)&amp;amp;config-&amp;gt;ichgterm, sizeof(uint16_t));
  if (ret != NRF_SUCCESS) {
    return ret;
  }

  ret = gInterface.MAX17260_Write_Data(MAX1726X_VEMPTY_REG, (uint8_t*)&amp;amp;config-&amp;gt;vempty, sizeof(uint16_t));
  if (ret != NRF_SUCCESS) {
    return ret;
  }

  ret = gInterface.MAX17260_Write_Data(MAX1726X_MODELCFG_REG, (uint8_t*)&amp;amp;config-&amp;gt;modelcfg, sizeof(uint16_t));
  if (ret != NRF_SUCCESS) {
    return ret;
  }

  return NRF_SUCCESS;
}

/**
 * @brief Polls the ModelCFG.Refresh bit and waits until it is cleared.
 *
 * @return NRF_SUCCESS on success, otherwise an error code.
 */
ret_code_t MAX17260_Wait_For_ModelCFG_Refresh(void) {
  ret_code_t ret        = NRF_SUCCESS;
  uint16_t model_config = 0;

  do {
    ret = gInterface.MAX17260_Read_Data(MAX1726X_MODELCFG_REG, (uint8_t*)&amp;amp;model_config, sizeof(uint16_t));
    if (ret != NRF_SUCCESS) {
      return ret;
    }
    nrf_delay_ms(100);    // about 10ms
  } while ((model_config &amp;amp; 0x8000) == 0x8000);

  return NRF_SUCCESS;
}

/**
 * @brief Restores the original Hibernate Configuration value.
 *
 * @param[in] hibernate_config Pointer to the variable containing the original Hibernate Configuration value.
 * @return NRF_SUCCESS on success, otherwise an error code.
 */
ret_code_t MAX17260_Restore_Original_HibCFG(const uint16_t* hibernate_config) {
  ret_code_t ret = gInterface.MAX17260_Write_Data(MAX1726X_HIBCFG_REG, (uint8_t*)hibernate_config, sizeof(uint16_t));
  if (ret != NRF_SUCCESS) {
    return ret;
  }
  return NRF_SUCCESS;
}

/**
 * @brief Initializes the MAX17260 configuration.
 *
 * @return NRF_SUCCESS on success, otherwise an error code.
 */
ret_code_t MAX17260_Initialize_Config(void) {
  ret_code_t ret            = NRF_SUCCESS;
  uint16_t hibernate_config = 0;
  max1726x_ez_config_t max1726x_ez_config;

  max1726x_ez_config.designcap = BAT_DESIGN_CAPACITY;
  max1726x_ez_config.ichgterm  = CHG_TERMINATION_CURRENT;
  max1726x_ez_config.modelcfg  = MODEL_CONFIG_VALUE;
  max1726x_ez_config.vempty    = BAT_EMPTY_VOLTAGE;

  ret = MAX17260_Store_Original_HibCFG(&amp;amp;hibernate_config);
  ret += MAX17260_Exit_Hibernate_Mode();
  ret += MAX17260_Write_Configuration(&amp;amp;max1726x_ez_config);
  ret += MAX17260_Wait_For_ModelCFG_Refresh();
  ret += MAX17260_Restore_Original_HibCFG(&amp;amp;hibernate_config);
  if (ret != NRF_SUCCESS) {
    return ret;
  }

  return NRF_SUCCESS;
}

/**
 * @brief       MAX17260_Read_Design_Cap.
 *              This function read initial design capacity.
 * @param[out]  pointer to store read design capacity
 * @return      NRF_SUCCESS on success, otherwise an error code.
 */
ret_code_t MAX17260_Read_Design_Cap(uint8_t reg, uint16_t* data) {
  ret_code_t ret = NRF_SUCCESS;

  ret = gInterface.MAX17260_Read_Data(reg, (uint8_t*)data, sizeof(uint16_t));
  if (ret != NRF_SUCCESS) {
    return ret;
  }
  return NRF_SUCCESS;
}

/**
 * @brief       MAX17260_Read_Voltage.
 *              This function read voltage.
 * @param[out]  pointer to store read voltage
 * @return      NRF_SUCCESS on success, otherwise an error code.
 */
ret_code_t MAX17260_Read_Voltage(uint8_t reg, uint16_t* data) {
  ret_code_t ret = NRF_SUCCESS;

  ret = gInterface.MAX17260_Read_Data(reg, (uint8_t*)data, sizeof(uint16_t));
  if (ret != NRF_SUCCESS) {
    return ret;
  }
  return NRF_SUCCESS;
}

/**
 * @brief       MAX17260_Read_Average_Voltage.
 *              This function read voltage.
 * @param[out]  pointer to store read average voltage
 * @return      NRF_SUCCESS on success, otherwise an error code.
 */
ret_code_t MAX17260_Read_Average_Voltage(uint8_t reg, uint16_t* data) {
  ret_code_t ret = NRF_SUCCESS;

  ret = gInterface.MAX17260_Read_Data(reg, (uint8_t*)data, sizeof(uint16_t));
  if (ret != NRF_SUCCESS) {
    return ret;
  }
  return NRF_SUCCESS;
}

/**
 * @brief       MAX17260_Monitor.
 *              This function read all monitor parameter of battery.
 * @param[out]  Fuel Gauge Monitor parameter structure to store all read value
 * @return      NRF_SUCCESS on success, otherwise an error code.
 */
ret_code_t MAX17260_Monitor(Fuel_Gauge_Monitor* monitor) {
  ret_code_t ret = NRF_SUCCESS;

  ret = MAX17260_Read_Voltage(MAX1726X_VCELL_REG, &amp;amp;monitor-&amp;gt;voltage);
  if (ret != NRF_SUCCESS) {
    return ret;
  }

  ret = MAX17260_Read_Average_Voltage(MAX1726X_AVGVCELL_REG, &amp;amp;monitor-&amp;gt;avg_voltage);
  if (ret != NRF_SUCCESS) {
    return ret;
  }
  ret = MAX17260_Read_Design_Cap(MAX1726X_DESIGNCAP_REG, &amp;amp;monitor-&amp;gt;design_cap);
  if (ret != NRF_SUCCESS) {
    return ret;
  }

  NRF_LOG_INFO(&amp;quot;----------------------------------------------------&amp;quot;);
  NRF_LOG_INFO(&amp;quot;Voltage    : %d  : %x&amp;quot;, monitor-&amp;gt;voltage);
  NRF_LOG_INFO(&amp;quot;Avg Voltage: %d  : %x&amp;quot;, monitor-&amp;gt;avg_voltage);
  NRF_LOG_INFO(&amp;quot;Design cap : %d  : %x&amp;quot;, monitor-&amp;gt;design_cap);
  NRF_LOG_INFO(&amp;quot;----------------------------------------------------&amp;quot;);

  return NRF_SUCCESS;
}
/**
 * @brief Function for main application entry.
 */
int main(void) {
  uint8_t rc;
  Fuel_Gauge_Monitor monitor;
  APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
  NRF_LOG_DEFAULT_BACKENDS_INIT();

  NRF_LOG_INFO(&amp;quot;TWI sensor example started.&amp;quot;);
  NRF_LOG_FLUSH();
  twi_init();

  NRF_LOG_INFO(&amp;quot;********************* MAX17260_Init *************************\r\n&amp;quot;);
  Fuel_Gauge_Interface interface = {0};
  interface.MAX17260_Read_Data   = I2C_Read_Data;
  interface.MAX17260_Write_Data  = I2C_Write_Data;

  MAX17260_Init(interface);

  MAX17260_Check_POR();
  MAX17260_Wait_Data_Ready_After_Power_Up();
  MAX17260_Initialize_Config();
  MAX17260_Clear_POR();

  rc = MAX17260_Monitor(&amp;amp;monitor);
  if (rc != NRF_SUCCESS) {
    NRF_LOG_INFO(&amp;quot;Failed to MAX17260_Monitor\r\n&amp;quot;);
  }

  while (true) {
    nrf_delay_ms(500);
    NRF_LOG_FLUSH();
  }
}
&lt;/pre&gt;&lt;br /&gt;&lt;img style="max-height:240px;max-width:320px;" alt=" " src="https://devzone.nordicsemi.com/resized-image/__size/640x480/__key/communityserver-discussions-components-files/4/max17260_5F00_i2c_5F00_read_5F00_debug_5F00_logs.png" /&gt;&lt;/p&gt;
&lt;p&gt;Could there be any other reason ? Should I look into any other factors that might be affecting the readings?&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Thanks in advance!&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Read a register of MAX17260 using TWI</title><link>https://devzone.nordicsemi.com/thread/489540?ContentTypeID=1</link><pubDate>Wed, 19 Jun 2024 13:26:37 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:72f09f1c-e22d-456a-81a6-6797e87648e6</guid><dc:creator>Sigurd</dc:creator><description>&lt;p&gt;Hi!&lt;/p&gt;
[quote user=""]I have tried reading the voltage from the &lt;span&gt;MAX1726X_VCELL_REG&amp;nbsp;&lt;/span&gt;&lt;span&gt;register (&lt;/span&gt;&lt;span&gt;0x09)&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;and applying the formula &lt;strong&gt;read_voltage&amp;nbsp;&lt;code&gt;* 0.0078125 (46613*0.000078125 = 3.641)&lt;/code&gt;&lt;/strong&gt;[/quote]
&lt;p&gt;This looks correct to me. There is also the average voltage you can try to read (AvgVCell Register (19h))&lt;/p&gt;
&lt;p&gt;I see that in Zephyr, the&amp;nbsp;max17262 sensor driver does several steps during&amp;nbsp;initialization, but I&amp;#39;m not sure if that affects the voltage reading or not.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/nrfconnect/sdk-zephyr/blob/v3.5.99-ncs1/drivers/sensor/max17262/max17262.c#L223"&gt;https://github.com/nrfconnect/sdk-zephyr/blob/v3.5.99-ncs1/drivers/sensor/max17262/max17262.c#L223&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>