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.

connecting bq33100 EVM board to MSP430G2331

Other Parts Discussed in Thread: BQ33100

Hi guys,

I tried to connect to bq33100 EVM board with the example code given in slac463a.zip.

I understand each line of the example and I thought it would perfectly work but I am not sure why it is not working.

I modified the SLV_Addr to 0x2D because i wanted to read the data of bq33100 slave address is 0x16 so that I bit shifted to the left and added one to read.

Then I got the first interrupt and passed when the I2C_state is 0. 

After that I am not getting any interrupts after all.

I am assuming since I am not getting follow up interrupts, I think I did not send the properly generating the start condition or sent wrong cmd to bq33100 at first attempt.

From bq33100 datasheet, the slave address for bq33100 is 0x16 and I would like to read the voltage of one of the five super caps (its SBS Cmd is 0x3b)

Could you please help me understand what's going on here? Also, is SBS Cmd as same as SMbus Cmd?

Also one person said that SMBus uses a specific data packet format which I2C does not, when forming the packets to send to thebq33100 make sure the endianess and byte sequence are correct for the bq33100 data set. 

I did not understand what this means. Can anyone give me an example of this?

Thank you,

-Jeonggoo Song


#include <msp430g2231.h>


char SLV_data = 0x00; // Variable for received data
char SLV_Addr = 0x2D; // Address is 0x3B << 1 bit + 1 for Read
int I2C_State = 0; // State variable

void main(void)
{
volatile unsigned int i; // Use volatile to prevent removal

WDTCTL = WDTPW + WDTHOLD; // Stop watchdog
if (CALBC1_1MHZ ==0xFF || CALDCO_1MHZ == 0xFF)
{
while(1); // If calibration constants are erased
// do not load, trap CPU!!
}
BCSCTL1 = CALBC1_1MHZ; // Set DCO
DCOCTL = CALDCO_1MHZ;

P1OUT = 0xC0; // P1.6 & P1.7 Pullups
P1REN |= 0xC0; // P1.6 & P1.7 Pullups
P1DIR = 0xFF; // Unused pins as outputs
P2OUT = 0;
P2DIR = 0xFF;

USICTL0 = USIPE6+USIPE7+USIMST+USISWRST;// Port & USI mode setup
USICTL1 = USII2C+USIIE; // Enable I2C mode & USI interrupt
USICKCTL = USIDIV_3+USISSEL_2+USICKPL;// Setup USI clocks: SCL = SMCLK/8 (~120kHz)
USICNT |= USIIFGCC; // Disable automatic clear control
USICTL0 &= ~USISWRST; // Enable USI
USICTL1 &= ~USIIFG; // Clear pending flag
_EINT();

while(1)
{
USICTL1 |= USIIFG; // Set flag and start communication
LPM0; // CPU off, await USI interrupt
for (i = 0; i < 50; i++); // Dummy delay between communication cycles
}
}

/******************************************************
// USI interrupt service routine
******************************************************/
#pragma vector = USI_VECTOR
__interrupt void USI_TXRX (void)
{
switch(I2C_State)
{
case 0: // Generate Start Condition & send address to slave
P1OUT |= 0x01; // LED on: sequence start
USISRL = 0x00; // Generate Start Condition...
USICTL0 |= USIGE+USIOE;
USICTL0 &= ~USIGE;
USISRL = SLV_Addr; // ... and transmit address, R/W = 1
USICNT = (USICNT & 0xE0) + 0x08; // Bit counter = 8, TX Address
I2C_State = 2; // Go to next state: receive address (N)Ack
break;

case 2: // Receive Address Ack/Nack bit
USICTL0 &= ~USIOE; // SDA = input
USICNT |= 0x01; // Bit counter = 1, receive (N)Ack bit
I2C_State = 4; // Go to next state: check (N)Ack
break;

case 4: // Process Address Ack/Nack & handle data RX
if (USISRL & 0x01) // If Nack received...
{ // Prep Stop Condition
USICTL0 |= USIOE;
USISRL = 0x00;
USICNT |= 0x01; // Bit counter = 1, SCL high, SDA low
I2C_State = 10; // Go to next state: generate Stop
P1OUT |= 0x01; // Turn on LED: error
}
else // Ack received
{ // Receive Data from slave
USICNT |= 0x08; // Bit counter = 8, RX data
I2C_State = 6; // Go to next state: Test data and (N)Ack
P1OUT &= ~0x01; // LED off
}
break;

case 6: // Send Data Ack/Nack bit
USICTL0 |= USIOE; // SDA = output
if (USISRL == SLV_data) // If data valid...
{
USISRL = 0x00; // Send Ack
SLV_data++; // Increment Slave data
P1OUT &= ~0x01; // LED off
}
else
{
USISRL = 0xFF; // Send NAck
P1OUT |= 0x01; // LED on: error
}
USICNT |= 0x01; // Bit counter = 1, send (N)Ack bit
I2C_State = 8; // Go to next state: prep stop
break;

case 8: // Prep Stop Condition
USICTL0 |= USIOE; // SDA = output
USISRL = 0x00;
USICNT |= 0x01; // Bit counter = 1, SCL high, SDA low
I2C_State = 10; // Go to next state: generate Stop
break;

case 10: // Generate Stop Condition
USISRL = 0x0FF; // USISRL = 1 to release SDA
USICTL0 |= USIGE; // Transparent latch enabled
USICTL0 &= ~(USIGE+USIOE);// Latch/SDA output disabled
I2C_State = 0; // Reset state machine for next transmission
LPM0_EXIT; // Exit active for next transfer
break;
}

USICTL1 &= ~USIIFG; // Clear pending flag

}
  • Jeonggoo, The Battery Management group is not going to be able to provide much help with MSP430 programming, but we can help with bq33100 operation. I think that you are going to find that SMBus and I2C protocol are very similar. I would recommend that you use an oscilloscope or logic analyzer to capture the data transfer for the commands of interest. This will help you to setup the controller interface for your project. SMBus refers to the bus interface protocol, timing, etc. the SBS CMDs are the commands that we have defined for this device. You will probably find them in the second or third word of the SMBus transfer. The return data or write data will be in the words that follow. regards Tom