Hi, TI expert
The customer has a request for BQ25790 related inquiries and schematic & source file review.
[Environmental information]
- AC input1: Brick Adapter DC 12V 3A (36W)
- AC input2: Powerbank (Any)
- Battery: SDI 4.2V 3500mAh 1S3P (10500mAh)
- Charging Current: 5A (to be adjusted after checking the temperature of the charger IC and inductor)
1) Problem: I2C Control is not available.
2) Requirements: Schematic and Source file review
We request solution review and schematic & source file review for the problem of not being able to control I2C.
221006 ORCA DB SCH03 3_LSUB.pdf
221118 ORCA DB Charger Setting (임시).xlsx
/******************************************************************************
* ORCA Micom Board
* Copyright by Linkflow All Rights Reserved.
*---------------------------------------------------------------------------*/
/**
* @file bq25790.c
* @brief bq25790 charger driver.
* VAC1-> 12V Cradle Input, VAC2->9V Power Bank(trouble adapter)
* @version 1.00
* @date 28 Sep 2022
* @author Linkflow Software team
*
* Copyright(C) 2022, Linkflow
* All rights reserved.
*/
/*****************************************************************************/
/*----------------------------------------------------------------------------
Defines referenced header files
-----------------------------------------------------------------------------*/
#include "app_main.h"
#include "dev_port.h"
#include "bq25790.h"
/*----------------------------------------------------------------------------
Definitions and macro
-----------------------------------------------------------------------------*/
#define I2C0_SPEED 100000 //# or 400000
//# --------------------- BQ25790 CHARGER ------------------------------------
#define BQ25790_I2C_ADDR 0x6B //# 7Bit
#define BQ25790_CACHE_REG_MAX 26 //# 26 registers.
#define BQ25790_MIN_SYS_V 0x00
#define BQ25790_CHRG_V_LIM_MSB 0x01 //# V_LIM_MSB
#define BQ25790_CHRG_V_LIM_LSB 0x02 //# V_LIM_LSB
#define BQ25790_CHRG_I_LIM_MSB 0x03
#define BQ25790_CHRG_I_LIM_LSB 0x04
#define BQ25790_INPUT_V_LIM 0x05
#define BQ25790_INPUT_I_LIM_MSB 0x06
#define BQ25790_INPUT_I_LIM_LSB 0x07
#define BQ25790_PRECHRG_CTRL 0x08
#define BQ25790_TERM_CTRL 0x09
#define BQ25790_RECHRG_CTRL 0x0a
#define BQ25790_VOTG_REG_MSB 0x0b //# Regulation
#define BQ25790_VOTG_REG_LSB 0x0c //# Regulation
#define BQ25790_IOTG_REG 0x0d //# Regulation
#define BQ25790_TIMER_CTRL 0x0e
#define BQ25790_CHRG_CTRL_0 0x0f
#define BQ25790_CHRG_CTRL_1 0x10
#define BQ25790_CHRG_CTRL_2 0x11
#define BQ25790_CHRG_CTRL_3 0x12
#define BQ25790_CHRG_CTRL_4 0x13
#define BQ25790_CHRG_CTRL_5 0x14
#define BQ25790_MPPT_CTRL 0x15
#define BQ25790_TEMP_CTRL 0x16
#define BQ25790_NTC_CTRL_0 0x17
#define BQ25790_NTC_CTRL_1 0x18
#define BQ25790_ICO_I_LIM 0x19
#define BQ25790_CHRG_STAT_0 0x1b
#define BQ25790_CHRG_STAT_1 0x1c
#define BQ25790_CHRG_STAT_2 0x1d
#define BQ25790_CHRG_STAT_3 0x1e
#define BQ25790_CHRG_STAT_4 0x1f
#define BQ25790_FAULT_STAT_0 0x20
#define BQ25790_FAULT_STAT_1 0x21
#define BQ25790_CHRG_FLAG_0 0x22
#define BQ25790_CHRG_FLAG_1 0x23
#define BQ25790_CHRG_FLAG_2 0x24
#define BQ25790_CHRG_FLAG_3 0x25
#define BQ25790_FAULT_FLAG_0 0x26
#define BQ25790_FAULT_FLAG_1 0x27
#define BQ25790_CHRG_MSK_0 0x28
#define BQ25790_CHRG_MSK_1 0x29
#define BQ25790_CHRG_MSK_2 0x2a
#define BQ25790_CHRG_MSK_3 0x2b
#define BQ25790_FAULT_MSK_0 0x2c
#define BQ25790_FAULT_MSK_1 0x2d
#define BQ25790_ADC_CTRL 0x2e
#define BQ25790_FN_DISABE_0 0x2f
#define BQ25790_FN_DISABE_1 0x30
#define BQ25790_ADC_IBUS 0x31
#define BQ25790_ADC_IBAT_MSB 0x33
#define BQ25790_ADC_IBAT_LSB 0x34
#define BQ25790_ADC_VBUS_MSB 0x35
#define BQ25790_ADC_VBUS_LSB 0x36
#define BQ25790_ADC_VAC1 0x37
#define BQ25790_ADC_VAC2 0x39
#define BQ25790_ADC_VBAT_MSB 0x3b
#define BQ25790_ADC_VBAT_LSB 0x3c
#define BQ25790_ADC_VSYS_MSB 0x3d
#define BQ25790_ADC_VSYS_LSB 0x3e
#define BQ25790_ADC_TS 0x3f
#define BQ25790_ADC_TDIE 0x41
#define BQ25790_ADC_DP 0x43
#define BQ25790_ADC_DM 0x45
#define BQ25790_DPDM_DRV 0x47
#define BQ25790_PART_INFO 0x48
#define BQ25790_DEF_ICHRG 4850000 //# 4.85mA
#define BQ25790_ICHRG_CURRENT_STEP_uA 10000 //# 10mA
#define BQ25790_DEF_PRECHRG 485000 //# 0.485mA
#define BQ25790_PRECHRG_CURRENT_STEP_uA 40000 //# 40mA
#define BQ25790_PRECHRG_I_MIN_uA 40000 //# 40mA
#define BQ25790_PRECHRG_I_MAX_uA 2000000 //#
#define BQ25790_DEF_VLIMIT 4200000 //# 4.2V
#define BQ25790_VREG_V_STEP_uV 10000
#define BQ25790_VREG_V_MIN_uV 3000000
#define BQ25790_VREG_V_MAX_uV 18800000
#define BQ25790_DEF_TERMCHRG 485000 //# 0.485
#define BQ25790_TERMCHRG_CURRENT_STEP_uV 40000
#define BQ25790_TERMCHRG_I_MIN_uV 40000
#define BQ25790_TERMCHRG_I_MAX_uV 1000000
#define BQ25790_DEF_VINDPM 10600000 //# 12V-1.4 = 10.6
#define BQ25790_VINDPM_STEP_uV 100000
#define BQ25790_VINDPM_V_MIN_uV 3600000
#define BQ25790_VINDPM_V_MAX_uV 22000000
#define BQ25790_DEF_IINDPM 2950000
#define BQ25790_IINDPM_STEP_uV 10000
#define BQ25790_IINDPM_I_MIN_uV 100000
#define BQ25790_IINDPM_I_MAX_uV 3300000
//# --------------------- End of BQ25790 CHARGER ----------------------------------
/*----------------------------------------------------------------------------
Declares variables
-----------------------------------------------------------------------------*/
static uint8_t cache_regs[BQ25790_CACHE_REG_MAX];
/**********************************************************************
* @brief i2c read for 8bit register
* @param[in] uint8_t ch, uint8_t dev_addr, uint8_t addr, uint8_t *value
* @return None
**********************************************************************/
static void bq25790_reg_read8(uint8_t dev_addr, uint8_t addr, uint8_t *value)
{
I2C_M_SETUP_Type cfg;
uint8_t txBuf[1];
uint8_t rxBuf[1];
txBuf[0] = addr;
cfg.sl_addr7bit = dev_addr;
cfg.tx_data = txBuf;
cfg.tx_length = 1;
cfg.rx_data = rxBuf;
cfg.rx_length = 1;
/* I2C transmission */
HAL_I2C_MasterReceiveData(I2C0, &cfg, I2C_TRANSFER_POLLING);
*value = rxBuf[0];
}
/**********************************************************************
* @brief i2c write for 8bit register
* @param[in] uint8_t ch, uint8_t dev_addr, uint8_t addr, uint8_t value
* @return None
**********************************************************************/
static void bq25790_reg_write8(uint8_t dev_addr, uint8_t addr, uint8_t value)
{
I2C_M_SETUP_Type cfg;
uint8_t buffer[2];
buffer[0] = addr;
buffer[1] = value;
cfg.sl_addr7bit = dev_addr;
cfg.tx_data = buffer;
cfg.tx_length = 2;
HAL_I2C_MasterTransmitData(I2C0, &cfg, I2C_TRANSFER_POLLING);
}
/**********************************************************************
* @brief bq25790 hardware initialize
* @param[in] None
* @return None
**********************************************************************/
static void bq25790_hw_init(void)
{
uint8_t old_value=0;
cache_regs[BQ25790_MIN_SYS_V] = 0x04; //# 0x00
cache_regs[BQ25790_PRECHRG_CTRL] = 0xcc; //# 0x08
cache_regs[BQ25790_TERM_CTRL] = 0x0c; //# 0x09
cache_regs[BQ25790_RECHRG_CTRL] = 0x23; //# 0x0A
cache_regs[BQ25790_VOTG_REG_MSB] = 0x00; //# 0x0B
cache_regs[BQ25790_VOTG_REG_LSB] = 0xDC; //# 0x0C
cache_regs[BQ25790_IOTG_REG] = 0x03; //# 0x0D
cache_regs[BQ25790_TIMER_CTRL] = 0x3d; //# 0x0E
cache_regs[BQ25790_CHRG_CTRL_0] = 0xa2; //# 0x0F
cache_regs[BQ25790_CHRG_CTRL_1] = 0x10; //# 0x10
cache_regs[BQ25790_CHRG_CTRL_2] = 0x78; //# 0x11
cache_regs[BQ25790_CHRG_CTRL_3] = 0x00; //# 0x12
cache_regs[BQ25790_CHRG_CTRL_5] = 0xBF; //# 0x14
cache_regs[BQ25790_TEMP_CTRL] = 0xA0; //# 0x16
cache_regs[BQ25790_NTC_CTRL_0] = 0x74; //# 0x17
cache_regs[BQ25790_NTC_CTRL_1] = 0x7c; //# 0x18
//# Set Minimal SYSV, 3.5V
bq25790_reg_write8(BQ25790_I2C_ADDR, BQ25790_MIN_SYS_V, cache_regs[BQ25790_MIN_SYS_V]);
bq25790_reg_write8(BQ25790_I2C_ADDR, BQ25790_PRECHRG_CTRL, cache_regs[BQ25790_PRECHRG_CTRL]);
bq25790_reg_write8(BQ25790_I2C_ADDR, BQ25790_TERM_CTRL, cache_regs[BQ25790_TERM_CTRL]);
bq25790_reg_write8(BQ25790_I2C_ADDR, BQ25790_RECHRG_CTRL, cache_regs[BQ25790_RECHRG_CTRL]);
bq25790_reg_write8(BQ25790_I2C_ADDR, BQ25790_VOTG_REG_MSB, cache_regs[BQ25790_VOTG_REG_MSB]);
bq25790_reg_write8(BQ25790_I2C_ADDR, BQ25790_VOTG_REG_LSB, cache_regs[BQ25790_VOTG_REG_LSB]);
bq25790_reg_write8(BQ25790_I2C_ADDR, BQ25790_IOTG_REG, cache_regs[BQ25790_IOTG_REG]);
bq25790_reg_write8(BQ25790_I2C_ADDR, BQ25790_TIMER_CTRL, cache_regs[BQ25790_TIMER_CTRL]);
bq25790_reg_write8(BQ25790_I2C_ADDR, BQ25790_CHRG_CTRL_0, cache_regs[BQ25790_CHRG_CTRL_0]);
/* watchdog disable, VAC_OVP=22V */
bq25790_reg_write8(BQ25790_I2C_ADDR, BQ25790_CHRG_CTRL_1, cache_regs[BQ25790_CHRG_CTRL_1]);
bq25790_reg_write8(BQ25790_I2C_ADDR, BQ25790_CHRG_CTRL_2, cache_regs[BQ25790_CHRG_CTRL_2]);
/* ??? 0x80 -> ADC disable */
bq25790_reg_write8(BQ25790_I2C_ADDR, BQ25790_CHRG_CTRL_3, cache_regs[BQ25790_CHRG_CTRL_3]);
bq25790_reg_write8(BQ25790_I2C_ADDR, BQ25790_CHRG_CTRL_5, cache_regs[BQ25790_CHRG_CTRL_5]);
bq25790_reg_write8(BQ25790_I2C_ADDR, BQ25790_TEMP_CTRL, cache_regs[BQ25790_TEMP_CTRL]);
bq25790_reg_write8(BQ25790_I2C_ADDR, BQ25790_NTC_CTRL_0, cache_regs[BQ25790_NTC_CTRL_0]);
bq25790_reg_write8(BQ25790_I2C_ADDR, BQ25790_NTC_CTRL_1, cache_regs[BQ25790_NTC_CTRL_1]);
/* don't control CHARGER CONTROL4 ?? --> system fault */
bq25790_reg_read8(BQ25790_I2C_ADDR, BQ25790_CHRG_CTRL_4, &old_value);
if (old_value != 0x01) {
__nop(); //# for debugging
}
}
/**********************************************************************
* @brief set bq25790 charge current limit
* @param[in] int value
* @return None
**********************************************************************/
void bq25790_set_ichrg_curr(int value)
{
int reg_val=0;
reg_val = (value / BQ25790_ICHRG_CURRENT_STEP_uA);
cache_regs[BQ25790_CHRG_I_LIM_MSB] = (reg_val >> 8) & 0xff; //# MSB
bq25790_reg_write8(BQ25790_I2C_ADDR, BQ25790_CHRG_I_LIM_MSB, cache_regs[BQ25790_CHRG_I_LIM_MSB]); //# 0x03
cache_regs[BQ25790_CHRG_I_LIM_LSB] = (reg_val & 0xff); //# LSB
bq25790_reg_write8(BQ25790_I2C_ADDR, BQ25790_CHRG_I_LIM_LSB, cache_regs[BQ25790_CHRG_I_LIM_LSB]); //# 0x04
}
/**********************************************************************
* @brief set bq25790 pre-charge current limit
* @param[in] int value
* @return None
**********************************************************************/
void bq25790_set_prechrg_curr(int value)
{
int reg_val=0;
uint8_t old_value=0;
if (value < BQ25790_PRECHRG_I_MIN_uA)
value = BQ25790_PRECHRG_I_MIN_uA;
else if (value > BQ25790_PRECHRG_I_MAX_uA)
value = BQ25790_PRECHRG_I_MAX_uA;
reg_val = (value / BQ25790_PRECHRG_CURRENT_STEP_uA) & 0x3F;
//# Bit [5:0]
old_value = (cache_regs[BQ25790_PRECHRG_CTRL] & 0xC0);
old_value |= reg_val;
cache_regs[BQ25790_PRECHRG_CTRL] = old_value;
bq25790_reg_write8(BQ25790_I2C_ADDR, BQ25790_PRECHRG_CTRL, cache_regs[BQ25790_PRECHRG_CTRL]); //# 0x08
}
/**********************************************************************
* @brief set bq25790 Charging Voltage.
* @param[in] int value
* @return None
**********************************************************************/
void bq25790_set_chrg_volt(int value)
{
int reg_val=0;
if (value < BQ25790_VREG_V_MIN_uV)
value = BQ25790_VREG_V_MIN_uV;
else if (value > BQ25790_VREG_V_MAX_uV)
value = BQ25790_VREG_V_MAX_uV;
reg_val = (value / BQ25790_VREG_V_STEP_uV);
cache_regs[BQ25790_CHRG_V_LIM_MSB] = (reg_val >> 8) & 0xff;
bq25790_reg_write8(BQ25790_I2C_ADDR, BQ25790_CHRG_V_LIM_MSB, cache_regs[BQ25790_CHRG_V_LIM_MSB]); //# 0x01
cache_regs[BQ25790_CHRG_V_LIM_LSB] = (reg_val & 0xff);
bq25790_reg_write8(BQ25790_I2C_ADDR, BQ25790_CHRG_V_LIM_LSB, cache_regs[BQ25790_CHRG_V_LIM_LSB]); //# 0x02
}
/**********************************************************************
* @brief set bq25790 Termination Charge Current.
* @param[in] int value
* @return None
**********************************************************************/
void bq25790_set_term_curr(int value)
{
int reg_val=0;
uint8_t old_value=0;
if (value < BQ25790_TERMCHRG_I_MIN_uV)
value = BQ25790_TERMCHRG_I_MIN_uV;
else if (value > BQ25790_TERMCHRG_I_MAX_uV)
value = BQ25790_TERMCHRG_I_MAX_uV;
reg_val = (value / BQ25790_TERMCHRG_CURRENT_STEP_uV);
//# Bit [4:0]
old_value = (cache_regs[BQ25790_TERM_CTRL] & 0xE0);
old_value |= reg_val & 0x1F;
cache_regs[BQ25790_TERM_CTRL] = old_value;
bq25790_reg_write8(BQ25790_I2C_ADDR, BQ25790_TERM_CTRL, cache_regs[BQ25790_TERM_CTRL]); //# 0x09
}
/**********************************************************************
* @brief set bq25790 Input Voltage Limit.
* @param[in] int value
* @return None
**********************************************************************/
void bq25790_set_input_volt_limit(int value)
{
int reg_val=0;
if (value < BQ25790_VINDPM_V_MIN_uV)
value = BQ25790_VINDPM_V_MIN_uV;
else if (value > BQ25790_VINDPM_V_MAX_uV)
value = BQ25790_VINDPM_V_MAX_uV;
reg_val = (value / BQ25790_VINDPM_STEP_uV);
cache_regs[BQ25790_INPUT_V_LIM] = reg_val;
bq25790_reg_write8(BQ25790_I2C_ADDR, BQ25790_INPUT_V_LIM, cache_regs[BQ25790_INPUT_V_LIM]); //# 0x05
}
/**********************************************************************
* @brief set bq25790 Input Current Limit.
* @param[in] int value
* @return None
**********************************************************************/
void bq25790_set_input_curr_limit(int value)
{
int reg_val=0;
if (value < BQ25790_IINDPM_I_MIN_uV)
value = BQ25790_IINDPM_I_MIN_uV;
else if (value > BQ25790_IINDPM_I_MAX_uV)
value = BQ25790_IINDPM_I_MAX_uV;
reg_val = (value / BQ25790_IINDPM_STEP_uV);
cache_regs[BQ25790_INPUT_I_LIM_MSB] = (reg_val >> 8) & 0xff;
bq25790_reg_write8(BQ25790_I2C_ADDR, BQ25790_INPUT_I_LIM_MSB, cache_regs[BQ25790_INPUT_I_LIM_MSB]); //# 0x06
cache_regs[BQ25790_INPUT_I_LIM_LSB] = (reg_val & 0xff);
bq25790_reg_write8(BQ25790_I2C_ADDR, BQ25790_INPUT_I_LIM_LSB, cache_regs[BQ25790_INPUT_I_LIM_LSB]); //# 0x07
}
/**********************************************************************
* @brief bq25790 ACFET1-RBFET1 Gate driver control (auto controlled. if you control, system hang..)
* @param[in] int value
* @return None
**********************************************************************/
void bq25790_acdrv1_gate_ctrl(int enable)
{
uint8_t old_value=0;
old_value = cache_regs[BQ25790_CHRG_CTRL_4];
if (enable) {
old_value |= 0x40;
} else {
old_value &= ~(0x40);
}
cache_regs[BQ25790_CHRG_CTRL_4] = old_value;
bq25790_reg_write8(BQ25790_I2C_ADDR, BQ25790_CHRG_CTRL_4, cache_regs[BQ25790_CHRG_CTRL_4]);
}
/**********************************************************************
* @brief bq25790 ACFET2-RBFET2 Gate driver control
* @param[in] int value
* @return None
**********************************************************************/
void bq25790_acdrv2_gate_ctrl(int enable)
{
uint8_t old_value=0;
old_value = cache_regs[BQ25790_CHRG_CTRL_4];
if (enable) {
old_value |= 0x80;
} else {
old_value &= ~(0x80);
}
cache_regs[BQ25790_CHRG_CTRL_4] = old_value;
bq25790_reg_write8(BQ25790_I2C_ADDR, BQ25790_CHRG_CTRL_4, cache_regs[BQ25790_CHRG_CTRL_4]);
}
/**********************************************************************
* @brief bq25790 get status registers.
* @param[in] State params.
* @return None
**********************************************************************/
void bq25790_get_state(struct bq25790_state *state)
{
uint8_t chrg_stat_0=0;
bq25790_reg_read8(BQ25790_I2C_ADDR, BQ25790_PART_INFO, &chrg_stat_0);
state->vac1_status = (chrg_stat_0 & 0x04);
state->vac2_status = (chrg_stat_0 & 0x02);
}
/**********************************************************************
* @brief Initialize bq25790 battery charger for ORCA Board.
* @param[in] int bus number
* @return None
**********************************************************************/
void init_bq25790(void)
{
uint8_t info=0;
int reg_val=0;
/* Get Part info */
bq25790_reg_read8(BQ25790_I2C_ADDR, BQ25790_PART_INFO, &info);
if (info != 0x1) {
__nop();
/* TODO */
}
bq25790_hw_init();
//# Set Charge Current Limit
bq25790_set_ichrg_curr(BQ25790_DEF_ICHRG);
//# Set Pre-charge Current Limit.
bq25790_set_prechrg_curr(BQ25790_DEF_PRECHRG);
//# Set Charge Voltage Limit (0x01, 0x02)
bq25790_set_chrg_volt(BQ25790_DEF_VLIMIT);
//# Set Termination Current 0x09
bq25790_set_term_curr(BQ25790_DEF_TERMCHRG);
//# Set Input Voltage.
bq25790_set_input_volt_limit(BQ25790_DEF_VINDPM);
//# Set Input Current Limit.
bq25790_set_input_curr_limit(BQ25790_DEF_IINDPM);
}
/* --------------------------------- End Of File ------------------------------ */
Please check. Thank you.