This class provides APIs to all of the registers of the TI BQ27441 battery gauge, as used on the u-blox C030 board. The caller should instantiate an I2C interface and pass this to init(), which will initialise the chip and place it into its lowest power state. When battery gauging is enabled, the getRemainingCapacity()/getRemainingPercentage() API calls may be used; otherwise the chip will be maintained in its lowest power state until a voltage/current/temperature reading is requested.
Dependents: example-battery-gauge-bq27441
TESTS/unit_tests/default/main.cpp
- Committer:
- breadboardbasics
- Date:
- 2017-12-13
- Revision:
- 6:998cc334f8f2
- Parent:
- 5:63b325f2c21a
File content as of revision 6:998cc334f8f2:
#include "mbed.h" #include "greentea-client/test_env.h" #include "unity.h" #include "utest.h" #include "battery_gauge_bq27441.h" using namespace utest::v1; // ---------------------------------------------------------------- // COMPILE-TIME MACROS // ---------------------------------------------------------------- // Pick some sensible minimum and maximum numbers #define MAX_TEMPERATURE_READING_C 80 #define MIN_TEMPERATURE_READING_C -20 #define MIN_VOLTAGE_READING_MV 0 #define MAX_VOLTAGE_READING_MV 12000 // Bigger than a 3 cell LiPo #define MAX_CURRENT_READING_MA 2000 #define MIN_CURRENT_READING_MA -2000 #define MIN_CAPACITY_READING_MAH 0 #define MAX_CAPACITY_READING_MAH 30000 // A very big battery indeed // The maximum size of configuration block // that we can handle in one go #define MAX_CONFIG_BLOCK_SIZE 32 // ---------------------------------------------------------------- // PRIVATE VARIABLES // ---------------------------------------------------------------- // I2C interface I2C * gpI2C = new I2C(I2C_SDA_B, I2C_SCL_B); // An empty array, so that we can check for emptiness static const char zeroArray[MAX_CONFIG_BLOCK_SIZE] = {0}; // ---------------------------------------------------------------- // PRIVATE FUNCTIONS // ---------------------------------------------------------------- // Print a buffer as a nice hex string static void printBytesAsHex(const char * pBuf, uint32_t size) { uint32_t x; printf (" 0 1 2 3 4 5 6 7 8 9 A B C D E F\n"); for (x = 1; x <= size; x++, pBuf++) { if (x % 16 == 8) { printf ("%02x ", *pBuf); } else if (x % 16 == 0) { printf ("%02x\n", *pBuf); } else { printf ("%02x-", *pBuf); } } if (x % 16 != 1) { printf("\n"); } } // ---------------------------------------------------------------- // TESTS // ---------------------------------------------------------------- // Test that the BQ27441 battery gauge can be initialised void test_init() { BatteryGaugeBq27441 * pBatteryGauge = new BatteryGaugeBq27441(); TEST_ASSERT_FALSE(pBatteryGauge->init(NULL)); TEST_ASSERT(pBatteryGauge->init(gpI2C)); } // Test that battery capacity monitoring can be performed void test_monitor() { BatteryGaugeBq27441 * pBatteryGauge = new BatteryGaugeBq27441(); // Call should fail if the battery gauge has not been initialised TEST_ASSERT_FALSE(pBatteryGauge->enableGauge()); TEST_ASSERT(pBatteryGauge->init(gpI2C)); #ifdef TARGET_UBLOX_C030 // Battery detection is not supported on C030 TEST_ASSERT(pBatteryGauge->disableBatteryDetect()); #endif // Normal case TEST_ASSERT(pBatteryGauge->enableGauge()); TEST_ASSERT(pBatteryGauge->isGaugeEnabled()); // TODO do something to assess whether it's actually working TEST_ASSERT(pBatteryGauge->disableGauge()); TEST_ASSERT(!pBatteryGauge->isGaugeEnabled()); // Normal case, slow mode TEST_ASSERT(pBatteryGauge->enableGauge(true)); TEST_ASSERT(pBatteryGauge->isGaugeEnabled()); // TODO do something to assess whether it's actually working slowly TEST_ASSERT(pBatteryGauge->disableGauge()); TEST_ASSERT(!pBatteryGauge->isGaugeEnabled()); } // Test that battery detection can be performed // TODO: find a way to check that a battery is not detected correctly void test_battery_detection() { BatteryGaugeBq27441 * pBatteryGauge = new BatteryGaugeBq27441(); // Call should fail if the battery gauge has not been initialised TEST_ASSERT_FALSE(pBatteryGauge->isBatteryDetected()); // Normal case TEST_ASSERT(pBatteryGauge->init(gpI2C)); #ifdef TARGET_UBLOX_C030 // Battery detection is not supported on C030 TEST_ASSERT(pBatteryGauge->disableBatteryDetect()); #endif TEST_ASSERT(pBatteryGauge->isBatteryDetected()); } // Test that a temperature reading can be performed void test_temperature() { BatteryGaugeBq27441 * pBatteryGauge = new BatteryGaugeBq27441(); int32_t temperatureC = MIN_TEMPERATURE_READING_C - 1; // Call should fail if the battery gauge has not been initialised TEST_ASSERT_FALSE(pBatteryGauge->getTemperature(&temperatureC)); // Normal case TEST_ASSERT(pBatteryGauge->init(gpI2C)); TEST_ASSERT(pBatteryGauge->getTemperature(&temperatureC)); printf ("Temperature %d C.\n", (int) temperatureC); // Range check TEST_ASSERT((temperatureC >= MIN_TEMPERATURE_READING_C) && (temperatureC <= MAX_TEMPERATURE_READING_C)); // The parameter is allowed to be NULL TEST_ASSERT(pBatteryGauge->getTemperature(NULL)); } // Test that a voltage reading can be performed void test_voltage() { BatteryGaugeBq27441 * pBatteryGauge = new BatteryGaugeBq27441(); int32_t voltageMV = MIN_VOLTAGE_READING_MV - 1; // Call should fail if the battery gauge has not been initialised TEST_ASSERT_FALSE(pBatteryGauge->getVoltage(&voltageMV)); // Normal case TEST_ASSERT(pBatteryGauge->init(gpI2C)); TEST_ASSERT(pBatteryGauge->getVoltage(&voltageMV)); printf ("Voltage %.3f V.\n", ((float) voltageMV) / 1000); // Range check TEST_ASSERT((voltageMV >= MIN_VOLTAGE_READING_MV) && (voltageMV <= MAX_VOLTAGE_READING_MV)); // The parameter is allowed to be NULL TEST_ASSERT(pBatteryGauge->getVoltage(NULL)); } // Test that a current reading can be performed void test_current() { BatteryGaugeBq27441 * pBatteryGauge = new BatteryGaugeBq27441(); int32_t currentMA = MIN_CURRENT_READING_MA - 1; // Call should fail if the battery gauge has not been initialised TEST_ASSERT_FALSE(pBatteryGauge->getCurrent(¤tMA)); // Normal case TEST_ASSERT(pBatteryGauge->init(gpI2C)); TEST_ASSERT(pBatteryGauge->getCurrent(¤tMA)); printf ("Current %.3f A.\n", ((float) currentMA) / 1000); // Range check TEST_ASSERT((currentMA >= MIN_CURRENT_READING_MA) && (currentMA <= MAX_CURRENT_READING_MA)); // The parameter is allowed to be NULL TEST_ASSERT(pBatteryGauge->getCurrent(NULL)); } // Test that a remaining capacity reading can be performed void test_remaining_capacity() { BatteryGaugeBq27441 * pBatteryGauge = new BatteryGaugeBq27441(); int32_t capacityMAh = MIN_CAPACITY_READING_MAH - 1; // Call should fail if the battery gauge has not been initialised TEST_ASSERT_FALSE(pBatteryGauge->getRemainingCapacity(&capacityMAh)); // Normal case TEST_ASSERT(pBatteryGauge->init(gpI2C)); TEST_ASSERT(pBatteryGauge->getRemainingCapacity(&capacityMAh)); printf ("Remaining capacity %.3f Ah.\n", ((float) capacityMAh) / 1000); // Range check TEST_ASSERT((capacityMAh >= MIN_CAPACITY_READING_MAH) && (capacityMAh <= MAX_CAPACITY_READING_MAH)); // The parameter is allowed to be NULL TEST_ASSERT(pBatteryGauge->getRemainingCapacity(NULL)); } // Test that a remaining percentage reading can be performed void test_remaining_percentage() { BatteryGaugeBq27441 * pBatteryGauge = new BatteryGaugeBq27441(); int32_t batteryPercent = 101; // Call should fail if the battery gauge has not been initialised TEST_ASSERT_FALSE(pBatteryGauge->getRemainingPercentage(&batteryPercent)); // Normal case TEST_ASSERT(pBatteryGauge->init(gpI2C)); #ifdef TARGET_UBLOX_C030 // Battery detection is not supported on C030 // and battery detect is required for the "gauging" type APIs TEST_ASSERT(pBatteryGauge->disableBatteryDetect()); #endif TEST_ASSERT(pBatteryGauge->getRemainingPercentage(&batteryPercent)); printf ("Remaining percentage %d%%.\n", (int) batteryPercent); // Range check TEST_ASSERT((batteryPercent >= 0) && (batteryPercent <= 100)); // The parameter is allowed to be NULL TEST_ASSERT(pBatteryGauge->getRemainingPercentage(NULL)); } // Test advanced functions to read the configuration of the chip void test_advanced_config_1() { BatteryGaugeBq27441 * pBatteryGauge = new BatteryGaugeBq27441(); uint8_t subClassId = 80; // IT Cfg int32_t offset = 0; int32_t length = MAX_CONFIG_BLOCK_SIZE - offset; char data1[MAX_CONFIG_BLOCK_SIZE]; uint32_t deadArea1 = 0xdeadbeef; char data2[MAX_CONFIG_BLOCK_SIZE]; uint32_t deadArea2 = 0xdeadbeef; // Initialise the battery gauge TEST_ASSERT(pBatteryGauge->init(gpI2C)); // Read IT Cfg (total length 79 bytes), starting from 0, into data1 subClassId = 80; memset(&(data1[0]), 0, sizeof (data1)); TEST_ASSERT(pBatteryGauge->advancedGetConfig(subClassId, offset, length, &(data1[0]))); printf("%d bytes received from subClassID %d, offset %d:\n", (int) length, subClassId, (int) offset); printBytesAsHex(&(data1[0]), length); TEST_ASSERT_EQUAL_UINT32 (0xdeadbeef, deadArea1); // Read it again, with an offset of 16 bytes, into data2 offset = 16; length = MAX_CONFIG_BLOCK_SIZE - 16; memset(&(data2[0]), 0, sizeof (data2)); TEST_ASSERT(pBatteryGauge->advancedGetConfig(subClassId, offset, length, &(data2[0]))); printf("%d bytes received from subClassID %d, offset %d:\n", (int) length, subClassId, (int) offset); printBytesAsHex(&(data2[0]), length); // The second 16 bytes of data1 and the first 16 bytes of data2 should match TEST_ASSERT_EQUAL_UINT8_ARRAY(&(data1[16]), &(data2[0]), 16); TEST_ASSERT_EQUAL_UINT32 (0xdeadbeef, deadArea2); // Read the next block of IT Cfg into data1 offset = MAX_CONFIG_BLOCK_SIZE; length = MAX_CONFIG_BLOCK_SIZE; memset(&(data1[0]), 0, sizeof (data1)); TEST_ASSERT(pBatteryGauge->advancedGetConfig(subClassId, offset, length, &(data1[0]))); printf("%d bytes received from subClassID %d, offset %d:\n", (int) length, subClassId, (int) offset); printBytesAsHex(&(data1[0]), length); TEST_ASSERT_EQUAL_UINT32 (0xdeadbeef, deadArea1); // Read the only the first 16 bytes, from the same offset into IT Cfg, into data2 length = 16; memset(&(data2[0]), 0, sizeof (data2)); TEST_ASSERT(pBatteryGauge->advancedGetConfig(subClassId, offset, length, &(data2[0]))); printf("%d bytes received from subClassID %d, offset %d:\n", (int) length, subClassId, (int) offset); printBytesAsHex(&(data2[0]), length); // The first 16 bytes of data1 and data2 should match TEST_ASSERT_EQUAL_UINT8_ARRAY(&(data1[0]), &(data2[0]), length); // The remainder of data2 should be zero TEST_ASSERT_EQUAL_UINT8_ARRAY(&(zeroArray[0]), &(data2[length]), sizeof(data2) - length); TEST_ASSERT_EQUAL_UINT32 (0xdeadbeef, deadArea2); } // Test advanced functions to write configuration to the chip void test_advanced_config_2() { BatteryGaugeBq27441 * pBatteryGauge = new BatteryGaugeBq27441(); uint8_t subClassId = 80; // IT Cfg int32_t offset = 0; int32_t length = MAX_CONFIG_BLOCK_SIZE - offset; char data1[MAX_CONFIG_BLOCK_SIZE]; uint32_t deadArea1 = 0xdeadbeef; char data2[MAX_CONFIG_BLOCK_SIZE]; // Initialise the battery gauge TEST_ASSERT(pBatteryGauge->init(gpI2C)); // Read Delta Voltage, two bytes at offset 39 in sub-class State, into data1 subClassId = 82; offset = 39; length = 2; memset(&(data1[0]), 0, sizeof (data1)); TEST_ASSERT(pBatteryGauge->advancedGetConfig(subClassId, offset, length, &(data1[0]))); printf("%d bytes received from subClassID %d, offset %d:\n", (int) length, subClassId, (int) offset); printBytesAsHex(&(data1[0]), length); TEST_ASSERT_EQUAL_UINT32 (0xdeadbeef, deadArea1); // Copy Delta Voltage, change the lower byte and then write it back (data1[1])++; printf ("Modified data block:\n"); printBytesAsHex(&(data1[0]), length); TEST_ASSERT(pBatteryGauge->advancedSetConfig(subClassId, offset, length, &(data1[0]))); printf("%d bytes written to subClassID %d, offset %d:\n", (int) length, subClassId, (int) offset); // Read it back and check that the Delta Voltage really is the new value subClassId = 82; offset = 32; length = 9; memset(&(data2[0]), 0, sizeof (data2)); TEST_ASSERT(pBatteryGauge->advancedGetConfig(subClassId, offset, length, &(data2[0]))); printf("%d bytes received from subClassID %d, offset %d:\n", (int) length, subClassId, (int) offset); printBytesAsHex(&(data2[0]), length); TEST_ASSERT_EQUAL_UINT32 (0xdeadbeef, deadArea1); TEST_ASSERT_EQUAL_UINT32 (data1[0], data2[7]); TEST_ASSERT_EQUAL_UINT32 (data1[1], data2[8]); // Now put Delta Voltage back as it was (data2[8])--; TEST_ASSERT(pBatteryGauge->advancedSetConfig(subClassId, offset, length, &(data2[0]))); printf("%d bytes written to subClassID %d, offset %d:\n", (int) length, subClassId, (int) offset); } // Test fail cases of the advanced configuration functions void test_advanced_config_3() { BatteryGaugeBq27441 * pBatteryGauge = new BatteryGaugeBq27441(); uint8_t subClassId = 80; // IT Cfg int32_t offset = 0; int32_t length = MAX_CONFIG_BLOCK_SIZE - offset; char data1[MAX_CONFIG_BLOCK_SIZE]; // All calls should fail if the battery gauge has not been initialised TEST_ASSERT_FALSE(pBatteryGauge->advancedSetConfig(subClassId, offset, length, &(data1[0]))); TEST_ASSERT_FALSE(pBatteryGauge->advancedGetConfig(subClassId, offset, length, &(data1[0]))); // Initialise the battery gauge TEST_ASSERT(pBatteryGauge->init(gpI2C)); // Perform some reads of bad length/offset combinations offset = 0; length = 33; TEST_ASSERT_FALSE(pBatteryGauge->advancedGetConfig(subClassId, offset, length, &(data1[0]))); TEST_ASSERT_FALSE(pBatteryGauge->advancedSetConfig(subClassId, offset, length, &(data1[0]))); offset = 1; length = 32; TEST_ASSERT_FALSE(pBatteryGauge->advancedGetConfig(subClassId, offset, length, &(data1[0]))); TEST_ASSERT_FALSE(pBatteryGauge->advancedSetConfig(subClassId, offset, length, &(data1[0]))); offset = 31; length = 2; TEST_ASSERT_FALSE(pBatteryGauge->advancedGetConfig(subClassId, offset, length, &(data1[0]))); TEST_ASSERT_FALSE(pBatteryGauge->advancedSetConfig(subClassId, offset, length, &(data1[0]))); offset = 32; length = 33; TEST_ASSERT_FALSE(pBatteryGauge->advancedGetConfig(subClassId, offset, length, &(data1[0]))); TEST_ASSERT_FALSE(pBatteryGauge->advancedSetConfig(subClassId, offset, length, &(data1[0]))); } // Send a control word to the BQ27441 battery gauge chip void test_advanced_control() { BatteryGaugeBq27441 * pBatteryGauge = new BatteryGaugeBq27441(); uint16_t controlWord = 0x0002; // get FW version uint16_t response = 0; // Call should fail if the battery gauge has not been initialised TEST_ASSERT_FALSE(pBatteryGauge->advancedSendControlWord(controlWord, &response)); // Initialise the battery gauge TEST_ASSERT(pBatteryGauge->init(gpI2C)); // Normal case TEST_ASSERT(pBatteryGauge->advancedSendControlWord(controlWord, &response)); // FW version must be 0x0109 TEST_ASSERT_EQUAL_UINT16(0x0109, response); // The parameter is allowed to be null TEST_ASSERT(pBatteryGauge->advancedSendControlWord(controlWord, NULL)); } // Read using a standard command from the BQ27441 battery gauge chip void test_advanced_get() { BatteryGaugeBq27441 * pBatteryGauge = new BatteryGaugeBq27441(); uint8_t address = 0x02; // Temperature uint16_t value = 0; int32_t temperatureC = -1; // Call should fail if the battery gauge has not been initialised TEST_ASSERT_FALSE(pBatteryGauge->advancedGet(address, &value)); // Initialise the battery gauge TEST_ASSERT(pBatteryGauge->init(gpI2C)); // Normal case TEST_ASSERT(pBatteryGauge->advancedGet(address, &value)); // Get the temperature via the standard API command TEST_ASSERT(pBatteryGauge->getTemperature(&temperatureC)); // Convert the value returned into a temperature reading and compare // it with the real answer, allowing a 1 degree tolerance in case // it has changed between readings. TEST_ASSERT_INT32_WITHIN (1, temperatureC, ((int32_t) value / 10) - 273); // The parameter is allowed to be null TEST_ASSERT(pBatteryGauge->advancedGet(address, NULL)); } // Test that the chip can be sealed and unsealed void test_advanced_seal() { BatteryGaugeBq27441 * pBatteryGauge = new BatteryGaugeBq27441(); uint8_t subClassId = 80; // IT Cfg int32_t offset = 78; // Position of the "TermV valid t" item at offset 78 int32_t length = 1; // Length of "TermV valid t" char data1[MAX_CONFIG_BLOCK_SIZE]; char data2[MAX_CONFIG_BLOCK_SIZE]; char data3[MAX_CONFIG_BLOCK_SIZE]; int32_t value; memset(&(data1[0]), 0, sizeof (data1)); memset(&(data2[0]), 0, sizeof (data2)); memset(&(data3[0]), 0, sizeof (data3)); // Make sure that the device is not sealed from a previous field test run TEST_ASSERT(pBatteryGauge->init(gpI2C)); #ifdef TARGET_UBLOX_C030 // Battery detection is not supported on C030 TEST_ASSERT(pBatteryGauge->disableBatteryDetect()); #endif TEST_ASSERT(pBatteryGauge->advancedUnseal()); delete pBatteryGauge; pBatteryGauge = new BatteryGaugeBq27441(); // Calls should fail if the battery gauge has not been initialised printf ("Calling advancedIsSealed()...\n"); TEST_ASSERT_FALSE(pBatteryGauge->advancedIsSealed()); printf ("Calling advancedSeal()...\n"); TEST_ASSERT_FALSE(pBatteryGauge->advancedSeal()); printf ("Calling advancedUnseal()...\n"); TEST_ASSERT_FALSE(pBatteryGauge->advancedUnseal()); // Normal case printf ("Calling init()...\n"); TEST_ASSERT(pBatteryGauge->init(gpI2C)); printf ("Calling advancedIsSealed()...\n"); TEST_ASSERT_FALSE(pBatteryGauge->advancedIsSealed()); // This call should pass printf ("Calling advancedGetConfig()...\n"); TEST_ASSERT(pBatteryGauge->advancedGetConfig(subClassId , offset, length, &(data1[0]))); // Now seal it printf ("Calling advancedSeal()...\n"); TEST_ASSERT(pBatteryGauge->advancedSeal()); printf ("Calling advancedIsSealed()...\n"); TEST_ASSERT(pBatteryGauge->advancedIsSealed()); memcpy (&(data2[0]), &(data1[0]), sizeof (data2)); // Try to increment the "TermV valid t" item (data2[0])++; // These calls should all be unaffected by sealing printf ("Calling advancedSetConfig()...\n"); TEST_ASSERT(pBatteryGauge->advancedSetConfig(subClassId, offset, length, &(data2[0]))); printf ("Calling advancedGetConfig()...\n"); TEST_ASSERT(pBatteryGauge->advancedGetConfig(subClassId, offset, length, &(data3[0]))); TEST_ASSERT(memcmp (&(data2[0]), &(data3[0]), sizeof (data2)) == 0); // Put "TermV valid t" back as it was (data2[0])--; printf ("Calling advancedSetConfig()...\n"); TEST_ASSERT(pBatteryGauge->advancedSetConfig(subClassId, offset, length, &(data2[0]))); printf ("Calling enableGauge()...\n"); TEST_ASSERT(pBatteryGauge->enableGauge()); printf ("Calling isBatteryDetected()...\n"); TEST_ASSERT(pBatteryGauge->isBatteryDetected()); printf ("Calling getTemperature()...\n"); TEST_ASSERT(pBatteryGauge->getTemperature(&value)); printf ("Calling getVoltage()...\n"); TEST_ASSERT(pBatteryGauge->getVoltage(&value)); printf ("Calling getCurrent()...\n"); TEST_ASSERT(pBatteryGauge->getCurrent(&value)); printf ("Calling getRemainingCapacity()...\n"); TEST_ASSERT(pBatteryGauge->getRemainingCapacity(&value)); printf ("Calling getRemainingPercentage()...\n"); TEST_ASSERT(pBatteryGauge->getRemainingPercentage(&value)); printf ("Calling enableGauge(\"true\")...\n"); TEST_ASSERT(pBatteryGauge->enableGauge(true)); printf ("Calling disableGauge()...\n"); TEST_ASSERT(pBatteryGauge->disableGauge()); // Now unseal it printf ("Calling advancedUnseal()...\n"); TEST_ASSERT(pBatteryGauge->advancedUnseal()); printf ("Calling advancedIsSealed()...\n"); TEST_ASSERT_FALSE(pBatteryGauge->advancedIsSealed()); // These calls should all still work // Try to increment the "TermV valid t" item (data2[0])++; printf ("Calling advancedSetConfig()...\n"); TEST_ASSERT(pBatteryGauge->advancedSetConfig(subClassId, offset, length, &(data2[0]))); printf ("Calling advancedGetConfig()...\n"); TEST_ASSERT(pBatteryGauge->advancedGetConfig(subClassId, offset, length, &(data3[0]))); TEST_ASSERT(memcmp (&(data2[0]), &(data3[0]), sizeof (data2)) == 0); // Put "TermV valid t" back as it was (data2[0])--; printf ("Calling advancedSetConfig()...\n"); TEST_ASSERT(pBatteryGauge->advancedSetConfig(subClassId, offset, length, &(data2[0]))); printf ("Calling enableGauge(\"true\")...\n"); TEST_ASSERT(pBatteryGauge->enableGauge(true)); printf ("Calling isBatteryDetected()...\n"); TEST_ASSERT(pBatteryGauge->isBatteryDetected()); printf ("Calling getTemperature()...\n"); TEST_ASSERT(pBatteryGauge->getTemperature(&value)); printf ("Calling getVoltage()...\n"); TEST_ASSERT(pBatteryGauge->getVoltage(&value)); printf ("Calling getCurrent()...\n"); TEST_ASSERT(pBatteryGauge->getCurrent(&value)); printf ("Calling getRemainingCapacity()...\n"); TEST_ASSERT(pBatteryGauge->getRemainingCapacity(&value)); printf ("Calling getRemainingPercentage()...\n"); TEST_ASSERT(pBatteryGauge->getRemainingPercentage(&value)); printf ("Calling disableGauge()...\n"); TEST_ASSERT(pBatteryGauge->disableGauge()); // TODO: I had some tests in here to check that init() and // advancedUnseal() behave when given the wrong seal code. // However, as soon as the chip gets a wrong seal code it // refuses to unseal again (I tried a 4 second delay but // that didn't help). This needs investigating. } // Reset the BQ27441 battery gauge chip at the outset void test_advanced_reset() { BatteryGaugeBq27441 * pBatteryGauge = new BatteryGaugeBq27441(); uint8_t subClassId = 80; // IT Cfg int32_t offset = 78; // Position of the "TermV valid t" item at offset 78 int32_t length = 1; // Length of "TermV valid t" char data1[MAX_CONFIG_BLOCK_SIZE]; char data2[MAX_CONFIG_BLOCK_SIZE]; char data3[MAX_CONFIG_BLOCK_SIZE]; memset(&(data1[0]), 0, sizeof (data1)); memset(&(data2[0]), 0, sizeof (data2)); memset(&(data3[0]), 0, sizeof (data3)); // Call should fail if the battery gauge has not been initialised TEST_ASSERT_FALSE(pBatteryGauge->advancedReset()); TEST_ASSERT(pBatteryGauge->init(gpI2C)); TEST_ASSERT(pBatteryGauge->advancedUnseal()); // Normal case // Increment the "TermV valid t" item TEST_ASSERT(pBatteryGauge->advancedGetConfig(subClassId, offset, length, &(data1[0]))); memcpy (&(data2[0]), &(data1[0]), sizeof (data2)); (data2[0])++; TEST_ASSERT(pBatteryGauge->advancedSetConfig(subClassId, offset, length, &(data2[0]))); // Read it back to make sure it was set TEST_ASSERT(pBatteryGauge->advancedGetConfig(subClassId, offset, length, &(data3[0]))); TEST_ASSERT(memcmp (&(data2[0]), &(data3[0]), sizeof (data2)) == 0); // Now reset the chip and check that the value is back to what it was before TEST_ASSERT(pBatteryGauge->advancedReset()); TEST_ASSERT(pBatteryGauge->advancedGetConfig(subClassId, offset, length, &(data3[0]))); TEST_ASSERT(memcmp (&(data1[0]), &(data3[0]), sizeof (data1)) == 0); } // ---------------------------------------------------------------- // TEST ENVIRONMENT // ---------------------------------------------------------------- // Setup the test environment utest::v1::status_t test_setup(const size_t number_of_cases) { // Setup Greentea, timeout is long enough to run these tests with // DEBUG_BQ27441 defined // Note: timeout is quite long as the chip has 4 second // timeouts in quite a lot of cases. GREENTEA_SETUP(480, "default_auto"); return verbose_test_setup_handler(number_of_cases); } // Test cases Case cases[] = { Case("Initialisation", test_init), Case("Monitoring", test_monitor), Case("Battery detection", test_battery_detection), Case("Temperature read", test_temperature), Case("Voltage read", test_voltage), Case("Current read", test_current), Case("Remaining capacity read", test_remaining_capacity), Case("Remaining percentage read", test_remaining_percentage), Case("Advanced config read", test_advanced_config_1), Case("Advanced config write", test_advanced_config_2), Case("Advanced config read/write fail cases", test_advanced_config_3), Case("Advanced control", test_advanced_control), Case("Advanced get", test_advanced_get), Case("Advanced seal", test_advanced_seal), Case("Advanced reset", test_advanced_reset) }; Specification specification(test_setup, cases); // ---------------------------------------------------------------- // MAIN // ---------------------------------------------------------------- // Entry point into the tests int main() { bool success = false; if (gpI2C != NULL) { success = !Harness::run(specification); } else { printf ("Unable to instantiate I2C interface.\n"); } return success; } // End Of File