Library to interface to the TI BQ27441, a fuel gauge monitor

Dependents:   rcCar

Fork of battery-gauge-bq27441 by u-blox

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