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@6:998cc334f8f2, 2017-12-13 (annotated)
- Committer:
- breadboardbasics
- Date:
- Wed Dec 13 17:14:51 2017 +0000
- Revision:
- 6:998cc334f8f2
- Parent:
- 5:63b325f2c21a
Fixes current = 0 problem and adds power measurement capability
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
rob.meades@u-blox.com | 1:566163f17cde | 1 | #include "mbed.h" |
rob.meades@u-blox.com | 1:566163f17cde | 2 | #include "greentea-client/test_env.h" |
rob.meades@u-blox.com | 1:566163f17cde | 3 | #include "unity.h" |
rob.meades@u-blox.com | 1:566163f17cde | 4 | #include "utest.h" |
rob.meades@u-blox.com | 1:566163f17cde | 5 | #include "battery_gauge_bq27441.h" |
rob.meades@u-blox.com | 1:566163f17cde | 6 | |
rob.meades@u-blox.com | 1:566163f17cde | 7 | using namespace utest::v1; |
rob.meades@u-blox.com | 1:566163f17cde | 8 | |
rob.meades@u-blox.com | 1:566163f17cde | 9 | // ---------------------------------------------------------------- |
rob.meades@u-blox.com | 1:566163f17cde | 10 | // COMPILE-TIME MACROS |
rob.meades@u-blox.com | 1:566163f17cde | 11 | // ---------------------------------------------------------------- |
rob.meades@u-blox.com | 1:566163f17cde | 12 | |
rob.meades@u-blox.com | 1:566163f17cde | 13 | // Pick some sensible minimum and maximum numbers |
rob.meades@u-blox.com | 1:566163f17cde | 14 | #define MAX_TEMPERATURE_READING_C 80 |
rob.meades@u-blox.com | 1:566163f17cde | 15 | #define MIN_TEMPERATURE_READING_C -20 |
rob.meades@u-blox.com | 1:566163f17cde | 16 | #define MIN_VOLTAGE_READING_MV 0 |
rob.meades@u-blox.com | 1:566163f17cde | 17 | #define MAX_VOLTAGE_READING_MV 12000 // Bigger than a 3 cell LiPo |
rob.meades@u-blox.com | 1:566163f17cde | 18 | #define MAX_CURRENT_READING_MA 2000 |
rob.meades@u-blox.com | 1:566163f17cde | 19 | #define MIN_CURRENT_READING_MA -2000 |
rob.meades@u-blox.com | 1:566163f17cde | 20 | #define MIN_CAPACITY_READING_MAH 0 |
rob.meades@u-blox.com | 1:566163f17cde | 21 | #define MAX_CAPACITY_READING_MAH 30000 // A very big battery indeed |
rob.meades@u-blox.com | 1:566163f17cde | 22 | |
rob.meades@u-blox.com | 1:566163f17cde | 23 | // The maximum size of configuration block |
rob.meades@u-blox.com | 1:566163f17cde | 24 | // that we can handle in one go |
rob.meades@u-blox.com | 1:566163f17cde | 25 | #define MAX_CONFIG_BLOCK_SIZE 32 |
rob.meades@u-blox.com | 1:566163f17cde | 26 | |
rob.meades@u-blox.com | 1:566163f17cde | 27 | // ---------------------------------------------------------------- |
rob.meades@u-blox.com | 1:566163f17cde | 28 | // PRIVATE VARIABLES |
rob.meades@u-blox.com | 1:566163f17cde | 29 | // ---------------------------------------------------------------- |
rob.meades@u-blox.com | 1:566163f17cde | 30 | |
rob.meades@u-blox.com | 1:566163f17cde | 31 | // I2C interface |
rob.meades@u-blox.com | 3:ebd56471d57c | 32 | I2C * gpI2C = new I2C(I2C_SDA_B, I2C_SCL_B); |
rob.meades@u-blox.com | 1:566163f17cde | 33 | |
rob.meades@u-blox.com | 1:566163f17cde | 34 | // An empty array, so that we can check for emptiness |
rob.meades@u-blox.com | 1:566163f17cde | 35 | static const char zeroArray[MAX_CONFIG_BLOCK_SIZE] = {0}; |
rob.meades@u-blox.com | 1:566163f17cde | 36 | |
rob.meades@u-blox.com | 1:566163f17cde | 37 | // ---------------------------------------------------------------- |
rob.meades@u-blox.com | 1:566163f17cde | 38 | // PRIVATE FUNCTIONS |
rob.meades@u-blox.com | 1:566163f17cde | 39 | // ---------------------------------------------------------------- |
rob.meades@u-blox.com | 1:566163f17cde | 40 | |
rob.meades@u-blox.com | 1:566163f17cde | 41 | // Print a buffer as a nice hex string |
rob.meades@u-blox.com | 1:566163f17cde | 42 | static void printBytesAsHex(const char * pBuf, uint32_t size) |
rob.meades@u-blox.com | 1:566163f17cde | 43 | { |
rob.meades@u-blox.com | 1:566163f17cde | 44 | uint32_t x; |
rob.meades@u-blox.com | 1:566163f17cde | 45 | |
rob.meades@u-blox.com | 1:566163f17cde | 46 | printf (" 0 1 2 3 4 5 6 7 8 9 A B C D E F\n"); |
rob.meades@u-blox.com | 1:566163f17cde | 47 | for (x = 1; x <= size; x++, pBuf++) |
rob.meades@u-blox.com | 1:566163f17cde | 48 | { |
rob.meades@u-blox.com | 1:566163f17cde | 49 | if (x % 16 == 8) { |
rob.meades@u-blox.com | 1:566163f17cde | 50 | printf ("%02x ", *pBuf); |
rob.meades@u-blox.com | 1:566163f17cde | 51 | } else if (x % 16 == 0) { |
rob.meades@u-blox.com | 1:566163f17cde | 52 | printf ("%02x\n", *pBuf); |
rob.meades@u-blox.com | 1:566163f17cde | 53 | } else { |
rob.meades@u-blox.com | 1:566163f17cde | 54 | printf ("%02x-", *pBuf); |
rob.meades@u-blox.com | 1:566163f17cde | 55 | } |
rob.meades@u-blox.com | 1:566163f17cde | 56 | } |
rob.meades@u-blox.com | 1:566163f17cde | 57 | |
rob.meades@u-blox.com | 1:566163f17cde | 58 | if (x % 16 != 1) { |
rob.meades@u-blox.com | 1:566163f17cde | 59 | printf("\n"); |
rob.meades@u-blox.com | 1:566163f17cde | 60 | } |
rob.meades@u-blox.com | 1:566163f17cde | 61 | } |
rob.meades@u-blox.com | 1:566163f17cde | 62 | |
rob.meades@u-blox.com | 1:566163f17cde | 63 | // ---------------------------------------------------------------- |
rob.meades@u-blox.com | 1:566163f17cde | 64 | // TESTS |
rob.meades@u-blox.com | 1:566163f17cde | 65 | // ---------------------------------------------------------------- |
rob.meades@u-blox.com | 1:566163f17cde | 66 | |
rob.meades@u-blox.com | 1:566163f17cde | 67 | // Test that the BQ27441 battery gauge can be initialised |
rob.meades@u-blox.com | 1:566163f17cde | 68 | void test_init() { |
rob.meades@u-blox.com | 1:566163f17cde | 69 | BatteryGaugeBq27441 * pBatteryGauge = new BatteryGaugeBq27441(); |
rob.meades@u-blox.com | 1:566163f17cde | 70 | |
rob.meades@u-blox.com | 1:566163f17cde | 71 | TEST_ASSERT_FALSE(pBatteryGauge->init(NULL)); |
rob.meades@u-blox.com | 1:566163f17cde | 72 | TEST_ASSERT(pBatteryGauge->init(gpI2C)); |
rob.meades@u-blox.com | 1:566163f17cde | 73 | } |
rob.meades@u-blox.com | 1:566163f17cde | 74 | |
rob.meades@u-blox.com | 1:566163f17cde | 75 | // Test that battery capacity monitoring can be performed |
rob.meades@u-blox.com | 1:566163f17cde | 76 | void test_monitor() { |
rob.meades@u-blox.com | 1:566163f17cde | 77 | BatteryGaugeBq27441 * pBatteryGauge = new BatteryGaugeBq27441(); |
rob.meades@u-blox.com | 1:566163f17cde | 78 | |
rob.meades@u-blox.com | 1:566163f17cde | 79 | // Call should fail if the battery gauge has not been initialised |
rob.meades@u-blox.com | 1:566163f17cde | 80 | TEST_ASSERT_FALSE(pBatteryGauge->enableGauge()); |
rob.meades@u-blox.com | 1:566163f17cde | 81 | |
rob.meades@u-blox.com | 1:566163f17cde | 82 | TEST_ASSERT(pBatteryGauge->init(gpI2C)); |
rob.meades@u-blox.com | 5:63b325f2c21a | 83 | #ifdef TARGET_UBLOX_C030 |
rob.meades@u-blox.com | 5:63b325f2c21a | 84 | // Battery detection is not supported on C030 |
rob.meades@u-blox.com | 5:63b325f2c21a | 85 | TEST_ASSERT(pBatteryGauge->disableBatteryDetect()); |
rob.meades@u-blox.com | 5:63b325f2c21a | 86 | #endif |
rob.meades@u-blox.com | 5:63b325f2c21a | 87 | |
rob.meades@u-blox.com | 1:566163f17cde | 88 | // Normal case |
rob.meades@u-blox.com | 1:566163f17cde | 89 | TEST_ASSERT(pBatteryGauge->enableGauge()); |
rob.meades@u-blox.com | 3:ebd56471d57c | 90 | TEST_ASSERT(pBatteryGauge->isGaugeEnabled()); |
rob.meades@u-blox.com | 3:ebd56471d57c | 91 | |
rob.meades@u-blox.com | 1:566163f17cde | 92 | // TODO do something to assess whether it's actually working |
rob.meades@u-blox.com | 1:566163f17cde | 93 | TEST_ASSERT(pBatteryGauge->disableGauge()); |
rob.meades@u-blox.com | 3:ebd56471d57c | 94 | TEST_ASSERT(!pBatteryGauge->isGaugeEnabled()); |
rob.meades@u-blox.com | 1:566163f17cde | 95 | |
rob.meades@u-blox.com | 1:566163f17cde | 96 | // Normal case, slow mode |
rob.meades@u-blox.com | 1:566163f17cde | 97 | TEST_ASSERT(pBatteryGauge->enableGauge(true)); |
rob.meades@u-blox.com | 3:ebd56471d57c | 98 | TEST_ASSERT(pBatteryGauge->isGaugeEnabled()); |
rob.meades@u-blox.com | 1:566163f17cde | 99 | // TODO do something to assess whether it's actually working slowly |
rob.meades@u-blox.com | 1:566163f17cde | 100 | TEST_ASSERT(pBatteryGauge->disableGauge()); |
rob.meades@u-blox.com | 3:ebd56471d57c | 101 | TEST_ASSERT(!pBatteryGauge->isGaugeEnabled()); |
rob.meades@u-blox.com | 1:566163f17cde | 102 | } |
rob.meades@u-blox.com | 1:566163f17cde | 103 | |
rob.meades@u-blox.com | 1:566163f17cde | 104 | // Test that battery detection can be performed |
rob.meades@u-blox.com | 1:566163f17cde | 105 | // TODO: find a way to check that a battery is not detected correctly |
rob.meades@u-blox.com | 1:566163f17cde | 106 | void test_battery_detection() { |
rob.meades@u-blox.com | 1:566163f17cde | 107 | BatteryGaugeBq27441 * pBatteryGauge = new BatteryGaugeBq27441(); |
rob.meades@u-blox.com | 1:566163f17cde | 108 | |
rob.meades@u-blox.com | 1:566163f17cde | 109 | // Call should fail if the battery gauge has not been initialised |
rob.meades@u-blox.com | 1:566163f17cde | 110 | TEST_ASSERT_FALSE(pBatteryGauge->isBatteryDetected()); |
rob.meades@u-blox.com | 1:566163f17cde | 111 | |
rob.meades@u-blox.com | 1:566163f17cde | 112 | // Normal case |
rob.meades@u-blox.com | 1:566163f17cde | 113 | TEST_ASSERT(pBatteryGauge->init(gpI2C)); |
rob.meades@u-blox.com | 5:63b325f2c21a | 114 | #ifdef TARGET_UBLOX_C030 |
rob.meades@u-blox.com | 5:63b325f2c21a | 115 | // Battery detection is not supported on C030 |
rob.meades@u-blox.com | 5:63b325f2c21a | 116 | TEST_ASSERT(pBatteryGauge->disableBatteryDetect()); |
rob.meades@u-blox.com | 5:63b325f2c21a | 117 | #endif |
rob.meades@u-blox.com | 1:566163f17cde | 118 | TEST_ASSERT(pBatteryGauge->isBatteryDetected()); |
rob.meades@u-blox.com | 1:566163f17cde | 119 | } |
rob.meades@u-blox.com | 1:566163f17cde | 120 | |
rob.meades@u-blox.com | 1:566163f17cde | 121 | // Test that a temperature reading can be performed |
rob.meades@u-blox.com | 1:566163f17cde | 122 | void test_temperature() { |
rob.meades@u-blox.com | 1:566163f17cde | 123 | BatteryGaugeBq27441 * pBatteryGauge = new BatteryGaugeBq27441(); |
rob.meades@u-blox.com | 1:566163f17cde | 124 | int32_t temperatureC = MIN_TEMPERATURE_READING_C - 1; |
rob.meades@u-blox.com | 1:566163f17cde | 125 | |
rob.meades@u-blox.com | 1:566163f17cde | 126 | // Call should fail if the battery gauge has not been initialised |
rob.meades@u-blox.com | 1:566163f17cde | 127 | TEST_ASSERT_FALSE(pBatteryGauge->getTemperature(&temperatureC)); |
rob.meades@u-blox.com | 1:566163f17cde | 128 | |
rob.meades@u-blox.com | 1:566163f17cde | 129 | // Normal case |
rob.meades@u-blox.com | 1:566163f17cde | 130 | TEST_ASSERT(pBatteryGauge->init(gpI2C)); |
rob.meades@u-blox.com | 1:566163f17cde | 131 | TEST_ASSERT(pBatteryGauge->getTemperature(&temperatureC)); |
rob.meades@u-blox.com | 5:63b325f2c21a | 132 | printf ("Temperature %d C.\n", (int) temperatureC); |
rob.meades@u-blox.com | 1:566163f17cde | 133 | // Range check |
rob.meades@u-blox.com | 1:566163f17cde | 134 | TEST_ASSERT((temperatureC >= MIN_TEMPERATURE_READING_C) && (temperatureC <= MAX_TEMPERATURE_READING_C)); |
rob.meades@u-blox.com | 1:566163f17cde | 135 | |
rob.meades@u-blox.com | 1:566163f17cde | 136 | // The parameter is allowed to be NULL |
rob.meades@u-blox.com | 1:566163f17cde | 137 | TEST_ASSERT(pBatteryGauge->getTemperature(NULL)); |
rob.meades@u-blox.com | 1:566163f17cde | 138 | } |
rob.meades@u-blox.com | 1:566163f17cde | 139 | |
rob.meades@u-blox.com | 1:566163f17cde | 140 | // Test that a voltage reading can be performed |
rob.meades@u-blox.com | 1:566163f17cde | 141 | void test_voltage() { |
rob.meades@u-blox.com | 1:566163f17cde | 142 | BatteryGaugeBq27441 * pBatteryGauge = new BatteryGaugeBq27441(); |
rob.meades@u-blox.com | 1:566163f17cde | 143 | int32_t voltageMV = MIN_VOLTAGE_READING_MV - 1; |
rob.meades@u-blox.com | 1:566163f17cde | 144 | |
rob.meades@u-blox.com | 1:566163f17cde | 145 | // Call should fail if the battery gauge has not been initialised |
rob.meades@u-blox.com | 1:566163f17cde | 146 | TEST_ASSERT_FALSE(pBatteryGauge->getVoltage(&voltageMV)); |
rob.meades@u-blox.com | 1:566163f17cde | 147 | |
rob.meades@u-blox.com | 1:566163f17cde | 148 | // Normal case |
rob.meades@u-blox.com | 1:566163f17cde | 149 | TEST_ASSERT(pBatteryGauge->init(gpI2C)); |
rob.meades@u-blox.com | 1:566163f17cde | 150 | TEST_ASSERT(pBatteryGauge->getVoltage(&voltageMV)); |
rob.meades@u-blox.com | 1:566163f17cde | 151 | printf ("Voltage %.3f V.\n", ((float) voltageMV) / 1000); |
rob.meades@u-blox.com | 1:566163f17cde | 152 | // Range check |
rob.meades@u-blox.com | 1:566163f17cde | 153 | TEST_ASSERT((voltageMV >= MIN_VOLTAGE_READING_MV) && (voltageMV <= MAX_VOLTAGE_READING_MV)); |
rob.meades@u-blox.com | 1:566163f17cde | 154 | |
rob.meades@u-blox.com | 1:566163f17cde | 155 | // The parameter is allowed to be NULL |
rob.meades@u-blox.com | 1:566163f17cde | 156 | TEST_ASSERT(pBatteryGauge->getVoltage(NULL)); |
rob.meades@u-blox.com | 1:566163f17cde | 157 | } |
rob.meades@u-blox.com | 1:566163f17cde | 158 | |
rob.meades@u-blox.com | 1:566163f17cde | 159 | // Test that a current reading can be performed |
rob.meades@u-blox.com | 1:566163f17cde | 160 | void test_current() { |
rob.meades@u-blox.com | 1:566163f17cde | 161 | BatteryGaugeBq27441 * pBatteryGauge = new BatteryGaugeBq27441(); |
rob.meades@u-blox.com | 1:566163f17cde | 162 | int32_t currentMA = MIN_CURRENT_READING_MA - 1; |
rob.meades@u-blox.com | 1:566163f17cde | 163 | |
rob.meades@u-blox.com | 1:566163f17cde | 164 | // Call should fail if the battery gauge has not been initialised |
rob.meades@u-blox.com | 1:566163f17cde | 165 | TEST_ASSERT_FALSE(pBatteryGauge->getCurrent(¤tMA)); |
rob.meades@u-blox.com | 1:566163f17cde | 166 | |
rob.meades@u-blox.com | 1:566163f17cde | 167 | // Normal case |
rob.meades@u-blox.com | 1:566163f17cde | 168 | TEST_ASSERT(pBatteryGauge->init(gpI2C)); |
rob.meades@u-blox.com | 1:566163f17cde | 169 | TEST_ASSERT(pBatteryGauge->getCurrent(¤tMA)); |
rob.meades@u-blox.com | 1:566163f17cde | 170 | printf ("Current %.3f A.\n", ((float) currentMA) / 1000); |
rob.meades@u-blox.com | 1:566163f17cde | 171 | // Range check |
rob.meades@u-blox.com | 1:566163f17cde | 172 | TEST_ASSERT((currentMA >= MIN_CURRENT_READING_MA) && (currentMA <= MAX_CURRENT_READING_MA)); |
rob.meades@u-blox.com | 1:566163f17cde | 173 | |
rob.meades@u-blox.com | 1:566163f17cde | 174 | // The parameter is allowed to be NULL |
rob.meades@u-blox.com | 1:566163f17cde | 175 | TEST_ASSERT(pBatteryGauge->getCurrent(NULL)); |
rob.meades@u-blox.com | 1:566163f17cde | 176 | } |
rob.meades@u-blox.com | 1:566163f17cde | 177 | |
rob.meades@u-blox.com | 1:566163f17cde | 178 | // Test that a remaining capacity reading can be performed |
rob.meades@u-blox.com | 1:566163f17cde | 179 | void test_remaining_capacity() { |
rob.meades@u-blox.com | 1:566163f17cde | 180 | BatteryGaugeBq27441 * pBatteryGauge = new BatteryGaugeBq27441(); |
rob.meades@u-blox.com | 1:566163f17cde | 181 | int32_t capacityMAh = MIN_CAPACITY_READING_MAH - 1; |
rob.meades@u-blox.com | 1:566163f17cde | 182 | |
rob.meades@u-blox.com | 1:566163f17cde | 183 | // Call should fail if the battery gauge has not been initialised |
rob.meades@u-blox.com | 1:566163f17cde | 184 | TEST_ASSERT_FALSE(pBatteryGauge->getRemainingCapacity(&capacityMAh)); |
rob.meades@u-blox.com | 1:566163f17cde | 185 | |
rob.meades@u-blox.com | 1:566163f17cde | 186 | // Normal case |
rob.meades@u-blox.com | 1:566163f17cde | 187 | TEST_ASSERT(pBatteryGauge->init(gpI2C)); |
rob.meades@u-blox.com | 1:566163f17cde | 188 | TEST_ASSERT(pBatteryGauge->getRemainingCapacity(&capacityMAh)); |
rob.meades@u-blox.com | 1:566163f17cde | 189 | printf ("Remaining capacity %.3f Ah.\n", ((float) capacityMAh) / 1000); |
rob.meades@u-blox.com | 1:566163f17cde | 190 | // Range check |
rob.meades@u-blox.com | 1:566163f17cde | 191 | TEST_ASSERT((capacityMAh >= MIN_CAPACITY_READING_MAH) && (capacityMAh <= MAX_CAPACITY_READING_MAH)); |
rob.meades@u-blox.com | 1:566163f17cde | 192 | |
rob.meades@u-blox.com | 1:566163f17cde | 193 | // The parameter is allowed to be NULL |
rob.meades@u-blox.com | 1:566163f17cde | 194 | TEST_ASSERT(pBatteryGauge->getRemainingCapacity(NULL)); |
rob.meades@u-blox.com | 1:566163f17cde | 195 | } |
rob.meades@u-blox.com | 1:566163f17cde | 196 | |
rob.meades@u-blox.com | 1:566163f17cde | 197 | // Test that a remaining percentage reading can be performed |
rob.meades@u-blox.com | 1:566163f17cde | 198 | void test_remaining_percentage() { |
rob.meades@u-blox.com | 1:566163f17cde | 199 | BatteryGaugeBq27441 * pBatteryGauge = new BatteryGaugeBq27441(); |
rob.meades@u-blox.com | 1:566163f17cde | 200 | int32_t batteryPercent = 101; |
rob.meades@u-blox.com | 1:566163f17cde | 201 | |
rob.meades@u-blox.com | 1:566163f17cde | 202 | // Call should fail if the battery gauge has not been initialised |
rob.meades@u-blox.com | 1:566163f17cde | 203 | TEST_ASSERT_FALSE(pBatteryGauge->getRemainingPercentage(&batteryPercent)); |
rob.meades@u-blox.com | 1:566163f17cde | 204 | |
rob.meades@u-blox.com | 1:566163f17cde | 205 | // Normal case |
rob.meades@u-blox.com | 1:566163f17cde | 206 | TEST_ASSERT(pBatteryGauge->init(gpI2C)); |
rob.meades@u-blox.com | 5:63b325f2c21a | 207 | #ifdef TARGET_UBLOX_C030 |
rob.meades@u-blox.com | 5:63b325f2c21a | 208 | // Battery detection is not supported on C030 |
rob.meades@u-blox.com | 5:63b325f2c21a | 209 | // and battery detect is required for the "gauging" type APIs |
rob.meades@u-blox.com | 5:63b325f2c21a | 210 | TEST_ASSERT(pBatteryGauge->disableBatteryDetect()); |
rob.meades@u-blox.com | 5:63b325f2c21a | 211 | #endif |
rob.meades@u-blox.com | 1:566163f17cde | 212 | TEST_ASSERT(pBatteryGauge->getRemainingPercentage(&batteryPercent)); |
rob.meades@u-blox.com | 5:63b325f2c21a | 213 | printf ("Remaining percentage %d%%.\n", (int) batteryPercent); |
rob.meades@u-blox.com | 1:566163f17cde | 214 | // Range check |
rob.meades@u-blox.com | 1:566163f17cde | 215 | TEST_ASSERT((batteryPercent >= 0) && (batteryPercent <= 100)); |
rob.meades@u-blox.com | 1:566163f17cde | 216 | |
rob.meades@u-blox.com | 1:566163f17cde | 217 | // The parameter is allowed to be NULL |
rob.meades@u-blox.com | 1:566163f17cde | 218 | TEST_ASSERT(pBatteryGauge->getRemainingPercentage(NULL)); |
rob.meades@u-blox.com | 1:566163f17cde | 219 | } |
rob.meades@u-blox.com | 1:566163f17cde | 220 | |
rob.meades@u-blox.com | 1:566163f17cde | 221 | // Test advanced functions to read the configuration of the chip |
rob.meades@u-blox.com | 1:566163f17cde | 222 | void test_advanced_config_1() { |
rob.meades@u-blox.com | 1:566163f17cde | 223 | BatteryGaugeBq27441 * pBatteryGauge = new BatteryGaugeBq27441(); |
rob.meades@u-blox.com | 1:566163f17cde | 224 | uint8_t subClassId = 80; // IT Cfg |
rob.meades@u-blox.com | 1:566163f17cde | 225 | int32_t offset = 0; |
rob.meades@u-blox.com | 1:566163f17cde | 226 | int32_t length = MAX_CONFIG_BLOCK_SIZE - offset; |
rob.meades@u-blox.com | 1:566163f17cde | 227 | char data1[MAX_CONFIG_BLOCK_SIZE]; |
rob.meades@u-blox.com | 1:566163f17cde | 228 | uint32_t deadArea1 = 0xdeadbeef; |
rob.meades@u-blox.com | 1:566163f17cde | 229 | char data2[MAX_CONFIG_BLOCK_SIZE]; |
rob.meades@u-blox.com | 1:566163f17cde | 230 | uint32_t deadArea2 = 0xdeadbeef; |
rob.meades@u-blox.com | 1:566163f17cde | 231 | |
rob.meades@u-blox.com | 1:566163f17cde | 232 | // Initialise the battery gauge |
rob.meades@u-blox.com | 1:566163f17cde | 233 | TEST_ASSERT(pBatteryGauge->init(gpI2C)); |
rob.meades@u-blox.com | 1:566163f17cde | 234 | |
rob.meades@u-blox.com | 1:566163f17cde | 235 | // Read IT Cfg (total length 79 bytes), starting from 0, into data1 |
rob.meades@u-blox.com | 1:566163f17cde | 236 | subClassId = 80; |
rob.meades@u-blox.com | 1:566163f17cde | 237 | memset(&(data1[0]), 0, sizeof (data1)); |
rob.meades@u-blox.com | 1:566163f17cde | 238 | TEST_ASSERT(pBatteryGauge->advancedGetConfig(subClassId, offset, length, &(data1[0]))); |
rob.meades@u-blox.com | 5:63b325f2c21a | 239 | printf("%d bytes received from subClassID %d, offset %d:\n", (int) length, subClassId, (int) offset); |
rob.meades@u-blox.com | 1:566163f17cde | 240 | printBytesAsHex(&(data1[0]), length); |
rob.meades@u-blox.com | 1:566163f17cde | 241 | TEST_ASSERT_EQUAL_UINT32 (0xdeadbeef, deadArea1); |
rob.meades@u-blox.com | 1:566163f17cde | 242 | |
rob.meades@u-blox.com | 1:566163f17cde | 243 | // Read it again, with an offset of 16 bytes, into data2 |
rob.meades@u-blox.com | 1:566163f17cde | 244 | offset = 16; |
rob.meades@u-blox.com | 1:566163f17cde | 245 | length = MAX_CONFIG_BLOCK_SIZE - 16; |
rob.meades@u-blox.com | 1:566163f17cde | 246 | memset(&(data2[0]), 0, sizeof (data2)); |
rob.meades@u-blox.com | 1:566163f17cde | 247 | TEST_ASSERT(pBatteryGauge->advancedGetConfig(subClassId, offset, length, &(data2[0]))); |
rob.meades@u-blox.com | 5:63b325f2c21a | 248 | printf("%d bytes received from subClassID %d, offset %d:\n", (int) length, subClassId, (int) offset); |
rob.meades@u-blox.com | 1:566163f17cde | 249 | printBytesAsHex(&(data2[0]), length); |
rob.meades@u-blox.com | 1:566163f17cde | 250 | // The second 16 bytes of data1 and the first 16 bytes of data2 should match |
rob.meades@u-blox.com | 1:566163f17cde | 251 | TEST_ASSERT_EQUAL_UINT8_ARRAY(&(data1[16]), &(data2[0]), 16); |
rob.meades@u-blox.com | 1:566163f17cde | 252 | TEST_ASSERT_EQUAL_UINT32 (0xdeadbeef, deadArea2); |
rob.meades@u-blox.com | 1:566163f17cde | 253 | |
rob.meades@u-blox.com | 1:566163f17cde | 254 | // Read the next block of IT Cfg into data1 |
rob.meades@u-blox.com | 1:566163f17cde | 255 | offset = MAX_CONFIG_BLOCK_SIZE; |
rob.meades@u-blox.com | 1:566163f17cde | 256 | length = MAX_CONFIG_BLOCK_SIZE; |
rob.meades@u-blox.com | 1:566163f17cde | 257 | memset(&(data1[0]), 0, sizeof (data1)); |
rob.meades@u-blox.com | 1:566163f17cde | 258 | TEST_ASSERT(pBatteryGauge->advancedGetConfig(subClassId, offset, length, &(data1[0]))); |
rob.meades@u-blox.com | 5:63b325f2c21a | 259 | printf("%d bytes received from subClassID %d, offset %d:\n", (int) length, subClassId, (int) offset); |
rob.meades@u-blox.com | 1:566163f17cde | 260 | printBytesAsHex(&(data1[0]), length); |
rob.meades@u-blox.com | 1:566163f17cde | 261 | TEST_ASSERT_EQUAL_UINT32 (0xdeadbeef, deadArea1); |
rob.meades@u-blox.com | 1:566163f17cde | 262 | |
rob.meades@u-blox.com | 1:566163f17cde | 263 | // Read the only the first 16 bytes, from the same offset into IT Cfg, into data2 |
rob.meades@u-blox.com | 1:566163f17cde | 264 | length = 16; |
rob.meades@u-blox.com | 1:566163f17cde | 265 | memset(&(data2[0]), 0, sizeof (data2)); |
rob.meades@u-blox.com | 1:566163f17cde | 266 | TEST_ASSERT(pBatteryGauge->advancedGetConfig(subClassId, offset, length, &(data2[0]))); |
rob.meades@u-blox.com | 5:63b325f2c21a | 267 | printf("%d bytes received from subClassID %d, offset %d:\n", (int) length, subClassId, (int) offset); |
rob.meades@u-blox.com | 1:566163f17cde | 268 | printBytesAsHex(&(data2[0]), length); |
rob.meades@u-blox.com | 1:566163f17cde | 269 | // The first 16 bytes of data1 and data2 should match |
rob.meades@u-blox.com | 1:566163f17cde | 270 | TEST_ASSERT_EQUAL_UINT8_ARRAY(&(data1[0]), &(data2[0]), length); |
rob.meades@u-blox.com | 1:566163f17cde | 271 | // The remainder of data2 should be zero |
rob.meades@u-blox.com | 1:566163f17cde | 272 | TEST_ASSERT_EQUAL_UINT8_ARRAY(&(zeroArray[0]), &(data2[length]), sizeof(data2) - length); |
rob.meades@u-blox.com | 1:566163f17cde | 273 | TEST_ASSERT_EQUAL_UINT32 (0xdeadbeef, deadArea2); |
rob.meades@u-blox.com | 1:566163f17cde | 274 | } |
rob.meades@u-blox.com | 1:566163f17cde | 275 | |
rob.meades@u-blox.com | 1:566163f17cde | 276 | // Test advanced functions to write configuration to the chip |
rob.meades@u-blox.com | 1:566163f17cde | 277 | void test_advanced_config_2() { |
rob.meades@u-blox.com | 1:566163f17cde | 278 | BatteryGaugeBq27441 * pBatteryGauge = new BatteryGaugeBq27441(); |
rob.meades@u-blox.com | 1:566163f17cde | 279 | uint8_t subClassId = 80; // IT Cfg |
rob.meades@u-blox.com | 1:566163f17cde | 280 | int32_t offset = 0; |
rob.meades@u-blox.com | 1:566163f17cde | 281 | int32_t length = MAX_CONFIG_BLOCK_SIZE - offset; |
rob.meades@u-blox.com | 1:566163f17cde | 282 | char data1[MAX_CONFIG_BLOCK_SIZE]; |
rob.meades@u-blox.com | 1:566163f17cde | 283 | uint32_t deadArea1 = 0xdeadbeef; |
rob.meades@u-blox.com | 1:566163f17cde | 284 | char data2[MAX_CONFIG_BLOCK_SIZE]; |
rob.meades@u-blox.com | 1:566163f17cde | 285 | |
rob.meades@u-blox.com | 1:566163f17cde | 286 | // Initialise the battery gauge |
rob.meades@u-blox.com | 1:566163f17cde | 287 | TEST_ASSERT(pBatteryGauge->init(gpI2C)); |
rob.meades@u-blox.com | 1:566163f17cde | 288 | |
rob.meades@u-blox.com | 1:566163f17cde | 289 | // Read Delta Voltage, two bytes at offset 39 in sub-class State, into data1 |
rob.meades@u-blox.com | 1:566163f17cde | 290 | subClassId = 82; |
rob.meades@u-blox.com | 1:566163f17cde | 291 | offset = 39; |
rob.meades@u-blox.com | 1:566163f17cde | 292 | length = 2; |
rob.meades@u-blox.com | 1:566163f17cde | 293 | memset(&(data1[0]), 0, sizeof (data1)); |
rob.meades@u-blox.com | 1:566163f17cde | 294 | TEST_ASSERT(pBatteryGauge->advancedGetConfig(subClassId, offset, length, &(data1[0]))); |
rob.meades@u-blox.com | 5:63b325f2c21a | 295 | printf("%d bytes received from subClassID %d, offset %d:\n", (int) length, subClassId, (int) offset); |
rob.meades@u-blox.com | 1:566163f17cde | 296 | printBytesAsHex(&(data1[0]), length); |
rob.meades@u-blox.com | 1:566163f17cde | 297 | TEST_ASSERT_EQUAL_UINT32 (0xdeadbeef, deadArea1); |
rob.meades@u-blox.com | 1:566163f17cde | 298 | |
rob.meades@u-blox.com | 1:566163f17cde | 299 | // Copy Delta Voltage, change the lower byte and then write it back |
rob.meades@u-blox.com | 1:566163f17cde | 300 | (data1[1])++; |
rob.meades@u-blox.com | 1:566163f17cde | 301 | printf ("Modified data block:\n"); |
rob.meades@u-blox.com | 1:566163f17cde | 302 | printBytesAsHex(&(data1[0]), length); |
rob.meades@u-blox.com | 1:566163f17cde | 303 | TEST_ASSERT(pBatteryGauge->advancedSetConfig(subClassId, offset, length, &(data1[0]))); |
rob.meades@u-blox.com | 5:63b325f2c21a | 304 | printf("%d bytes written to subClassID %d, offset %d:\n", (int) length, subClassId, (int) offset); |
rob.meades@u-blox.com | 1:566163f17cde | 305 | |
rob.meades@u-blox.com | 1:566163f17cde | 306 | // Read it back and check that the Delta Voltage really is the new value |
rob.meades@u-blox.com | 1:566163f17cde | 307 | subClassId = 82; |
rob.meades@u-blox.com | 1:566163f17cde | 308 | offset = 32; |
rob.meades@u-blox.com | 1:566163f17cde | 309 | length = 9; |
rob.meades@u-blox.com | 1:566163f17cde | 310 | memset(&(data2[0]), 0, sizeof (data2)); |
rob.meades@u-blox.com | 1:566163f17cde | 311 | TEST_ASSERT(pBatteryGauge->advancedGetConfig(subClassId, offset, length, &(data2[0]))); |
rob.meades@u-blox.com | 5:63b325f2c21a | 312 | printf("%d bytes received from subClassID %d, offset %d:\n", (int) length, subClassId, (int) offset); |
rob.meades@u-blox.com | 1:566163f17cde | 313 | printBytesAsHex(&(data2[0]), length); |
rob.meades@u-blox.com | 1:566163f17cde | 314 | TEST_ASSERT_EQUAL_UINT32 (0xdeadbeef, deadArea1); |
rob.meades@u-blox.com | 1:566163f17cde | 315 | TEST_ASSERT_EQUAL_UINT32 (data1[0], data2[7]); |
rob.meades@u-blox.com | 1:566163f17cde | 316 | TEST_ASSERT_EQUAL_UINT32 (data1[1], data2[8]); |
rob.meades@u-blox.com | 1:566163f17cde | 317 | |
rob.meades@u-blox.com | 1:566163f17cde | 318 | // Now put Delta Voltage back as it was |
rob.meades@u-blox.com | 1:566163f17cde | 319 | (data2[8])--; |
rob.meades@u-blox.com | 1:566163f17cde | 320 | TEST_ASSERT(pBatteryGauge->advancedSetConfig(subClassId, offset, length, &(data2[0]))); |
rob.meades@u-blox.com | 5:63b325f2c21a | 321 | printf("%d bytes written to subClassID %d, offset %d:\n", (int) length, subClassId, (int) offset); |
rob.meades@u-blox.com | 1:566163f17cde | 322 | } |
rob.meades@u-blox.com | 1:566163f17cde | 323 | |
rob.meades@u-blox.com | 1:566163f17cde | 324 | // Test fail cases of the advanced configuration functions |
rob.meades@u-blox.com | 1:566163f17cde | 325 | void test_advanced_config_3() { |
rob.meades@u-blox.com | 1:566163f17cde | 326 | BatteryGaugeBq27441 * pBatteryGauge = new BatteryGaugeBq27441(); |
rob.meades@u-blox.com | 1:566163f17cde | 327 | uint8_t subClassId = 80; // IT Cfg |
rob.meades@u-blox.com | 1:566163f17cde | 328 | int32_t offset = 0; |
rob.meades@u-blox.com | 1:566163f17cde | 329 | int32_t length = MAX_CONFIG_BLOCK_SIZE - offset; |
rob.meades@u-blox.com | 1:566163f17cde | 330 | char data1[MAX_CONFIG_BLOCK_SIZE]; |
rob.meades@u-blox.com | 1:566163f17cde | 331 | |
rob.meades@u-blox.com | 1:566163f17cde | 332 | // All calls should fail if the battery gauge has not been initialised |
rob.meades@u-blox.com | 1:566163f17cde | 333 | TEST_ASSERT_FALSE(pBatteryGauge->advancedSetConfig(subClassId, offset, length, &(data1[0]))); |
rob.meades@u-blox.com | 1:566163f17cde | 334 | TEST_ASSERT_FALSE(pBatteryGauge->advancedGetConfig(subClassId, offset, length, &(data1[0]))); |
rob.meades@u-blox.com | 1:566163f17cde | 335 | |
rob.meades@u-blox.com | 1:566163f17cde | 336 | // Initialise the battery gauge |
rob.meades@u-blox.com | 1:566163f17cde | 337 | TEST_ASSERT(pBatteryGauge->init(gpI2C)); |
rob.meades@u-blox.com | 1:566163f17cde | 338 | |
rob.meades@u-blox.com | 1:566163f17cde | 339 | // Perform some reads of bad length/offset combinations |
rob.meades@u-blox.com | 1:566163f17cde | 340 | offset = 0; |
rob.meades@u-blox.com | 1:566163f17cde | 341 | length = 33; |
rob.meades@u-blox.com | 1:566163f17cde | 342 | TEST_ASSERT_FALSE(pBatteryGauge->advancedGetConfig(subClassId, offset, length, &(data1[0]))); |
rob.meades@u-blox.com | 1:566163f17cde | 343 | TEST_ASSERT_FALSE(pBatteryGauge->advancedSetConfig(subClassId, offset, length, &(data1[0]))); |
rob.meades@u-blox.com | 1:566163f17cde | 344 | offset = 1; |
rob.meades@u-blox.com | 1:566163f17cde | 345 | length = 32; |
rob.meades@u-blox.com | 1:566163f17cde | 346 | TEST_ASSERT_FALSE(pBatteryGauge->advancedGetConfig(subClassId, offset, length, &(data1[0]))); |
rob.meades@u-blox.com | 1:566163f17cde | 347 | TEST_ASSERT_FALSE(pBatteryGauge->advancedSetConfig(subClassId, offset, length, &(data1[0]))); |
rob.meades@u-blox.com | 1:566163f17cde | 348 | offset = 31; |
rob.meades@u-blox.com | 1:566163f17cde | 349 | length = 2; |
rob.meades@u-blox.com | 1:566163f17cde | 350 | TEST_ASSERT_FALSE(pBatteryGauge->advancedGetConfig(subClassId, offset, length, &(data1[0]))); |
rob.meades@u-blox.com | 1:566163f17cde | 351 | TEST_ASSERT_FALSE(pBatteryGauge->advancedSetConfig(subClassId, offset, length, &(data1[0]))); |
rob.meades@u-blox.com | 1:566163f17cde | 352 | offset = 32; |
rob.meades@u-blox.com | 1:566163f17cde | 353 | length = 33; |
rob.meades@u-blox.com | 1:566163f17cde | 354 | TEST_ASSERT_FALSE(pBatteryGauge->advancedGetConfig(subClassId, offset, length, &(data1[0]))); |
rob.meades@u-blox.com | 1:566163f17cde | 355 | TEST_ASSERT_FALSE(pBatteryGauge->advancedSetConfig(subClassId, offset, length, &(data1[0]))); |
rob.meades@u-blox.com | 1:566163f17cde | 356 | } |
rob.meades@u-blox.com | 1:566163f17cde | 357 | |
rob.meades@u-blox.com | 1:566163f17cde | 358 | // Send a control word to the BQ27441 battery gauge chip |
rob.meades@u-blox.com | 1:566163f17cde | 359 | void test_advanced_control() { |
rob.meades@u-blox.com | 1:566163f17cde | 360 | BatteryGaugeBq27441 * pBatteryGauge = new BatteryGaugeBq27441(); |
rob.meades@u-blox.com | 1:566163f17cde | 361 | uint16_t controlWord = 0x0002; // get FW version |
rob.meades@u-blox.com | 1:566163f17cde | 362 | uint16_t response = 0; |
rob.meades@u-blox.com | 1:566163f17cde | 363 | |
rob.meades@u-blox.com | 1:566163f17cde | 364 | // Call should fail if the battery gauge has not been initialised |
rob.meades@u-blox.com | 1:566163f17cde | 365 | TEST_ASSERT_FALSE(pBatteryGauge->advancedSendControlWord(controlWord, &response)); |
rob.meades@u-blox.com | 1:566163f17cde | 366 | |
rob.meades@u-blox.com | 1:566163f17cde | 367 | // Initialise the battery gauge |
rob.meades@u-blox.com | 1:566163f17cde | 368 | TEST_ASSERT(pBatteryGauge->init(gpI2C)); |
rob.meades@u-blox.com | 1:566163f17cde | 369 | |
rob.meades@u-blox.com | 1:566163f17cde | 370 | // Normal case |
rob.meades@u-blox.com | 1:566163f17cde | 371 | TEST_ASSERT(pBatteryGauge->advancedSendControlWord(controlWord, &response)); |
rob.meades@u-blox.com | 1:566163f17cde | 372 | // FW version must be 0x0109 |
rob.meades@u-blox.com | 1:566163f17cde | 373 | TEST_ASSERT_EQUAL_UINT16(0x0109, response); |
rob.meades@u-blox.com | 1:566163f17cde | 374 | |
rob.meades@u-blox.com | 1:566163f17cde | 375 | // The parameter is allowed to be null |
rob.meades@u-blox.com | 1:566163f17cde | 376 | TEST_ASSERT(pBatteryGauge->advancedSendControlWord(controlWord, NULL)); |
rob.meades@u-blox.com | 1:566163f17cde | 377 | } |
rob.meades@u-blox.com | 1:566163f17cde | 378 | |
rob.meades@u-blox.com | 1:566163f17cde | 379 | // Read using a standard command from the BQ27441 battery gauge chip |
rob.meades@u-blox.com | 1:566163f17cde | 380 | void test_advanced_get() { |
rob.meades@u-blox.com | 1:566163f17cde | 381 | BatteryGaugeBq27441 * pBatteryGauge = new BatteryGaugeBq27441(); |
rob.meades@u-blox.com | 1:566163f17cde | 382 | uint8_t address = 0x02; // Temperature |
rob.meades@u-blox.com | 1:566163f17cde | 383 | uint16_t value = 0; |
rob.meades@u-blox.com | 1:566163f17cde | 384 | int32_t temperatureC = -1; |
rob.meades@u-blox.com | 1:566163f17cde | 385 | |
rob.meades@u-blox.com | 1:566163f17cde | 386 | // Call should fail if the battery gauge has not been initialised |
rob.meades@u-blox.com | 1:566163f17cde | 387 | TEST_ASSERT_FALSE(pBatteryGauge->advancedGet(address, &value)); |
rob.meades@u-blox.com | 1:566163f17cde | 388 | |
rob.meades@u-blox.com | 1:566163f17cde | 389 | // Initialise the battery gauge |
rob.meades@u-blox.com | 1:566163f17cde | 390 | TEST_ASSERT(pBatteryGauge->init(gpI2C)); |
rob.meades@u-blox.com | 1:566163f17cde | 391 | |
rob.meades@u-blox.com | 1:566163f17cde | 392 | // Normal case |
rob.meades@u-blox.com | 1:566163f17cde | 393 | TEST_ASSERT(pBatteryGauge->advancedGet(address, &value)); |
rob.meades@u-blox.com | 1:566163f17cde | 394 | // Get the temperature via the standard API command |
rob.meades@u-blox.com | 1:566163f17cde | 395 | TEST_ASSERT(pBatteryGauge->getTemperature(&temperatureC)); |
rob.meades@u-blox.com | 1:566163f17cde | 396 | // Convert the value returned into a temperature reading and compare |
rob.meades@u-blox.com | 1:566163f17cde | 397 | // it with the real answer, allowing a 1 degree tolerance in case |
rob.meades@u-blox.com | 1:566163f17cde | 398 | // it has changed between readings. |
rob.meades@u-blox.com | 1:566163f17cde | 399 | TEST_ASSERT_INT32_WITHIN (1, temperatureC, ((int32_t) value / 10) - 273); |
rob.meades@u-blox.com | 1:566163f17cde | 400 | |
rob.meades@u-blox.com | 1:566163f17cde | 401 | // The parameter is allowed to be null |
rob.meades@u-blox.com | 1:566163f17cde | 402 | TEST_ASSERT(pBatteryGauge->advancedGet(address, NULL)); |
rob.meades@u-blox.com | 1:566163f17cde | 403 | } |
rob.meades@u-blox.com | 1:566163f17cde | 404 | |
rob.meades@u-blox.com | 1:566163f17cde | 405 | // Test that the chip can be sealed and unsealed |
rob.meades@u-blox.com | 1:566163f17cde | 406 | void test_advanced_seal() { |
rob.meades@u-blox.com | 1:566163f17cde | 407 | BatteryGaugeBq27441 * pBatteryGauge = new BatteryGaugeBq27441(); |
rob.meades@u-blox.com | 1:566163f17cde | 408 | uint8_t subClassId = 80; // IT Cfg |
rob.meades@u-blox.com | 1:566163f17cde | 409 | int32_t offset = 78; // Position of the "TermV valid t" item at offset 78 |
rob.meades@u-blox.com | 1:566163f17cde | 410 | int32_t length = 1; // Length of "TermV valid t" |
rob.meades@u-blox.com | 1:566163f17cde | 411 | char data1[MAX_CONFIG_BLOCK_SIZE]; |
rob.meades@u-blox.com | 1:566163f17cde | 412 | char data2[MAX_CONFIG_BLOCK_SIZE]; |
rob.meades@u-blox.com | 1:566163f17cde | 413 | char data3[MAX_CONFIG_BLOCK_SIZE]; |
rob.meades@u-blox.com | 1:566163f17cde | 414 | int32_t value; |
rob.meades@u-blox.com | 1:566163f17cde | 415 | |
rob.meades@u-blox.com | 1:566163f17cde | 416 | memset(&(data1[0]), 0, sizeof (data1)); |
rob.meades@u-blox.com | 1:566163f17cde | 417 | memset(&(data2[0]), 0, sizeof (data2)); |
rob.meades@u-blox.com | 1:566163f17cde | 418 | memset(&(data3[0]), 0, sizeof (data3)); |
rob.meades@u-blox.com | 1:566163f17cde | 419 | |
rob.meades@u-blox.com | 1:566163f17cde | 420 | // Make sure that the device is not sealed from a previous field test run |
rob.meades@u-blox.com | 1:566163f17cde | 421 | TEST_ASSERT(pBatteryGauge->init(gpI2C)); |
rob.meades@u-blox.com | 5:63b325f2c21a | 422 | #ifdef TARGET_UBLOX_C030 |
rob.meades@u-blox.com | 5:63b325f2c21a | 423 | // Battery detection is not supported on C030 |
rob.meades@u-blox.com | 5:63b325f2c21a | 424 | TEST_ASSERT(pBatteryGauge->disableBatteryDetect()); |
rob.meades@u-blox.com | 5:63b325f2c21a | 425 | #endif |
rob.meades@u-blox.com | 1:566163f17cde | 426 | TEST_ASSERT(pBatteryGauge->advancedUnseal()); |
rob.meades@u-blox.com | 1:566163f17cde | 427 | |
rob.meades@u-blox.com | 1:566163f17cde | 428 | delete pBatteryGauge; |
rob.meades@u-blox.com | 1:566163f17cde | 429 | pBatteryGauge = new BatteryGaugeBq27441(); |
rob.meades@u-blox.com | 1:566163f17cde | 430 | // Calls should fail if the battery gauge has not been initialised |
rob.meades@u-blox.com | 1:566163f17cde | 431 | printf ("Calling advancedIsSealed()...\n"); |
rob.meades@u-blox.com | 1:566163f17cde | 432 | TEST_ASSERT_FALSE(pBatteryGauge->advancedIsSealed()); |
rob.meades@u-blox.com | 1:566163f17cde | 433 | printf ("Calling advancedSeal()...\n"); |
rob.meades@u-blox.com | 1:566163f17cde | 434 | TEST_ASSERT_FALSE(pBatteryGauge->advancedSeal()); |
rob.meades@u-blox.com | 1:566163f17cde | 435 | printf ("Calling advancedUnseal()...\n"); |
rob.meades@u-blox.com | 1:566163f17cde | 436 | TEST_ASSERT_FALSE(pBatteryGauge->advancedUnseal()); |
rob.meades@u-blox.com | 1:566163f17cde | 437 | |
rob.meades@u-blox.com | 1:566163f17cde | 438 | // Normal case |
rob.meades@u-blox.com | 1:566163f17cde | 439 | printf ("Calling init()...\n"); |
rob.meades@u-blox.com | 1:566163f17cde | 440 | TEST_ASSERT(pBatteryGauge->init(gpI2C)); |
rob.meades@u-blox.com | 1:566163f17cde | 441 | printf ("Calling advancedIsSealed()...\n"); |
rob.meades@u-blox.com | 1:566163f17cde | 442 | TEST_ASSERT_FALSE(pBatteryGauge->advancedIsSealed()); |
rob.meades@u-blox.com | 1:566163f17cde | 443 | // This call should pass |
rob.meades@u-blox.com | 1:566163f17cde | 444 | printf ("Calling advancedGetConfig()...\n"); |
rob.meades@u-blox.com | 1:566163f17cde | 445 | TEST_ASSERT(pBatteryGauge->advancedGetConfig(subClassId , offset, length, &(data1[0]))); |
rob.meades@u-blox.com | 1:566163f17cde | 446 | |
rob.meades@u-blox.com | 1:566163f17cde | 447 | // Now seal it |
rob.meades@u-blox.com | 1:566163f17cde | 448 | printf ("Calling advancedSeal()...\n"); |
rob.meades@u-blox.com | 1:566163f17cde | 449 | TEST_ASSERT(pBatteryGauge->advancedSeal()); |
rob.meades@u-blox.com | 1:566163f17cde | 450 | printf ("Calling advancedIsSealed()...\n"); |
rob.meades@u-blox.com | 1:566163f17cde | 451 | TEST_ASSERT(pBatteryGauge->advancedIsSealed()); |
rob.meades@u-blox.com | 1:566163f17cde | 452 | memcpy (&(data2[0]), &(data1[0]), sizeof (data2)); |
rob.meades@u-blox.com | 1:566163f17cde | 453 | // Try to increment the "TermV valid t" item |
rob.meades@u-blox.com | 1:566163f17cde | 454 | (data2[0])++; |
rob.meades@u-blox.com | 1:566163f17cde | 455 | // These calls should all be unaffected by sealing |
rob.meades@u-blox.com | 1:566163f17cde | 456 | printf ("Calling advancedSetConfig()...\n"); |
rob.meades@u-blox.com | 1:566163f17cde | 457 | TEST_ASSERT(pBatteryGauge->advancedSetConfig(subClassId, offset, length, &(data2[0]))); |
rob.meades@u-blox.com | 1:566163f17cde | 458 | printf ("Calling advancedGetConfig()...\n"); |
rob.meades@u-blox.com | 1:566163f17cde | 459 | TEST_ASSERT(pBatteryGauge->advancedGetConfig(subClassId, offset, length, &(data3[0]))); |
rob.meades@u-blox.com | 1:566163f17cde | 460 | TEST_ASSERT(memcmp (&(data2[0]), &(data3[0]), sizeof (data2)) == 0); |
rob.meades@u-blox.com | 1:566163f17cde | 461 | // Put "TermV valid t" back as it was |
rob.meades@u-blox.com | 1:566163f17cde | 462 | (data2[0])--; |
rob.meades@u-blox.com | 1:566163f17cde | 463 | printf ("Calling advancedSetConfig()...\n"); |
rob.meades@u-blox.com | 1:566163f17cde | 464 | TEST_ASSERT(pBatteryGauge->advancedSetConfig(subClassId, offset, length, &(data2[0]))); |
rob.meades@u-blox.com | 1:566163f17cde | 465 | printf ("Calling enableGauge()...\n"); |
rob.meades@u-blox.com | 1:566163f17cde | 466 | TEST_ASSERT(pBatteryGauge->enableGauge()); |
rob.meades@u-blox.com | 1:566163f17cde | 467 | printf ("Calling isBatteryDetected()...\n"); |
rob.meades@u-blox.com | 1:566163f17cde | 468 | TEST_ASSERT(pBatteryGauge->isBatteryDetected()); |
rob.meades@u-blox.com | 1:566163f17cde | 469 | printf ("Calling getTemperature()...\n"); |
rob.meades@u-blox.com | 1:566163f17cde | 470 | TEST_ASSERT(pBatteryGauge->getTemperature(&value)); |
rob.meades@u-blox.com | 1:566163f17cde | 471 | printf ("Calling getVoltage()...\n"); |
rob.meades@u-blox.com | 1:566163f17cde | 472 | TEST_ASSERT(pBatteryGauge->getVoltage(&value)); |
rob.meades@u-blox.com | 1:566163f17cde | 473 | printf ("Calling getCurrent()...\n"); |
rob.meades@u-blox.com | 1:566163f17cde | 474 | TEST_ASSERT(pBatteryGauge->getCurrent(&value)); |
rob.meades@u-blox.com | 1:566163f17cde | 475 | printf ("Calling getRemainingCapacity()...\n"); |
rob.meades@u-blox.com | 1:566163f17cde | 476 | TEST_ASSERT(pBatteryGauge->getRemainingCapacity(&value)); |
rob.meades@u-blox.com | 1:566163f17cde | 477 | printf ("Calling getRemainingPercentage()...\n"); |
rob.meades@u-blox.com | 1:566163f17cde | 478 | TEST_ASSERT(pBatteryGauge->getRemainingPercentage(&value)); |
rob.meades@u-blox.com | 1:566163f17cde | 479 | printf ("Calling enableGauge(\"true\")...\n"); |
rob.meades@u-blox.com | 1:566163f17cde | 480 | TEST_ASSERT(pBatteryGauge->enableGauge(true)); |
rob.meades@u-blox.com | 1:566163f17cde | 481 | printf ("Calling disableGauge()...\n"); |
rob.meades@u-blox.com | 1:566163f17cde | 482 | TEST_ASSERT(pBatteryGauge->disableGauge()); |
rob.meades@u-blox.com | 1:566163f17cde | 483 | |
rob.meades@u-blox.com | 1:566163f17cde | 484 | // Now unseal it |
rob.meades@u-blox.com | 1:566163f17cde | 485 | printf ("Calling advancedUnseal()...\n"); |
rob.meades@u-blox.com | 1:566163f17cde | 486 | TEST_ASSERT(pBatteryGauge->advancedUnseal()); |
rob.meades@u-blox.com | 1:566163f17cde | 487 | printf ("Calling advancedIsSealed()...\n"); |
rob.meades@u-blox.com | 1:566163f17cde | 488 | TEST_ASSERT_FALSE(pBatteryGauge->advancedIsSealed()); |
rob.meades@u-blox.com | 1:566163f17cde | 489 | // These calls should all still work |
rob.meades@u-blox.com | 1:566163f17cde | 490 | // Try to increment the "TermV valid t" item |
rob.meades@u-blox.com | 1:566163f17cde | 491 | (data2[0])++; |
rob.meades@u-blox.com | 1:566163f17cde | 492 | printf ("Calling advancedSetConfig()...\n"); |
rob.meades@u-blox.com | 1:566163f17cde | 493 | TEST_ASSERT(pBatteryGauge->advancedSetConfig(subClassId, offset, length, &(data2[0]))); |
rob.meades@u-blox.com | 1:566163f17cde | 494 | printf ("Calling advancedGetConfig()...\n"); |
rob.meades@u-blox.com | 1:566163f17cde | 495 | TEST_ASSERT(pBatteryGauge->advancedGetConfig(subClassId, offset, length, &(data3[0]))); |
rob.meades@u-blox.com | 1:566163f17cde | 496 | TEST_ASSERT(memcmp (&(data2[0]), &(data3[0]), sizeof (data2)) == 0); |
rob.meades@u-blox.com | 1:566163f17cde | 497 | // Put "TermV valid t" back as it was |
rob.meades@u-blox.com | 1:566163f17cde | 498 | (data2[0])--; |
rob.meades@u-blox.com | 1:566163f17cde | 499 | printf ("Calling advancedSetConfig()...\n"); |
rob.meades@u-blox.com | 1:566163f17cde | 500 | TEST_ASSERT(pBatteryGauge->advancedSetConfig(subClassId, offset, length, &(data2[0]))); |
rob.meades@u-blox.com | 1:566163f17cde | 501 | printf ("Calling enableGauge(\"true\")...\n"); |
rob.meades@u-blox.com | 1:566163f17cde | 502 | TEST_ASSERT(pBatteryGauge->enableGauge(true)); |
rob.meades@u-blox.com | 1:566163f17cde | 503 | printf ("Calling isBatteryDetected()...\n"); |
rob.meades@u-blox.com | 1:566163f17cde | 504 | TEST_ASSERT(pBatteryGauge->isBatteryDetected()); |
rob.meades@u-blox.com | 1:566163f17cde | 505 | printf ("Calling getTemperature()...\n"); |
rob.meades@u-blox.com | 1:566163f17cde | 506 | TEST_ASSERT(pBatteryGauge->getTemperature(&value)); |
rob.meades@u-blox.com | 1:566163f17cde | 507 | printf ("Calling getVoltage()...\n"); |
rob.meades@u-blox.com | 1:566163f17cde | 508 | TEST_ASSERT(pBatteryGauge->getVoltage(&value)); |
rob.meades@u-blox.com | 1:566163f17cde | 509 | printf ("Calling getCurrent()...\n"); |
rob.meades@u-blox.com | 1:566163f17cde | 510 | TEST_ASSERT(pBatteryGauge->getCurrent(&value)); |
rob.meades@u-blox.com | 1:566163f17cde | 511 | printf ("Calling getRemainingCapacity()...\n"); |
rob.meades@u-blox.com | 1:566163f17cde | 512 | TEST_ASSERT(pBatteryGauge->getRemainingCapacity(&value)); |
rob.meades@u-blox.com | 1:566163f17cde | 513 | printf ("Calling getRemainingPercentage()...\n"); |
rob.meades@u-blox.com | 1:566163f17cde | 514 | TEST_ASSERT(pBatteryGauge->getRemainingPercentage(&value)); |
rob.meades@u-blox.com | 1:566163f17cde | 515 | printf ("Calling disableGauge()...\n"); |
rob.meades@u-blox.com | 1:566163f17cde | 516 | TEST_ASSERT(pBatteryGauge->disableGauge()); |
rob.meades@u-blox.com | 1:566163f17cde | 517 | |
rob.meades@u-blox.com | 1:566163f17cde | 518 | // TODO: I had some tests in here to check that init() and |
rob.meades@u-blox.com | 1:566163f17cde | 519 | // advancedUnseal() behave when given the wrong seal code. |
rob.meades@u-blox.com | 1:566163f17cde | 520 | // However, as soon as the chip gets a wrong seal code it |
rob.meades@u-blox.com | 1:566163f17cde | 521 | // refuses to unseal again (I tried a 4 second delay but |
rob.meades@u-blox.com | 1:566163f17cde | 522 | // that didn't help). This needs investigating. |
rob.meades@u-blox.com | 1:566163f17cde | 523 | } |
rob.meades@u-blox.com | 1:566163f17cde | 524 | |
rob.meades@u-blox.com | 1:566163f17cde | 525 | // Reset the BQ27441 battery gauge chip at the outset |
rob.meades@u-blox.com | 1:566163f17cde | 526 | void test_advanced_reset() { |
rob.meades@u-blox.com | 1:566163f17cde | 527 | BatteryGaugeBq27441 * pBatteryGauge = new BatteryGaugeBq27441(); |
rob.meades@u-blox.com | 1:566163f17cde | 528 | uint8_t subClassId = 80; // IT Cfg |
rob.meades@u-blox.com | 1:566163f17cde | 529 | int32_t offset = 78; // Position of the "TermV valid t" item at offset 78 |
rob.meades@u-blox.com | 1:566163f17cde | 530 | int32_t length = 1; // Length of "TermV valid t" |
rob.meades@u-blox.com | 1:566163f17cde | 531 | char data1[MAX_CONFIG_BLOCK_SIZE]; |
rob.meades@u-blox.com | 1:566163f17cde | 532 | char data2[MAX_CONFIG_BLOCK_SIZE]; |
rob.meades@u-blox.com | 1:566163f17cde | 533 | char data3[MAX_CONFIG_BLOCK_SIZE]; |
rob.meades@u-blox.com | 1:566163f17cde | 534 | |
rob.meades@u-blox.com | 1:566163f17cde | 535 | memset(&(data1[0]), 0, sizeof (data1)); |
rob.meades@u-blox.com | 1:566163f17cde | 536 | memset(&(data2[0]), 0, sizeof (data2)); |
rob.meades@u-blox.com | 1:566163f17cde | 537 | memset(&(data3[0]), 0, sizeof (data3)); |
rob.meades@u-blox.com | 1:566163f17cde | 538 | |
rob.meades@u-blox.com | 1:566163f17cde | 539 | // Call should fail if the battery gauge has not been initialised |
rob.meades@u-blox.com | 1:566163f17cde | 540 | TEST_ASSERT_FALSE(pBatteryGauge->advancedReset()); |
rob.meades@u-blox.com | 1:566163f17cde | 541 | |
rob.meades@u-blox.com | 1:566163f17cde | 542 | TEST_ASSERT(pBatteryGauge->init(gpI2C)); |
rob.meades@u-blox.com | 1:566163f17cde | 543 | TEST_ASSERT(pBatteryGauge->advancedUnseal()); |
rob.meades@u-blox.com | 1:566163f17cde | 544 | |
rob.meades@u-blox.com | 1:566163f17cde | 545 | // Normal case |
rob.meades@u-blox.com | 1:566163f17cde | 546 | // Increment the "TermV valid t" item |
rob.meades@u-blox.com | 1:566163f17cde | 547 | TEST_ASSERT(pBatteryGauge->advancedGetConfig(subClassId, offset, length, &(data1[0]))); |
rob.meades@u-blox.com | 1:566163f17cde | 548 | memcpy (&(data2[0]), &(data1[0]), sizeof (data2)); |
rob.meades@u-blox.com | 1:566163f17cde | 549 | (data2[0])++; |
rob.meades@u-blox.com | 1:566163f17cde | 550 | TEST_ASSERT(pBatteryGauge->advancedSetConfig(subClassId, offset, length, &(data2[0]))); |
rob.meades@u-blox.com | 1:566163f17cde | 551 | // Read it back to make sure it was set |
rob.meades@u-blox.com | 1:566163f17cde | 552 | TEST_ASSERT(pBatteryGauge->advancedGetConfig(subClassId, offset, length, &(data3[0]))); |
rob.meades@u-blox.com | 1:566163f17cde | 553 | TEST_ASSERT(memcmp (&(data2[0]), &(data3[0]), sizeof (data2)) == 0); |
rob.meades@u-blox.com | 1:566163f17cde | 554 | |
rob.meades@u-blox.com | 1:566163f17cde | 555 | // Now reset the chip and check that the value is back to what it was before |
rob.meades@u-blox.com | 1:566163f17cde | 556 | TEST_ASSERT(pBatteryGauge->advancedReset()); |
rob.meades@u-blox.com | 1:566163f17cde | 557 | TEST_ASSERT(pBatteryGauge->advancedGetConfig(subClassId, offset, length, &(data3[0]))); |
rob.meades@u-blox.com | 1:566163f17cde | 558 | TEST_ASSERT(memcmp (&(data1[0]), &(data3[0]), sizeof (data1)) == 0); |
rob.meades@u-blox.com | 1:566163f17cde | 559 | } |
rob.meades@u-blox.com | 1:566163f17cde | 560 | |
rob.meades@u-blox.com | 1:566163f17cde | 561 | // ---------------------------------------------------------------- |
rob.meades@u-blox.com | 1:566163f17cde | 562 | // TEST ENVIRONMENT |
rob.meades@u-blox.com | 1:566163f17cde | 563 | // ---------------------------------------------------------------- |
rob.meades@u-blox.com | 1:566163f17cde | 564 | |
rob.meades@u-blox.com | 1:566163f17cde | 565 | // Setup the test environment |
rob.meades@u-blox.com | 1:566163f17cde | 566 | utest::v1::status_t test_setup(const size_t number_of_cases) { |
rob.meades@u-blox.com | 1:566163f17cde | 567 | // Setup Greentea, timeout is long enough to run these tests with |
rob.meades@u-blox.com | 1:566163f17cde | 568 | // DEBUG_BQ27441 defined |
rob.meades@u-blox.com | 1:566163f17cde | 569 | // Note: timeout is quite long as the chip has 4 second |
rob.meades@u-blox.com | 1:566163f17cde | 570 | // timeouts in quite a lot of cases. |
rob.meades@u-blox.com | 1:566163f17cde | 571 | GREENTEA_SETUP(480, "default_auto"); |
rob.meades@u-blox.com | 1:566163f17cde | 572 | return verbose_test_setup_handler(number_of_cases); |
rob.meades@u-blox.com | 1:566163f17cde | 573 | } |
rob.meades@u-blox.com | 1:566163f17cde | 574 | |
rob.meades@u-blox.com | 1:566163f17cde | 575 | // Test cases |
rob.meades@u-blox.com | 1:566163f17cde | 576 | Case cases[] = { |
rob.meades@u-blox.com | 1:566163f17cde | 577 | Case("Initialisation", test_init), |
rob.meades@u-blox.com | 1:566163f17cde | 578 | Case("Monitoring", test_monitor), |
rob.meades@u-blox.com | 1:566163f17cde | 579 | Case("Battery detection", test_battery_detection), |
rob.meades@u-blox.com | 1:566163f17cde | 580 | Case("Temperature read", test_temperature), |
rob.meades@u-blox.com | 1:566163f17cde | 581 | Case("Voltage read", test_voltage), |
rob.meades@u-blox.com | 1:566163f17cde | 582 | Case("Current read", test_current), |
rob.meades@u-blox.com | 1:566163f17cde | 583 | Case("Remaining capacity read", test_remaining_capacity), |
rob.meades@u-blox.com | 1:566163f17cde | 584 | Case("Remaining percentage read", test_remaining_percentage), |
rob.meades@u-blox.com | 1:566163f17cde | 585 | Case("Advanced config read", test_advanced_config_1), |
rob.meades@u-blox.com | 1:566163f17cde | 586 | Case("Advanced config write", test_advanced_config_2), |
rob.meades@u-blox.com | 1:566163f17cde | 587 | Case("Advanced config read/write fail cases", test_advanced_config_3), |
rob.meades@u-blox.com | 1:566163f17cde | 588 | Case("Advanced control", test_advanced_control), |
rob.meades@u-blox.com | 1:566163f17cde | 589 | Case("Advanced get", test_advanced_get), |
rob.meades@u-blox.com | 1:566163f17cde | 590 | Case("Advanced seal", test_advanced_seal), |
rob.meades@u-blox.com | 1:566163f17cde | 591 | Case("Advanced reset", test_advanced_reset) |
rob.meades@u-blox.com | 1:566163f17cde | 592 | }; |
rob.meades@u-blox.com | 1:566163f17cde | 593 | |
rob.meades@u-blox.com | 1:566163f17cde | 594 | Specification specification(test_setup, cases); |
rob.meades@u-blox.com | 1:566163f17cde | 595 | |
rob.meades@u-blox.com | 1:566163f17cde | 596 | // ---------------------------------------------------------------- |
rob.meades@u-blox.com | 1:566163f17cde | 597 | // MAIN |
rob.meades@u-blox.com | 1:566163f17cde | 598 | // ---------------------------------------------------------------- |
rob.meades@u-blox.com | 1:566163f17cde | 599 | |
rob.meades@u-blox.com | 1:566163f17cde | 600 | // Entry point into the tests |
rob.meades@u-blox.com | 1:566163f17cde | 601 | int main() { |
rob.meades@u-blox.com | 1:566163f17cde | 602 | bool success = false; |
rob.meades@u-blox.com | 1:566163f17cde | 603 | |
rob.meades@u-blox.com | 1:566163f17cde | 604 | if (gpI2C != NULL) { |
rob.meades@u-blox.com | 1:566163f17cde | 605 | success = !Harness::run(specification); |
rob.meades@u-blox.com | 1:566163f17cde | 606 | } else { |
rob.meades@u-blox.com | 1:566163f17cde | 607 | printf ("Unable to instantiate I2C interface.\n"); |
rob.meades@u-blox.com | 1:566163f17cde | 608 | } |
rob.meades@u-blox.com | 1:566163f17cde | 609 | |
rob.meades@u-blox.com | 1:566163f17cde | 610 | return success; |
rob.meades@u-blox.com | 1:566163f17cde | 611 | } |
rob.meades@u-blox.com | 1:566163f17cde | 612 | |
rob.meades@u-blox.com | 1:566163f17cde | 613 | // End Of File |