Statistics
| Branch: | Tag: | Revision:

amiro-os / os / unittests / periphery-lld / src / ut_alld_bq27500.c @ 22be62dc

History | View | Annotate | Download (17.006 KB)

1 e545e620 Thomas Schöpping
/*
2
AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
3
Copyright (C) 2016..2018  Thomas Schöpping et al.
4

5
This program is free software: you can redistribute it and/or modify
6
it under the terms of the GNU General Public License as published by
7
the Free Software Foundation, either version 3 of the License, or
8
(at your option) any later version.
9

10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
GNU General Public License for more details.
14

15
You should have received a copy of the GNU General Public License
16
along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
*/
18
19
#include <ut_alld_bq27500.h>
20
21
#if ((AMIROOS_CFG_TESTS_ENABLE == true) && defined(AMIROLLD_CFG_USE_BQ27500)) || defined(__DOXYGEN__)
22
23
#include <string.h>
24
#include <aos_debug.h>
25
#include <chprintf.h>
26
#include <aos_thread.h>
27
#include <alld_bq27500.h>
28
29
aos_utresult_t utAlldBq27500Func(BaseSequentialStream* stream, aos_unittest_t* ut)
30
{
31
  aosDbgCheck(ut->data != NULL && ((ut_bq27500data_t*)(ut->data))->driver != NULL);
32
33
  // local variables
34
  aos_utresult_t result = {0, 0};
35
  uint32_t status;
36
  bq27500_lld_batlow_t bl;
37
  bq27500_lld_batgood_t bg;
38
  uint16_t dst;
39
  bq27500_lld_flags_t flags;
40
  uint16_t subdata = 0;
41
  uint8_t original_length;
42
  char original_name[8+1];
43
  uint8_t val = 0x00;
44
  uint8_t block[32];
45
  char new_name[] = "test";
46
  uint8_t new_lenght;
47
  char name[8+1] = {'\0'};
48
  uint8_t sum = 0;
49
  bool success;
50
  bool success2;
51
52
  chprintf(stream, "read battery low gpio...\n");
53
  status = bq27500_lld_read_batlow(((ut_bq27500data_t*)ut->data)->driver, &bl);
54
  chprintf(stream, "\t\tbattery low: 0x%X\n", bl);
55
  if (status == APAL_STATUS_SUCCESS) {
56
    aosUtPassed(stream, &result);
57
  } else {
58
    aosUtFailedMsg(stream, &result, "0x%08X\n", status);
59
  }
60
61
  chprintf(stream, "read battery good gpio...\n");
62
  status = bq27500_lld_read_batgood(((ut_bq27500data_t*)ut->data)->driver, &bg);
63
  chprintf(stream, "\t\tbattery good: 0x%X\n", bg);
64
  if (status == APAL_STATUS_SUCCESS) {
65
    aosUtPassed(stream, &result);
66
  } else {
67
    aosUtFailedMsg(stream, &result, "0x%08X\n", status);
68
  }
69
70
  chprintf(stream, "std command FLAGS...\n");
71
  status = bq27500_lld_std_command(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_STD_CMD_Flags, &flags.value, ((ut_bq27500data_t*)ut->data)->timeout);
72
  chprintf(stream, "\t\tflags: 0x%04X\n", flags.value);
73
  chprintf(stream, "\t\tbattery detected: 0x%X\n", flags.content.bat_det);
74
  chprintf(stream, "\t\tbattery fully charged: 0x%X\n", flags.content.fc);
75
  if (status == APAL_STATUS_SUCCESS) {
76
    aosUtPassed(stream, &result);
77
  } else {
78
    aosUtFailedMsg(stream, &result, "0x%08X\n", status);
79
  }
80
81
  chprintf(stream, "std command CTNL...\n");
82
  status = bq27500_lld_std_command(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_STD_CMD_Control, &dst, ((ut_bq27500data_t*)ut->data)->timeout);
83
  if (status == APAL_STATUS_SUCCESS) {
84
    aosUtPassed(stream, &result);
85
  } else {
86
    aosUtFailedMsg(stream, &result, "0x%08X\n", status);
87
  }
88
89
  chprintf(stream, "sub command: CTRL Status...\n");
90
  aosThdMSleep(5);
91
  status = bq27500_lld_sub_command_call(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_SUB_CMD_CONTROL_STATUS, ((ut_bq27500data_t*)ut->data)->timeout);
92
  aosThdMSleep(5);
93
  status |= bq27500_lld_std_command(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_STD_CMD_Control, &dst, ((ut_bq27500data_t*)ut->data)->timeout);
94
  aosThdMSleep(5);
95
  bq27500_lld_control_status_t ctrl;
96
  status |= bq27500_lld_sub_command_read(((ut_bq27500data_t*)ut->data)->driver, &ctrl.value, ((ut_bq27500data_t*)ut->data)->timeout);
97
  chprintf(stream, "\t\tdst: 0x%X\n", ctrl.value);
98
  chprintf(stream, "\t\tsleep: 0x%X\n", ctrl.content.sleep);
99
  chprintf(stream, "\t\thibernate: 0x%X\n", ctrl.content.hibernate);
100
  if (status == APAL_STATUS_SUCCESS) {
101
    aosUtPassed(stream, &result);
102
  } else {
103
    aosUtFailedMsg(stream, &result, "0x%08X\n", status);
104
  }
105
106
  chprintf(stream, "sub command: firmware version...\n");
107
  status = bq27500_lld_sub_command_call(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_SUB_CMD_FW_VERSION, ((ut_bq27500data_t*)ut->data)->timeout);
108
  aosThdMSleep(1);
109
  bq27500_lld_version_t version;
110
  status |= bq27500_lld_sub_command_read(((ut_bq27500data_t*)ut->data)->driver, &version.value, ((ut_bq27500data_t*)ut->data)->timeout);
111
  chprintf(stream, "\t\tfirmware version: %X%X-%X%X\n", version.content.major_high, version.content.major_low, version.content.minor_high, version.content.minor_low);
112
  if (status == APAL_STATUS_SUCCESS) {
113
    aosUtPassed(stream, &result);
114
  } else {
115
    aosUtFailedMsg(stream, &result, "0x%08X\n", status);
116
  }
117
118
  chprintf(stream, "sub command: hardware version...\n");
119
  status = bq27500_lld_sub_command_call(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_SUB_CMD_HW_VERSION, ((ut_bq27500data_t*)ut->data)->timeout);
120
  aosThdMSleep(1);
121
  status |= bq27500_lld_sub_command_read(((ut_bq27500data_t*)ut->data)->driver, &version.value, ((ut_bq27500data_t*)ut->data)->timeout);
122
  chprintf(stream, "\t\thardware version: %X%X-%X%X\n", version.content.major_high, version.content.major_low, version.content.minor_high, version.content.minor_low);
123
  if (status == APAL_STATUS_SUCCESS) {
124
    aosUtPassed(stream, &result);
125
  } else {
126
    aosUtFailedMsg(stream, &result, "0x%08X\n", status);
127
  }
128
129
  chprintf(stream, "ext command: device name length...\n");
130
  status = bq27500_lld_ext_command(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_EXT_CMD_DeviceNameLength, BQ27500_LLD_EXT_CMD_READ, &original_length, 1, 0, ((ut_bq27500data_t*)ut->data)->timeout);
131
  chprintf(stream, "\t\tdevice name length: %d \n", original_length);
132
  if (status == APAL_STATUS_SUCCESS && original_length <= 8) {
133
    aosUtPassed(stream, &result);
134
  } else {
135
    aosUtFailedMsg(stream, &result, "0x%08X\n", status);
136
    original_length = 8;
137
  }
138
139
  chprintf(stream, "ext command: device name (read)...\n");
140
  status = bq27500_lld_ext_command(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_EXT_CMD_DeviceName, BQ27500_LLD_EXT_CMD_READ, (uint8_t*)original_name, original_length, 0, ((ut_bq27500data_t*)ut->data)->timeout);
141
  original_name[original_length] = '\0';
142
  chprintf(stream, "\t\tdevice name: %s\n", original_name);
143
  if (status == APAL_STATUS_SUCCESS) {
144
    aosUtPassed(stream, &result);
145
  } else {
146
    aosUtFailedMsg(stream, &result, "0x%08X\n", status);
147
  }
148
149
  chprintf(stream, "battery info std commands...\n");
150
  status = bq27500_lld_std_command(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_STD_CMD_Temperatur, &dst, ((ut_bq27500data_t*)ut->data)->timeout);
151
  chprintf(stream, "\t\ttemperature: %fK (%fC) \n", (float)dst/10.0f, (float)dst/10.0f-273.5f);
152
  status |= bq27500_lld_std_command(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_STD_CMD_FullAvailableCapacity, &dst, ((ut_bq27500data_t*)ut->data)->timeout);
153
  chprintf(stream, "\t\tfull available capacity: %umAh \n", dst);
154
  status |= bq27500_lld_std_command(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_STD_CMD_FullChargeCapacity, &dst, ((ut_bq27500data_t*)ut->data)->timeout);
155
  chprintf(stream, "\t\tfull charge capacity: %umAh \n", dst);
156
  status |= bq27500_lld_std_command(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_STD_CMD_RemainingCapacity, &dst, ((ut_bq27500data_t*)ut->data)->timeout);
157
  chprintf(stream, "\t\tremaining capacity: %umAh \n", dst);
158
  status |= bq27500_lld_std_command(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_STD_CMD_Voltage, &dst, ((ut_bq27500data_t*)ut->data)->timeout);
159
  chprintf(stream, "\t\tvoltage: %umV \n", dst);
160
  status |= bq27500_lld_std_command(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_STD_CMD_AverageCurrent, &dst, ((ut_bq27500data_t*)ut->data)->timeout);
161
  chprintf(stream, "\t\taverage current: %dmA \n", (int8_t)dst);
162
  status |= bq27500_lld_std_command(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_STD_CMD_AveragePower, &dst, ((ut_bq27500data_t*)ut->data)->timeout);
163
  chprintf(stream, "\t\taverage power: %dmW \n", (int8_t)dst);
164
  status |= bq27500_lld_std_command(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_STD_CMD_TimeToFull, &dst, ((ut_bq27500data_t*)ut->data)->timeout);
165
  if (dst != (uint16_t)~0) {
166
    chprintf(stream, "\t\ttime to full: %umin \n", dst);
167
  } else {
168
    chprintf(stream, "\t\ttime to full: (not charging) \n", dst);
169
  }
170
  status |= bq27500_lld_std_command(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_STD_CMD_TimeToEmpty, &dst, ((ut_bq27500data_t*)ut->data)->timeout);
171
  if (dst != (uint16_t)~0) {
172
    chprintf(stream, "\t\ttime to empty: %umin \n", dst);
173
  } else {
174
    chprintf(stream, "\t\ttime to empty: (not discharging) \n", dst);
175
  }
176
  if (status == APAL_STATUS_SUCCESS) {
177
    aosUtPassed(stream, &result);
178
  } else {
179
    aosUtFailedMsg(stream, &result, "0x%08X\n", status);
180
  }
181
182
  chprintf(stream, "check sealed state...\n");
183
  status = bq27500_lld_std_command(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_STD_CMD_Control, &dst, ((ut_bq27500data_t*)ut->data)->timeout);
184
  status |= bq27500_lld_sub_command_call(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_SUB_CMD_CONTROL_STATUS, ((ut_bq27500data_t*)ut->data)->timeout);
185
  aosThdMSleep(1);
186
  status |= bq27500_lld_sub_command_read(((ut_bq27500data_t*)ut->data)->driver, &ctrl.value, ((ut_bq27500data_t*)ut->data)->timeout);
187
  chprintf(stream, "\t\tsealed: 0x%X\n", ctrl.content.ss);
188
  chprintf(stream, "\t\tfull access sealed: 0x%X\n", ctrl.content.fas);
189
  if (status == APAL_STATUS_SUCCESS) {
190
    aosUtPassed(stream, &result);
191
  } else {
192
    aosUtFailedMsg(stream, &result, "0x%08X\n", status);
193
  }
194
195
  chprintf(stream, "unseale...\n");
196
  status = bq27500_lld_send_ctnl_data(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_DEFAULT_UNSEAL_KEY1, ((ut_bq27500data_t*)ut->data)->timeout);
197
  aosThdMSleep(50);
198
  status |= bq27500_lld_send_ctnl_data(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_DEFAULT_UNSEAL_KEY0, ((ut_bq27500data_t*)ut->data)->timeout);
199
  aosThdMSleep(50);
200
  status |= bq27500_lld_sub_command_call(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_SUB_CMD_CONTROL_STATUS, ((ut_bq27500data_t*)ut->data)->timeout);
201
  aosThdMSleep(50);
202
  status |= bq27500_lld_std_command(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_STD_CMD_Control, &dst, ((ut_bq27500data_t*)ut->data)->timeout);
203
  status |= bq27500_lld_sub_command_read(((ut_bq27500data_t*)ut->data)->driver, &ctrl.value, ((ut_bq27500data_t*)ut->data)->timeout);
204
  if (status == APAL_STATUS_SUCCESS && ctrl.content.ss == 0x0) {
205
    aosUtPassed(stream, &result);
206
  } else {
207
    aosUtFailedMsg(stream, &result, "0x%08X\n", status);
208
  }
209
210
  chprintf(stream, "read device name from data flash...\n");
211
  status = bq27500_lld_ext_command(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_EXT_CMD_BlockDataControl, BQ27500_LLD_EXT_CMD_WRITE, &val, 1, 0, ((ut_bq27500data_t*)ut->data)->timeout);
212
  aosThdMSleep(50);
213
  val = 0x30;
214
  status |= bq27500_lld_ext_command(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_EXT_CMD_DataFlashClass, BQ27500_LLD_EXT_CMD_WRITE, &val, 1, 0, ((ut_bq27500data_t*)ut->data)->timeout);
215
  aosThdMSleep(50);
216
  val = 0;
217
  status |= bq27500_lld_ext_command(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_EXT_CMD_DataFlashBlock, BQ27500_LLD_EXT_CMD_WRITE, &val, 1, 0, ((ut_bq27500data_t*)ut->data)->timeout);
218
  aosThdMSleep(50);
219
  status |= bq27500_lld_ext_command(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_EXT_CMD_BlockData, BQ27500_LLD_EXT_CMD_READ, (uint8_t*)block, original_length, 13, ((ut_bq27500data_t*)ut->data)->timeout);
220
  block[original_length] = '\0';
221
  chprintf(stream, "\t\tdevice name: %s\n", block);
222
  if (status == APAL_STATUS_SUCCESS && (strcmp((char*)block, (char*)original_name) == 0)) {
223
    aosUtPassed(stream, &result);
224
  } else {
225
    chprintf(stream, "\t\tread data: ");
226
    for (uint8_t blockIdx = 0; blockIdx < original_length; blockIdx++) {
227
      chprintf(stream, "0x%02X\n", block[blockIdx]);
228
    }
229
    aosUtFailedMsg(stream, &result, "0x%08X\n", status);
230
  }
231
232
  chprintf(stream, "change device name in data flash to \"test\"...\n");
233
  status = bq27500_lld_ext_command(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_EXT_CMD_BlockData, BQ27500_LLD_EXT_CMD_WRITE, (uint8_t*)new_name, 5, 13, ((ut_bq27500data_t*)ut->data)->timeout);
234
  aosThdMSleep(50);
235
  status |= bq27500_lld_ext_command(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_EXT_CMD_BlockData, BQ27500_LLD_EXT_CMD_READ, (uint8_t*)block, 32, 0, ((ut_bq27500data_t*)ut->data)->timeout);
236
  // compute blockdata checksum
237
  status |= bq27500_lld_compute_blockdata_checksum(block, &sum);
238
  // write checksum to BlockDataChecksum, triggering the write of BlackData
239
  status |= bq27500_lld_ext_command(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_EXT_CMD_BlockDataCheckSum, BQ27500_LLD_EXT_CMD_WRITE, &sum, 1, 0, ((ut_bq27500data_t*)ut->data)->timeout);
240
  aosThdMSleep(50);
241
  status |= bq27500_lld_ext_command(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_EXT_CMD_DeviceNameLength, BQ27500_LLD_EXT_CMD_READ, &new_lenght, 1, 0, ((ut_bq27500data_t*)ut->data)->timeout);
242
  aosThdMSleep(50);
243
  // read out device name, to see if changing it was successfull
244
  status |= bq27500_lld_ext_command(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_EXT_CMD_DeviceName, BQ27500_LLD_EXT_CMD_READ, (uint8_t*)name, new_lenght, 0, ((ut_bq27500data_t*)ut->data)->timeout);
245
  name[new_lenght] = '\0';
246
  chprintf(stream, "\t\tdevice name: %s\n", name);
247
  success = (strcmp(name, new_name) == 0);
248
249
  // change device name back to original name
250
  val = 0x00;
251
  status = bq27500_lld_ext_command(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_EXT_CMD_BlockDataControl, BQ27500_LLD_EXT_CMD_WRITE, &val, 1, 0, ((ut_bq27500data_t*)ut->data)->timeout);
252
  aosThdMSleep(50);
253
  val = 0x30;
254
  status |= bq27500_lld_ext_command(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_EXT_CMD_DataFlashClass, BQ27500_LLD_EXT_CMD_WRITE, &val, 1, 0, ((ut_bq27500data_t*)ut->data)->timeout);
255
  aosThdMSleep(50);
256
  val = 0;
257
  status |= bq27500_lld_ext_command(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_EXT_CMD_DataFlashBlock, BQ27500_LLD_EXT_CMD_WRITE, &val, 1, 0, ((ut_bq27500data_t*)ut->data)->timeout);
258
  aosThdMSleep(50);
259
  status |= bq27500_lld_ext_command(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_EXT_CMD_BlockData, BQ27500_LLD_EXT_CMD_WRITE, (uint8_t*)original_name, 7, 13, ((ut_bq27500data_t*)ut->data)->timeout);
260
  aosThdMSleep(50);
261
  status |= bq27500_lld_ext_command(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_EXT_CMD_BlockData, BQ27500_LLD_EXT_CMD_READ, (uint8_t*)block, 32, 0, ((ut_bq27500data_t*)ut->data)->timeout);
262
  // compute blockdata checksum
263
  sum = 0;
264
  status |= bq27500_lld_compute_blockdata_checksum(block, &sum);
265
  // write checksum to BlockDataChecksum, triggering the write of BlackData
266
  status |= bq27500_lld_ext_command(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_EXT_CMD_BlockDataCheckSum, BQ27500_LLD_EXT_CMD_WRITE, &sum, 1, 0, ((ut_bq27500data_t*)ut->data)->timeout);
267
  aosThdMSleep(1000);
268
  status |= bq27500_lld_ext_command(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_EXT_CMD_DeviceNameLength, BQ27500_LLD_EXT_CMD_READ, &original_length, 1, 0, ((ut_bq27500data_t*)ut->data)->timeout);
269
  aosThdMSleep(50);
270
  // read device name, to see if changing it back to the original name was successfull
271
  status |= bq27500_lld_ext_command(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_EXT_CMD_DeviceName, BQ27500_LLD_EXT_CMD_READ, (uint8_t*)name, original_length, 0, ((ut_bq27500data_t*)ut->data)->timeout);
272
  success2 = (strcmp(name, original_name) == 0);
273
  name[original_length] = '\0';
274
  chprintf(stream, "\t\tchanged back to name: %s, original_name: %s\n", name, original_name);
275
  if (status == APAL_STATUS_OK && ((success && success2) || (ctrl.content.sleep == 0))) {
276
    aosUtPassed(stream, &result);
277
  } else {
278
    aosUtFailedMsg(stream, &result, "0x%08X, changing: 0x%X - changing back: 0x%X\n", status, success, success2);
279
  }
280
281
  chprintf(stream, "seal...\n");
282
  status = bq27500_lld_std_command(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_STD_CMD_Control, &dst, ((ut_bq27500data_t*)ut->data)->timeout);
283
  aosThdMSleep(50);
284
  status |= bq27500_lld_sub_command_call(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_SUB_CMD_SEALED, ((ut_bq27500data_t*)ut->data)->timeout);
285
  aosThdMSleep(50);
286
  status |= bq27500_lld_std_command(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_STD_CMD_Control, &dst, ((ut_bq27500data_t*)ut->data)->timeout);
287
  aosThdMSleep(50);
288
  status |= bq27500_lld_sub_command_call(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_SUB_CMD_CONTROL_STATUS, ((ut_bq27500data_t*)ut->data)->timeout);
289
  aosThdMSleep(50);
290
  status |= bq27500_lld_sub_command_read(((ut_bq27500data_t*)ut->data)->driver, &ctrl.value, ((ut_bq27500data_t*)ut->data)->timeout);
291
  if (status == APAL_STATUS_SUCCESS && ctrl.content.ss == 0x1) {
292
    aosUtPassed(stream, &result);
293
  } else {
294
    chprintf(stream, "\tfailed (0x%X)\n", status);
295
    aosUtFailedMsg(stream, &result, "0x%08X, ctrl 0x%X\n", status, subdata);
296
    ++result.failed;
297
  }
298
299
  aosUtInfoMsg(stream,"driver object memory footprint: %u bytes\n", sizeof(BQ27500Driver));
300
301
  return result;
302
}
303
304
#endif /* (AMIROOS_CFG_TESTS_ENABLE == true) && defined(AMIROLLD_CFG_USE_BQ27500) */