Hi! I'm trying to use the Fuel Tank MKII Battery BoosterPack Plug-In Module with a MSP-EXP432P401R Rev. 2.0 Launchpad. I'm using the example provided in MSP432 Simplelink SDK 1.40.00.28 (boostxl_batpakmkii_fuelgauge_MSP_EXP432P401R_nortos_ccs), and I want to optimize it by getting the CPU to sleep instead of waiting for received bytes in a while loop.
The problem is that when using my code it reads a different response from BQ27441 (it reads 0xB000 when it should be reading 0x0108). The code I'm using:
volatile bool i2cRxFlag = false;
void I2C_init(void)
{
/* Initialize USCI_B0 and I2C Master to communicate with slave devices*/
I2C_initMaster(EUSCI_B1_BASE, &i2cConfig);
/* Disable I2C module to make changes */
I2C_disableModule(EUSCI_B1_BASE);
/* Enable I2C Module to start operations */
I2C_enableModule(EUSCI_B1_BASE);
MAP_I2C_clearInterruptFlag(EUSCI_B1_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_RECEIVE_INTERRUPT0 + EUSCI_B_I2C_STOP_INTERRUPT);
MAP_I2C_enableInterrupt(EUSCI_B1_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_RECEIVE_INTERRUPT0 + EUSCI_B_I2C_STOP_INTERRUPT);
MAP_Interrupt_enableInterrupt(INT_EUSCIB1);
return;
}
void EUSCIB1_IRQHandler(void)
{
unsigned int status;
status = MAP_I2C_getEnabledInterruptStatus(EUSCI_B1_BASE);
MAP_I2C_clearInterruptFlag(EUSCI_B1_BASE, status);
if (status & EUSCI_B_I2C_TRANSMIT_INTERRUPT0)
{
i2cTxFlag = true;
}
if (status & EUSCI_B_I2C_STOP_INTERRUPT)
{
i2cStopFlag = true;
}
if (status & EUSCI_B_I2C_RECEIVE_INTERRUPT0)
{
i2cRxFlag = true;
}
MAP_Interrupt_disableSleepOnIsrExit();
}
bool I2C_read16(unsigned char pointer, short * result, unsigned int timeout)
{
uint8_t val = 0;
uint8_t valScratch = 0;
short r = 0;
/* Set master to transmit mode PL */
I2C_setMode(EUSCI_B1_BASE,
EUSCI_B_I2C_TRANSMIT_MODE);
/* Clear any existing interrupt flag PL */
I2C_clearInterruptFlag(EUSCI_B1_BASE,
EUSCI_B_I2C_TRANSMIT_INTERRUPT0);
/* Initiate start and send first character */
if (!I2C_masterSendSingleByteWithTimeout(EUSCI_B1_BASE, pointer, timeout))
return 0;
/*
* Generate Start condition and set it to receive mode.
* This sends out the slave address and continues to read
* until you issue a STOP
*/
I2C_masterReceiveStart(EUSCI_B1_BASE);
/* Wait for RX buffer to fill */
//while(!(I2C_getInterruptStatus(EUSCI_B1_BASE,
// EUSCI_B_I2C_RECEIVE_INTERRUPT0)));
if (!(MAP_I2C_getInterruptStatus(EUSCI_B1_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0)))
{
while (i2cRxFlag == false)
{
MAP_PCM_gotoLPM0InterruptSafe();
MAP_Interrupt_enableMaster();
}
i2cRxFlag = false;
}
/* Read from I2C RX register */
valScratch = I2C_masterReceiveMultiByteNext(EUSCI_B1_BASE);
/* Receive second byte then send STOP condition */
if (!I2C_masterReceiveMultiByteFinishWithTimeout(EUSCI_B1_BASE, &val, timeout))
return 0;
/* Shift val to top MSB */
r = (val << 8);
/* Read from I2C RX Register and write to LSB of r */
r |= valScratch;
/* Return temperature value */
*result = r;
return 1;
}
As you can see, I only added a few lines of code. After waiting for the RX buffer to fill, if I use the original while() loop (which is commented above) it reads 0x0108, but if I use my code (the if statement above), it reads 0xB000.
What could be the problem?