This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CCS/MSP430FR5969: bq24250 i2c code problem

Part Number: MSP430FR5969
Other Parts Discussed in Thread: BQ24250

Tool/software: Code Composer Studio

hello everyone,

I want to read the charging status of Register 0x00 of  bq2250 ic   using I2c code.

when i am debugging the code ,its getting struck in this step of  eusci_b_i2c.c driver file.


//Poll for transmit interrupt flag.
while(!(HWREG16(baseAddress + OFS_UCBxIFG) & UCTXIFG))
{
;
}

please guide me to solve .

I2c code for Bq24250 :

#include "driverlib.h"
#include"clockinit.h"
void i2c_init();
void i2c_write();
uint8_t i2c_read();
void gpio_init();
uint8_t reg_status=0,reg_val=0;
uint32_t clock_val=0;

#define SLAVE_ADDRESS 0x6A

int main(void)
{

WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
PM5CTL0 &= ~LOCKLPM5;
_bic_SR_register(GIE);
clockinit();
clock_val=CS_getSMCLK();
gpio_init();
i2c_init();
_delay_cycles(2000);
reg_val=i2c_read();
while(1);
}
void gpio_init()
{

GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1,GPIO_PIN6 + GPIO_PIN7,GPIO_SECONDARY_MODULE_FUNCTION);
}
void i2c_init()
{
EUSCI_B_I2C_initMasterParam param = {0};
param.selectClockSource = EUSCI_B_I2C_CLOCKSOURCE_SMCLK;
param.i2cClk = CS_getSMCLK();
param.dataRate = EUSCI_B_I2C_SET_DATA_RATE_400KBPS;
param.byteCounterThreshold = 1;
param.autoSTOPGeneration = EUSCI_B_I2C_NO_AUTO_STOP;
EUSCI_B_I2C_setSlaveAddress(EUSCI_B0_BASE, SLAVE_ADDRESS);
EUSCI_B_I2C_initMaster(EUSCI_B0_BASE, &param);
EUSCI_B_I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_MODE);
EUSCI_B_I2C_enable(EUSCI_B0_BASE);
EUSCI_B_I2C_clearInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_NAK_INTERRUPT);

