I'm on Kinetis K02 Processor . The following is the code to change the battery capacity to 500 mAh. I'm following the same sequence outlined in sluuad4c.pdf.
I2C rate is 400 kHz.
bool bq27621ChangeCapacityParameter (uint16_t capacityVal)
{
i2c_status_t i2cStatus;
uint8_t txBuf[3];
uint8_t checkSum, tempMod;
uint16_t flagVal = 0;
uint8_t msbCap, lsbCap,
prvMsbCap, prvLsbCap,
prvCheckSum;
// UNSEALED
txBuf [0] = 0x00;
txBuf [1] = UNSEAL_CODE_L;
txBuf [2] = UNSEAL_CODE_H;
i2cStatus = I2C_DRV_MasterSendDataBlocking(BOARD_I2C_INSTANCE, &i2cDevice,
NULL, 0, (const uint8_t*)txBuf, 3, DEVICE_I2C_TIMEOUT);
if (i2cStatus != kStatus_I2C_Success)
return false;
i2cStatus = I2C_DRV_MasterSendDataBlocking(BOARD_I2C_INSTANCE, &i2cDevice,
NULL, 0, (const uint8_t*)txBuf, 3, DEVICE_I2C_TIMEOUT);
if (i2cStatus != kStatus_I2C_Success)
return false;
// Enter CFG Update
txBuf [0] = BQ27621_CTRL1_ADDR;
txBuf [1] = SET_CFGUPDATE & 0xff;
txBuf [2] = (SET_CFGUPDATE >> 8) & 0xff;
i2cStatus = I2C_DRV_MasterSendDataBlocking(BOARD_I2C_INSTANCE, &i2cDevice,
NULL, 0, (const uint8_t*)txBuf, 3, DEVICE_I2C_TIMEOUT);
if (i2cStatus != kStatus_I2C_Success)
return false;
// Check Flag bit 4
for (int i = 2000; (i > 0) && !(flagVal & 0x10); i--)
{
_bq27621ReadFlag(&flagVal);
}
//Bit never get set..ignored for now
//if ((flagVal & 0x10) != 0x10)
// return false;
// Enable block data memory control
txBuf [0] = BLOCKDATACONTROL;
txBuf [1] = 0x00;
i2cStatus = I2C_DRV_MasterSendDataBlocking(BOARD_I2C_INSTANCE, &i2cDevice,
NULL, 0, (const uint8_t*)txBuf, 2, DEVICE_I2C_TIMEOUT);
if (i2cStatus != kStatus_I2C_Success)
return false;
// Access State subclass: Design Capacity parameter
txBuf [0] = DATACLASS;
txBuf [1] = 0x52;
i2cStatus = I2C_DRV_MasterSendDataBlocking(BOARD_I2C_INSTANCE, &i2cDevice,
NULL, 0, (const uint8_t*)txBuf, 2, DEVICE_I2C_TIMEOUT);
if (i2cStatus != kStatus_I2C_Success)
return false;
// Access location block in subclass
txBuf [0] = DATABLOCK;
txBuf [1] = 0x00;
i2cStatus = I2C_DRV_MasterSendDataBlocking(BOARD_I2C_INSTANCE, &i2cDevice,
NULL, 0, (const uint8_t*)txBuf, 2, DEVICE_I2C_TIMEOUT);
if (i2cStatus != kStatus_I2C_Success)
return false;
// Read previous CheckSum - Getting 0x70
i2cStatus = I2C_DRV_MasterReceiveDataBlocking(BOARD_I2C_INSTANCE, &i2cDevice,
(const uint8_t *)(BLOCKDATACHECKSUM), 1, &prvCheckSum, 1, DEVICE_I2C_TIMEOUT);
// Read previous Design Capacity @ 0x43 (offset = 3) - getting 0x00
i2cStatus = I2C_DRV_MasterReceiveDataBlocking(BOARD_I2C_INSTANCE, &i2cDevice,
(const uint8_t *)(DESIGNCAPACITY_H), 1, &prvMsbCap, 1, DEVICE_I2C_TIMEOUT);
if (i2cStatus != kStatus_I2C_Success)
return false;
//Getting 0x70 back
i2cStatus = I2C_DRV_MasterReceiveDataBlocking(BOARD_I2C_INSTANCE, &i2cDevice,
(const uint8_t *)(DESIGNCAPACITY_L), 1, &prvLsbCap, 1, DEVICE_I2C_TIMEOUT);
if (i2cStatus != kStatus_I2C_Success)
return false;
msbCap = (capacityVal >> 8) & 0xFF;
lsbCap = capacityVal & 0xFF;
if ((prvMsbCap != (msbCap)) || (prvLsbCap != lsbCap))
{
// Write new Design Capacity
txBuf [0] = DESIGNCAPACITY_H;
txBuf [1] = msbCap;
i2cStatus = I2C_DRV_MasterSendDataBlocking(BOARD_I2C_INSTANCE, &i2cDevice,
NULL, 0, (const uint8_t*)txBuf, 2, DEVICE_I2C_TIMEOUT);
if (i2cStatus != kStatus_I2C_Success)
return false;
txBuf [0] = DESIGNCAPACITY_L;
txBuf [1] = lsbCap;
i2cStatus = I2C_DRV_MasterSendDataBlocking(BOARD_I2C_INSTANCE, &i2cDevice,
NULL, 0, (const uint8_t*)txBuf, 2, DEVICE_I2C_TIMEOUT);
if (i2cStatus != kStatus_I2C_Success)
return false;
// Compute and write checksum
tempMod = (255 - prvCheckSum - prvMsbCap - prvLsbCap) % 256;
checkSum = 255 - ((tempMod + msbCap + lsbCap) % 256);
txBuf [0] = BLOCKDATACHECKSUM;
txBuf [1] = checkSum;
//Getting NACK
i2cStatus = I2C_DRV_MasterSendDataBlocking(BOARD_I2C_INSTANCE, &i2cDevice,
NULL, 0, (const uint8_t*)txBuf, 2, DEVICE_I2C_TIMEOUT);
if (i2cStatus != kStatus_I2C_Success)
return false;
}
// Exit CFG with soft reset
txBuf [0] = BQ27621_CTRL1_ADDR;
txBuf [2] = (SOFT_RESET) & 0xff;
txBuf [1] = SOFT_RESET & 0xff;
i2cStatus = I2C_DRV_MasterSendDataBlocking(BOARD_I2C_INSTANCE, &i2cDevice,
NULL, 0, (const uint8_t*)txBuf, 3, DEVICE_I2C_TIMEOUT);
if (i2cStatus != kStatus_I2C_Success)
return false;
// Confirm CFG Update Exit
_bq27621ReadFlag(&flagVal);
if ((flagVal & 0x10) == 0x10)
return false;
// Return to SEALED
txBuf [0] = 0x00;
txBuf [1] = SEAL_CODE_L;
txBuf [2] = SEAL_CODE_H;
i2cStatus = I2C_DRV_MasterSendDataBlocking(BOARD_I2C_INSTANCE, &i2cDevice,
NULL, 0, (const uint8_t*)txBuf, 3, DEVICE_I2C_TIMEOUT);
if (i2cStatus != kStatus_I2C_Success)
return false;
return true;
}