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:
Tue Jun 06 15:58:21 2017 +0100
Revision:
3:ebd56471d57c
Parent:
1:566163f17cde
Child:
5:63b325f2c21a
Add API to check if battery gauging is enabled.  Remove old UTM board pin-outs.  Remove unused Doxyfile.

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