cstm32cpu-registershaltexas-instruments

STM32 and BQ25713 it can not Read / Write to a register via I2C correctly


I am using Texas instruments BQ25713 charger. When we programming BQ25713 via I2C, it cannot write/read a value to any register correctly.

E.g.; Not able to read ManufacturerID() 0x2E

Expected: 0x2E / 0x002E

Result: 0x2E41

I've also tried with DeviceID() - ChargeCurrent() - ChargeOption0() - MaxChargeVoltage() and others but I got wrong read and write again.

There is only one exception, that is CHRG_OK -> AC_STAT is working well. it can see input present / no present.

I2C_ADDRESS: 0xD6(6B). (I didn't find any problem about I2C address)

From Datasheet;

9.5 Programming The charger supports battery-charger commands that use either Write-Word or Read-Word protocols, as summarized in Section 9.5.1. The I2C address is D6h. The ManufacturerID and DeviceID registers are assigned identify the charger device. The ManufacturerID register command always returns 40h.

    #define BQ25713_REG_I2C_ADDRESS 0xD6 // I2C Address (R) Converted to 8 Bit from 6Bh
    #define BQ25713_REG_MANUFACTURER_ID 0x2E // MANUFACTURER ID (R) // I've also tried as 0x002E
    
    checkBitsAndControlLEDs(BQ25713_REG_MANUFACTURER_ID);

    uint16_t SetI2CData(uint16_t regAddress, uint16_t regValue) {
        HAL_StatusTypeDef status;
        uint8_t regValSet8[2];
    
        // Seperation as LSB ve MSB 
        regValSet8[0] = regValue & 0xFF;          // LSB 
        regValSet8[1] = (regValue >> 8) & 0xFF;   // MSB 
    
        // is Device Ready
        status = HAL_I2C_IsDeviceReady(&hi2c1, BQ25713_REG_I2C_ADDRESS, 3, HAL_MAX_DELAY);
        if (status != HAL_OK) {
            // Cihaz hazır değil, hata durumunu göster
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET);
            HAL_Delay(300);
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET);         
        }
        // Write LSB   
        status = HAL_I2C_Mem_Write(&hi2c1, BQ25713_REG_I2C_ADDRESS, regAddress, I2C_MEMADD_SIZE_16BIT, &regValSet8[0], 1, HAL_MAX_DELAY);
        if (status != HAL_OK) {
            // Error LSB
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET);
            HAL_Delay(300);
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET);    
        }
    
        // Write MSB
        status = HAL_I2C_Mem_Write(&hi2c1, BQ25713_REG_I2C_ADDRESS, regAddress + 1, I2C_MEMADD_SIZE_16BIT, &regValSet8[1], 1, HAL_MAX_DELAY);
        if (status != HAL_OK) {
            // Error MSB
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET);
            HAL_Delay(300);
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET);      
        }
    
    
        return 0; 
    }
    
    uint16_t ReadI2CData(uint16_t regAddress) {
    
        uint8_t readData[2];
        HAL_StatusTypeDef status;
    
        // Check device
        status = HAL_I2C_IsDeviceReady(&hi2c1, BQ25713_REG_I2C_ADDRESS, 3, HAL_MAX_DELAY);
        if (status != HAL_OK) {
            // Error
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);
            HAL_Delay(300);
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);  
         
        }
    
        // Read data from Register
        status = HAL_I2C_Mem_Read(&hi2c1, BQ25713_REG_I2C_ADDRESS | 0x01, regAddress, I2C_MEMADD_SIZE_16BIT, readData, 2, HAL_MAX_DELAY);
        if (status != HAL_OK) {
            // Error
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);
            HAL_Delay(10000);
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);
            HAL_Delay(10000);
        } 
    
        // Combine LSB and MSB
        uint16_t readI2CData = (readData[0] << 8) | readData[1];
        return readI2CData;
    }

// Check Bits via LED
void checkBitsAndControlLEDs(uint16_t check_register) {
    uint16_t regData = ReadI2CData(check_register);

    for (int i = 15; i >= 0; i--) {
        if ((regData >> i) & 1) {
            // if bit is 1, light on LED 2 (GREEN)
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET); 
            HAL_Delay(2500);
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET);  
        } else {
            // if bit is 0, light on LED 1 (RED)
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET); 
            HAL_Delay(2500);
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);  
        }
        HAL_Delay(1000);  // 1s Delay
    }
}

MCU: STM32F030 IDE: STM32CubeIDE (HAL, INIT, I2C functions has been imported)

There is no error or warning when make debug and run process.

I spent 4 days for this but there is no successful result. Seems I need your advice and support.


Solution

  • The BQ25713 datasheet shows the Reg Addr used the I2C communication is 8-bits. E.g. see Figure 9-11. Multi Read.

    The code uses I2C_MEMADD_SIZE_16BIT in the calls to HAL_I2C_Mem_Write and HAL_I2C_Mem_Read. I.e. the code attempts to send a 16-bit register address to the BQ25713 rather than a 8-bit register address.

    Also, the datasheet shows the BQ25713 registers are 8-bits, yet the SetI2CData and ReadI2CData functions use uint16_t rather than uint8_t as the the data type for the registers.

    While the datasheet does show Multi Write and Multi Read I2C operations which work on multiple 8-bit registers with consecutive register addresses it might be clearer if the code was changed to write/read 8-bit registers.

    At a minimum suggest changing the code to use I2C_MEMADD_SIZE_8BIT instead of I2C_MEMADD_SIZE_16BIT.

    In summary, the code in the question seems to treat the BQ25713 registers as having 16-bit addresses and 16-bits of data, whereas the datasheet shows 8-bit register addresses with 8-bits of data.