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

Committer:
rob.meades@u-blox.com
Date:
Wed Jun 14 17:11:40 2017 +0100
Revision:
5:63b325f2c21a
Parent:
3:ebd56471d57c
Add ability to enable/disable battery detection and make sure that it is switched off when the tests are run on the u-blox C030 platform (since the BIN pin is not connected).

Who changed what in which revision?

UserRevisionLine numberNew 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(&currentMA));
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(&currentMA));
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