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:
Mon Apr 10 11:18:51 2017 +0100
Revision:
1:566163f17cde
Child:
3:ebd56471d57c
Add files to repo, removing temp.txt placeholder.

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