EUSCI_B_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_NAK_INTERRUPT);


}
uint8_t i2c_read()
{
//Send single byte data.
EUSCI_B_I2C_masterSendSingleByte(EUSCI_B0_BASE,0x00);// read register 0x00

//Delay until transmission completes
while(EUSCI_B_I2C_isBusBusy(EUSCI_B0_BASE))
{
;
}
EUSCI_B_I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_MODE);
EUSCI_B_I2C_clearInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0+ EUSCI_B_I2C_TRANSMIT_INTERRUPT0);
EUSCI_B_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0);
reg_status=EUSCI_B_I2C_masterReceiveSingleByte(EUSCI_B0_BASE);
EUSCI_B_I2C_masterReceiveStart(EUSCI_B0_BASE);
reg_status = EUSCI_B_I2C_masterReceiveSingle(EUSCI_B0_BASE);
return reg_status;
}

  • Hello Manoj,

    I just received your question. I will look through the code and get back to you.

  • Hello Manoj,

    Which "//Poll for transmit interrupt flag" does it get stuck in? Is it the one after the send start condition or the one after send single byte?
  • it is on send single byte function
  • Can I see how your hardware is setup before we dig into the code? I would like to see the connection between the MCU and bq24250, the pull up resistors and their values.
  • yeah its working with different version code .so,Hardware is fine.but some fault in my code
  • Hello Manoj,

    I found an error, the GPIO initialization must be done before the PMM unLock.

    This means that you must first call,

        // Configure Pins for I2C
        //Set P1.6 and P1.7 as Secondary Module Function Input.
        /*
    
         * Select Port 1
         * Set Pin 6, 7 to input Secondary Module Function, (UCB0SIMO/UCB0SDA, UCB0SOMI/UCB0SCL).
         */
        GPIO_setAsPeripheralModuleFunctionInputPin(
            GPIO_PORT_P1,
            GPIO_PIN6 + GPIO_PIN7,
            GPIO_SECONDARY_MODULE_FUNCTION
            );
    
        /*
         * Disable the GPIO power-on default high-impedance mode to activate
         * previously configured port settings
         */
        PMM_unlockLPM5();

  • Just to add clarification:
    PMM_unlockLPM5() is the same as PM5CTL0 &= ~LOCKLPM5;
  • sorry to say, i changed your suggested change but its not working .still it gets struck in
    //Poll for transmit interrupt flag.
    while(!(HWREG16(baseAddress + OFS_UCBxIFG) & UCTXIFG))
    {
    ;
    }
  • yeah its same PM5CTL0 &= ~LOCKLPM5 is a register version and PMM_unlockLPM5() is a driverlib version
  • I just tested this code and I had the same issue as you then after changing the SLAVE_ADDRESS to the correct address everything worked.

    #include "driverlib.h"
    
    void i2c_init();
    void i2c_write();
    uint8_t i2c_read();
    void gpio_init();
    uint8_t reg_status=0,reg_val=0;
    uint32_t clock_val=0;
    
    #define SLAVE_ADDRESS 0x48
    
    int main(void)
    {
    
        WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
        //_bic_SR_register(GIE);
    
        //Set DCO frequency to 1MHz
        CS_setDCOFreq(CS_DCORSEL_0,CS_DCOFSEL_0);
        //Set ACLK = VLO with frequency divider of 1
        CS_initClockSignal(CS_ACLK,CS_VLOCLK_SELECT,CS_CLOCK_DIVIDER_1);
        //Set SMCLK = DCO with frequency divider of 1
        CS_initClockSignal(CS_SMCLK,CS_DCOCLK_SELECT,CS_CLOCK_DIVIDER_1);
        //Set MCLK = DCO with frequency divider of 1
        CS_initClockSignal(CS_MCLK,CS_DCOCLK_SELECT,CS_CLOCK_DIVIDER_1);
    
        clock_val=CS_getSMCLK();
        gpio_init();
        PM5CTL0 &= ~LOCKLPM5;
        i2c_init();
        _delay_cycles(2000);
        reg_val=i2c_read();
        while(1);
    }
    
    void gpio_init()
    {
        GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1,GPIO_PIN6 + GPIO_PIN7,GPIO_SECONDARY_MODULE_FUNCTION);
    }
    
    void i2c_init()
    {
        EUSCI_B_I2C_initMasterParam param = {0};
        param.selectClockSource = EUSCI_B_I2C_CLOCKSOURCE_SMCLK;
        param.i2cClk = CS_getSMCLK();
        param.dataRate = EUSCI_B_I2C_SET_DATA_RATE_400KBPS;
        param.byteCounterThreshold = 1;
        param.autoSTOPGeneration = EUSCI_B_I2C_NO_AUTO_STOP;
        EUSCI_B_I2C_setSlaveAddress(EUSCI_B0_BASE, SLAVE_ADDRESS);
        EUSCI_B_I2C_initMaster(EUSCI_B0_BASE, &param);
        EUSCI_B_I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_MODE);
        EUSCI_B_I2C_enable(EUSCI_B0_BASE);
        EUSCI_B_I2C_clearInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_NAK_INTERRUPT);
    
        EUSCI_B_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_NAK_INTERRUPT);
    }
    
    uint8_t i2c_read()
    {
        //Send single byte data.
        EUSCI_B_I2C_masterSendSingleByte(EUSCI_B0_BASE,0x00);// read register 0x00
    
        //Delay until transmission completes
        while(EUSCI_B_I2C_isBusBusy(EUSCI_B0_BASE))
        {
        ;
        }
        EUSCI_B_I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_MODE);
        EUSCI_B_I2C_clearInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0+ EUSCI_B_I2C_TRANSMIT_INTERRUPT0);
        EUSCI_B_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0);
        reg_status=EUSCI_B_I2C_masterReceiveSingleByte(EUSCI_B0_BASE);
        EUSCI_B_I2C_masterReceiveStart(EUSCI_B0_BASE);
        reg_status = EUSCI_B_I2C_masterReceiveSingle(EUSCI_B0_BASE);
        return reg_status;
    }

**Attention** This is a public forum