SLUAAA1 October   2021 BQ21061 , BQ21062 , BQ24179 , BQ25150 , BQ25155 , BQ25157 , BQ25672 , BQ25790 , BQ25792 , BQ25798 , BQ25882 , BQ25883 , BQ25887 , BQ25895 , BQ25896 , BQ25898 , BQ25898D

 

  1.   Trademarks
  2. 1Introduction
  3. 2Battery Characterization
  4. 3Generating the Lookup Table
  5. 4BQ25155 Register Configuration
  6. 5Best Use Cases
  7. 6Python Lookup Table Generator
  8. 7MSP430 Code Snippet

MSP430 Code Snippet

{...
	
    //Disable Watchdog and Enable TS
    StdI2C_P_TX_Single(BQ25150_ADDR, BQ25150_CHARGERCTRL0, 0x90, &Err);
	
    // Disable interrupts for all the rest except ADC comparator
    StdI2C_P_TX_Single(BQ25150_ADDR, BQ25150_MASK0, 0xFE, &Err); //Mask all but VIN_PGOOD
    StdI2C_P_TX_Single(BQ25150_ADDR, BQ25150_MASK1, 0xBF, &Err); //Mask all
    StdI2C_P_TX_Single(BQ25150_ADDR, BQ25150_MASK2, 0xF7, &Err); //Mask all
    StdI2C_P_TX_Single(BQ25150_ADDR, BQ25150_MASK3, 0xFF, &Err); //Mask all
	
    // Enable ADC channels for VBAT only
    StdI2C_P_TX_Single(BQ25150_ADDR, BQ25150_ADC_READ_EN, 0x08, &Err);
	
    // Enable ADC
    StdI2C_P_TX_Single(BQ25150_ADDR, BQ25150_ADCCTRL0, 0x80, &Err); //Set ADC to perform conversion every 1s at 24ms conversion speed
    StdI2C_P_TX_Single(BQ25150_ADDR, BQ25150_ADCCTRL1, 0x00, &Err); //Disables comparator channels

    //Set PG pin as GPIO for discharge
    StdI2C_P_TX_Single(BQ25150_ADDR, BQ25150_ICCTRL1, 0x08, &Err);
    StdI2C_P_TX_Single(BQ25150_ADDR, BQ25150_ICCTRL2, 0x10, &Err);

    //GPIO_setAsInputPinWithPullUpResistor(BQ_INT2);
    GPIO_setAsInputPin(BQ_INT2);
    GPIO_enableInterrupt(BQ_INT2);
    GPIO_selectInterruptEdge(BQ_INT2, GPIO_HIGH_TO_LOW_TRANSITION);
    GPIO_clearInterrupt(BQ_INT2);

	StdI2C_P_RX_Single(BQ25150_ADDR, BQ25150_ADCDATA_VBAT_M, &VBAT_Meas_M, &Err); //Finding current battery voltage
	StdI2C_P_RX_Single(BQ25150_ADDR, BQ25150_ADCDATA_VBAT_M, &VBAT_Meas_L, &Err);
	VBAT_Meas = (uint16_t)(VBAT_Meas_M << 8) | VBAT_Meas_L; //Converting to 16-bit integer
	cur_SOC = find_initial_SOC(VBAT_Meas); //Finding initial SOC
	sprintf(SOC_string, "SOC = %d %%        ", cur_SOC);

    while(1) {

		waitms(1000); //Period between SOC updates
		StdI2C_P_RX_Single(BQ25150_ADDR, BQ25150_ADCDATA_VBAT_M, &VBAT_Meas_M, &Err);
		StdI2C_P_RX_Single(BQ25150_ADDR, BQ25150_ADCDATA_VBAT_L, &VBAT_Meas_L, &Err);
		VBAT_Meas = (uint16_t)(VBAT_Meas_M << 8) | VBAT_Meas_L;
		cur_SOC = update_SOC_discharge(cur_SOC, VBAT_Meas); //Update SOC
		sprintf(SOC_string, "SOC = %d %%        ", cur_SOC);


    }
}

uint8_t find_initial_SOC(uint16_t VBAT_Meas){
	int i;

	for (i = 99; i >= 0; i--){
		if (VBAT_Meas >= SOC_lookup_table[i]){
			return (uint8_t)(i + 1);
		}
	}
	return 0;
}

uint8_t update_SOC_discharge(uint8_t cur_SOC, uint16_t VBAT_Meas){
	int i;

	for (i = cur_SOC - 1; i >= 0; i--){ //Begins at current SOC so it doesn't have to go through the whole array each time. 
		if (VBAT_Meas >= SOC_lookup_table[i]){ 
			return (uint8_t)(i + 1); //Must add 1 to the SOC found because array is zero-indexed.
		}
	}

	return 0; //Default is SOC = 0.
}