Lamp-Da 0.1
A compact lantern project
Loading...
Searching...
No Matches
BQ76905.h
Go to the documentation of this file.
1/**************************************************************************/
9/**************************************************************************/
10
11#ifndef BQ76905_H
12#define BQ76905_H
13
14#include <cstdint>
15
16namespace bq76905 {
17
18using byte = uint8_t;
19
20// Platform specific
21constexpr uint8_t i2cObjectIndex = 0;
22// \Platform specific
23
24constexpr bool usesStopBit = true;
25
26constexpr uint16_t DEVICE_NUMBER = 0x7605;
27
28// addresses
29
30constexpr uint8_t SAFETY_ALERT_A_ADDR = 0x02;
31constexpr uint8_t SAFETY_ALERT_B_ADDR = 0x04;
32
33constexpr uint8_t BATTERY_STATUS_ADDR = 0x12;
34
35constexpr uint8_t CELL_1_VOLTAGE_ADDR = 0x14;
36constexpr uint8_t CELL_2_VOLTAGE_ADDR = 0x16;
37constexpr uint8_t CELL_3_VOLTAGE_ADDR = 0x18;
38constexpr uint8_t CELL_4_VOLTAGE_ADDR = 0x1A;
39constexpr uint8_t CELL_5_VOLTAGE_ADDR = 0x1C;
40
41constexpr uint8_t REG_18_VOLTAGE_ADDR = 0x22;
42
43constexpr uint8_t VSS_VOLTAGE_ADDR = 0x24;
44constexpr uint8_t STACK_VOLTAGE_ADDR = 0x26;
45
46constexpr uint8_t INT_TEMPERATURE_ADDR = 0x28;
47constexpr uint8_t TS_MEASURMENT_ADDR = 0x2A;
48
49constexpr uint8_t RAW_CURRENT_ADDR = 0x36;
50constexpr uint8_t CURRENT_ADDR = 0x3A;
51constexpr uint8_t CC1_CURRENT_ADDR = 0x3C;
52
53constexpr uint8_t ALARM_STATUS_ADDR = 0x62;
54constexpr uint8_t ALARM_RAW_STATUS_ADDR = 0x64;
55constexpr uint8_t ALARM_ENABLE_ADDR = 0x66;
56
57constexpr uint8_t FET_CONTROL_ADDR = 0x68;
58constexpr uint8_t REGOUT_CONTROL_ADDR = 0x69;
59
60constexpr uint8_t DSG_FET_DRIVER_PWM_CONTROL_ADDR = 0x6A;
61constexpr uint8_t CHG_FET_DRIVER_PWM_CONTROL_ADDR = 0x6C;
62
63// adresses for subcommands
64
65constexpr uint8_t SUBCOMMAND_ADDR = 0x3E;
66constexpr uint8_t SUBCOMMAND_DATA_ADDR = 0x40;
67constexpr uint8_t SUBCOMMAND_DATA_CHECKSUM_ADDR = 0x60;
68
69constexpr uint16_t SUBCOMMAND_DEVICE_NUMBER_ADDR = 0x0001;
70constexpr uint16_t SUBCOMMAND_FW_VERSION_ADDR = 0x0002;
71constexpr uint16_t SUBCOMMAND_HW_VERSION_ADDR = 0x0003;
72
73constexpr uint16_t SUBCOMMAND_PASSQ_ADDR = 0x0003;
74constexpr uint16_t SUBCOMMAND_RESET_PASSQ_ADDR = 0x0005;
75
76constexpr uint16_t SUBCOMMAND_EXIT_DEEPSLEEP_ADDR = 0x000E;
77constexpr uint16_t SUBCOMMAND_DEEPSLEEP_ADDR = 0x000F;
78constexpr uint16_t SUBCOMMAND_SHUTDOWN_ADDR = 0x0010;
79constexpr uint16_t SUBCOMMAND_RESET_ADDR = 0x0012;
80
81constexpr uint16_t SUBCOMMAND_FET_ENABLE_ADDR = 0x0022;
82
83constexpr uint16_t SUBCOMMAND_SEAL_ADDR = 0x0030;
84
85constexpr uint16_t SUBCOMMAND_SECURITY_KEYS_ADDR = 0x0035;
86
87constexpr uint16_t SUBCOMMAND_CB_ACTIVE_CELLS_ADDR = 0x0083;
88
89constexpr uint16_t SUBCOMMAND_SET_CFGUPDATE_ADDR = 0x0090;
90constexpr uint16_t SUBCOMMAND_EXIT_CFGUPDATE_ADDR = 0x0092;
91
92constexpr uint16_t SUBCOMMAND_PROG_TIMER_ADDR = 0x0094;
93
94constexpr uint16_t SUBCOMMAND_SLEEP_ENABLE_ADDR = 0x0099;
95constexpr uint16_t SUBCOMMAND_SLEEP_DISABLE_ADDR = 0x009A;
96
97constexpr uint16_t SUBCOMMAND_PROT_RECOVERY_ADDR = 0x009B;
98
99// configuration registers
100
101// most of them are not implemented to prevent missuse
102
103constexpr uint16_t SUBCOMMAND_CONFIGURATION_DA_ADDR = 0x9019;
104constexpr uint16_t SUBCOMMAND_CONFIGURATION_VCELL_MODE_ADDR = 0x901B;
105constexpr uint16_t SUBCOMMAND_CONFIGURATION_TS_OFFSET_ADDR = 0x900E;
106
107// compute data checksum for communication
108uint8_t checksum(uint8_t lenght, uint8_t* data)
109{
110 uint8_t checksum = 0;
111 for (uint8_t i = 0; i < lenght; ++i)
112 checksum += data[i];
113 checksum = 0xff & (~checksum);
114 return checksum;
115}
116
118{
119public:
120 BQ76905() {};
121 // Initialise the variable here, but it will be written from the main program
122 static const byte BQ76905addr = 0x08; // I2C address
123
124 template<typename T> bool readRegEx(T& dataParam)
125 {
126 // This is a function for reading data words.
127 // The number of bytes that make up a word is 2.
128 constexpr uint8_t arrLen = 2;
129 // Create an array to hold the returned data
130 byte valBytes[arrLen];
131
132 if (readDataReg(dataParam.addr, valBytes, arrLen))
133 {
134 // Cycle through array of data
135 dataParam.val0 = (byte)valBytes[0];
136 dataParam.val1 = (byte)valBytes[1];
137 return true;
138 }
139 return false;
140 }
141 // used by external functions to write registers
142 template<typename T> static bool writeRegEx(T dataParam)
143 {
144 byte valBytes[2];
145 valBytes[0] = dataParam.val0;
146 valBytes[1] = dataParam.val1;
147 return writeData(dataParam.addr, 2, valBytes);
148 }
149// macro to generate bit mask to access bits
150#define GETMASK(index, size) (((1 << (size)) - 1) << (index))
151// macro to read bits from variable, using mask
152#define READFROM(data, index, size) (((data) & GETMASK((index), (size))) >> (index))
153// macro to write bits into variable, using mask
154#define WRITETO(data, index, size, value) ((data) = ((data) & (~GETMASK((index), (size)))) | ((value) << (index)))
155// macro to wrap functions for easy access
156// if name is called with empty brackets, read bits and return value
157// if name is prefixed with set_, write value in brackets into bits defined in
158// FIELD
159#define FIELD(data, name, index, size) \
160 inline decltype(data) name() { return READFROM(data, index, size); } \
161 inline void set_##name(decltype(data) value) { WRITETO(data, index, size, value); }
162
163// macro to wrap functions for easy access, read only
164// if name is called with empty brackets, read bits and return value
165#define FIELD_RO(data, name, index, size) \
166 inline decltype(data) name() { return READFROM(data, index, size); }
167
168 // used to set and reset the error flag
169 inline static bool isFlagRaised = false;
170
171 // Base class for register operations
173 {
174 virtual ~IBaseReadRegister() {};
175
176 virtual uint16_t address() const = 0;
177
178 int16_t get()
179 {
180 byte valBytes[2];
181 if (readDataReg(address(), valBytes, 2))
182 {
183 // Cycle through array of data
184 byte val0 = (byte)valBytes[0];
185 byte val1 = (byte)valBytes[1];
186
187 // fuse them
188 uint16_t res = val1 << 8 | val0;
189 // convert to real units
190 return (uint16_t)res;
191 }
192 isFlagRaised = true;
193 // error
194 return 0;
195 }
196 };
197
199 {
200 virtual ~ISubcommandRegister() {};
201
202 virtual uint16_t command_address() const = 0;
203
204 protected:
205 void raw_send()
206 {
207 // write command header
208 if (!writeData16(SUBCOMMAND_ADDR, command_address()))
209 {
210 isFlagRaised = true;
211 return;
212 }
213 }
214 };
215
217 {
218 virtual ~ISubcommandReadRegister() {};
219
220 static constexpr uint8_t readDataSize = 12;
221 byte valBytes[readDataSize];
222
223 uint32_t get_read_results()
224 {
225 const uint32_t res = (valBytes[3] << 24) | (valBytes[2] << 16) | (valBytes[1] << 8) | valBytes[0];
226 return res;
227 }
228
229 protected:
230 void raw_read()
231 {
232 // set command
233 raw_send();
234
235 delay_us(2000);
236
237 if (!readDataReg(SUBCOMMAND_DATA_ADDR, valBytes, readDataSize))
238 {
239 isFlagRaised = true;
240 }
241 }
242
243 void raw_read_big_endian()
244 {
245 // set command
246 raw_send();
247
248 delay_us(2000);
249
250 byte tempValBytes[readDataSize];
251 if (readDataReg(SUBCOMMAND_DATA_ADDR, tempValBytes, 12))
252 {
253 for (uint i = 0; i < readDataSize; i += 2)
254 {
255 // big endian
256 valBytes[i + 1] = tempValBytes[i];
257 valBytes[i] = tempValBytes[i + 1];
258 }
259 return;
260 }
261 isFlagRaised = true;
262 }
263
264 void raw_write8(uint8_t data)
265 {
266 const uint8_t dataSize = 3;
267
268 // 2 bytes for adress (always), max data to send on 32 bits
269 byte valBytes[dataSize];
270 valBytes[0] = command_address() & 0xff;
271 valBytes[1] = (command_address() >> 8) & 0xff;
272 valBytes[2] = data;
273
274 raw_write(dataSize, valBytes);
275 }
276
277 void raw_write16(uint16_t data)
278 {
279 const uint8_t dataSize = 4;
280
281 // 2 bytes for adress (always), max data to send on 32 bits
282 byte valBytes[dataSize];
283 valBytes[0] = command_address() & 0xff;
284 valBytes[1] = (command_address() >> 8) & 0xff;
285 valBytes[2] = data & 0xff;
286 valBytes[3] = (data >> 8) & 0xff;
287
288 raw_write(dataSize, valBytes);
289 }
290
291 private:
292 // internal command write
293 void raw_write(uint8_t lenght, uint8_t* data)
294 {
295 if (not writeData(SUBCOMMAND_ADDR, lenght, data))
296 {
297 isFlagRaised = true;
298 return;
299 }
300
301 delay_us(2000);
302
303 byte checkSumData[2];
304 checkSumData[0] = checksum(lenght, data);
305 checkSumData[1] = lenght + 2;
306
307 // Write Data Checksum and length, required for RAM writes
308 if (not writeData(SUBCOMMAND_DATA_CHECKSUM_ADDR, 2, checkSumData))
309 {
310 isFlagRaised = true;
311 return;
312 }
313 }
314 };
315
317 {
318 uint8_t val0;
319 uint8_t val1;
320
321 void read_reg()
322 {
323 raw_read();
324 val0 = valBytes[0];
325 val1 = valBytes[1];
326 }
327
328 void write()
329 {
330 uint16_t vals = val1 << 8 | val0;
331 raw_write16(vals);
332 }
333 };
334
335 struct Regt
336 {
337 // Provides individual alert signals when enabled safety alerts have triggered
338 // Provides individual fault signals when enabled safety faults have triggered
340 {
341 uint8_t addr = SAFETY_ALERT_A_ADDR;
342 byte val0 = 0x00;
343 byte val1 = 0x00;
344 // Cell Overvoltage Safety Alert
345 // 0 = Indicates protection alert has not triggered
346 // 1 = indicates protection alert has triggered
347 FIELD_RO(val0, COV_ALERT, 0x07, 0x01)
348 // Cell Undervoltage Safety Alert
349 // 0 = Indicates protection alert has not triggered
350 // 1 = indicates protection alert has triggered
351 FIELD_RO(val0, CUV_ALERT, 0x06, 0x01)
352 // Short Circuit in Discharge Safety Alert
353 // 0 = Indicates protection alert has not triggered
354 // 1 = indicates protection alert has triggered
355 FIELD_RO(val0, SCD_ALERT, 0x05, 0x01)
356 // Overcurrent in Discharge 1 Safety Alert
357 // 0 = Indicates protection alert has not triggered
358 // 1 = indicates protection alert has triggered
359 FIELD_RO(val0, OCD1_ALERT, 0x04, 0x01)
360 // Overcurrent in Discharge 2 Safety Alert
361 // 0 = Indicates protection alert has not triggered
362 // 1 = indicates protection alert has triggered
363 FIELD_RO(val0, OCD2_ALERT, 0x03, 0x01)
364 // Overcurrent in Charge Safety Alert
365 // 0 = Indicates protection alert has not triggered
366 // 1 = indicates protection alert has triggered
367 FIELD_RO(val0, OCC_ALERT, 0x02, 0x01)
368
369 // Cell Overvoltage Safety Fault
370 // 0 = Indicates protection fault has not triggered
371 // 1 = indicates protection fault has triggered
372 FIELD_RO(val1, COV_FAULT, 0x07, 0x01)
373 // Cell Undervoltage Safety Fault
374 // 0 = Indicates protection fault has not triggered
375 // 1 = indicates protection fault has triggered
376 FIELD_RO(val1, CUV_FAULT, 0x06, 0x01)
377 // Short Circuit in Discharge Safety Fault
378 // 0 = Indicates protection fault has not triggered
379 // 1 = indicates protection fault has triggered
380 FIELD_RO(val1, SCD_FAULT, 0x05, 0x01)
381 // Overcurrent in Discharge 1 Safety Fault
382 // 0 = Indicates protection fault has not triggered
383 // 1 = indicates protection fault has triggered
384 FIELD_RO(val1, OCD1_FAULT, 0x04, 0x01)
385 // Overcurrent in Discharge 2 Safety Fault
386 // 0 = Indicates protection fault has not triggered
387 // 1 = indicates protection fault has triggered
388 FIELD_RO(val1, OCD2_FAULT, 0x03, 0x01)
389 // Overcurrent in Charge Safety Fault
390 // 0 = Indicates protection fault has not triggered
391 // 1 = indicates protection fault has triggered
392 FIELD_RO(val1, OCC_FAULT, 0x02, 0x01)
393 // Current Protection Latch Safety Fault
394 // 0 = Indicates the number of attempted current protection recoveries has not yet exceeded the latch count.
395 // 1 = Indicates the number of attempted current protection recoveries has exceeded the latch count, and
396 // autorecovery based on time is disabled
397 FIELD_RO(val1, CURLATCH, 0x01, 0x01)
398 // REGOUT Safety Fault
399 // 0 = Indicates protection fault has not triggered
400 // 1 = indicates protection fault has triggered
401 FIELD_RO(val1, REGOUT, 0x00, 0x01)
402 } safetyAlertA;
403
404 // Provides individual alert signals when enabled safety alerts have triggered.
405 // Provides individual fault signals when enabled safety faults have triggered.
407 {
408 uint8_t addr = SAFETY_ALERT_B_ADDR;
409 byte val0 = 0x00;
410 byte val1 = 0x00;
411
412 // Overtemperature in Discharge Safety Alert
413 // 0 = Indicates protection alert has not triggered
414 // 1 = indicates protection alert has triggered
415 FIELD_RO(val0, OTD_ALERT, 0x07, 0x01)
416 // Overtemperature in Charge Safety Alert
417 // 0 = Indicates protection alert has not triggered
418 // 1 = indicates protection alert has triggered
419 FIELD_RO(val0, OTC_ALERT, 0x06, 0x01)
420 // Undertemperature in Discharge Safety Alert
421 // 0 = Indicates protection alert has not triggered
422 // 1 = indicates protection alert has triggered
423 FIELD_RO(val0, UTD_ALERT, 0x05, 0x01)
424 // Undertemperature in Charge Safety Alert
425 // 0 = Indicates protection alert has not triggered
426 // 1 = indicates protection alert has triggered
427 FIELD_RO(val0, UTC_ALERT, 0x04, 0x01)
428 // Internal Overtemperature Safety Alert
429 // 0 = Indicates protection alert has not triggered
430 // 1 = indicates protection alert has triggered
431 FIELD_RO(val0, OTINT_ALERT, 0x03, 0x01)
432 // Host Watchdog Safety Alert
433 // 0 = Indicates protection alert has not triggered
434 // 1 = indicates protection alert has triggered
435 FIELD_RO(val0, HWD_ALERT, 0x02, 0x01)
436 // VREF Measurement Diagnostic Alert
437 // 0 = Indicates protection alert has not triggered
438 // 1 = indicates protection alert has triggered
439 FIELD_RO(val0, VREF_ALERT, 0x01, 0x01)
440 // VSS Measurement Diagnostic Alert
441 // 0 = Indicates protection alert has not triggered
442 // 1 = indicates protection alert has triggered
443 FIELD_RO(val0, VSS_ALERT, 0x00, 0x01)
444
445 // Overtemperature in Discharge Safety Fault
446 // 0 = Indicates protection fault has not triggered
447 // 1 = indicates protection fault has triggered
448 FIELD_RO(val1, OTD_FAULT, 0x07, 0x01)
449 // Overtemperature in Charge Safety Fault
450 // 0 = Indicates protection fault has not triggered
451 // 1 = indicates protection fault has triggered
452 FIELD_RO(val1, OTC_FAULT, 0x06, 0x01)
453 // Undertemperature in Discharge Safety Fault
454 // 0 = Indicates protection fault has not triggered
455 // 1 = indicates protection fault has triggered
456 FIELD_RO(val1, UTD_FAULT, 0x05, 0x01)
457 // Undertemperature in Charge Safety Fault
458 // 0 = Indicates protection fault has not triggered
459 // 1 = indicates protection fault has triggered
460 FIELD_RO(val1, UTC_FAULT, 0x04, 0x01)
461 // Internal Overtemperature Safety Fault
462 // 0 = Indicates protection fault has not triggered
463 // 1 = indicates protection fault has triggered
464 FIELD_RO(val1, OTINT_FAULT, 0x03, 0x01)
465 // Host Watchdog Safety Fault
466 // 0 = Indicates protection fault has not triggered
467 // 1 = indicates protection fault has triggered
468 FIELD_RO(val1, HWD_FAULT, 0x02, 0x01)
469 // VREF Measurement Diagnostic Fault
470 // 0 = Indicates protection fault has not triggered
471 // 1 = indicates protection fault has triggered
472 FIELD_RO(val1, VREF_FAULT, 0x01, 0x01)
473 // VSS Measurement Diagnostic Fault
474 // 0 = Indicates protection fault has not triggered
475 // 1 = indicates protection fault has triggered
476 FIELD_RO(val1, VSS_FAULT, 0x00, 0x01)
477 } safetyAlertB;
478
479 // Provides flags related to battery status.
481 {
482 uint8_t addr = BATTERY_STATUS_ADDR;
483 byte val0 = 0x00;
484 byte val1 = 0x00;
485
486 // This bit is set when the device fully resets. It is cleared upon exit of CONFIG_UPDATE mode. It can be used by
487 // the host to determine if any RAM configuration changes were lost due to a reset.
488 // 0 = Full reset has not occurred since last exit of CONFIG_UPDATE mode.
489 // 1 = Full reset has occurred since last exit of CONFIG_UPDATE and reconfiguration of any RAM settings is
490 // required.
491 FIELD_RO(val0, POR, 0x07, 0x01)
492 // This bit indicates whether or not SLEEP mode is allowed based on configuration and commands.
493 // TheSettings:Configuration:Power Config[SLEEP_EN] bit sets the default state of this bit. The host can send
494 // commands to enable or disable SLEEP mode based on system requirements. When this bit is set, the device can
495 // transition to SLEEP mode when other SLEEP criteria are met.
496 // 0 = SLEEP mode is disabled by the host.
497 // 1 = SLEEP mode is allowed when other SLEEP conditions are met.
498 FIELD_RO(val0, SLEEP_EN, 0x06, 0x01)
499 // This bit indicates whether or not the device is in CONFIG_UPDATE mode. It is set after the SET_CFGUPDATE()
500 // subcommand is received and fully processed. Configuration settings can be changed only while this bit is set.
501 // 0 = Device is not in CONFIG_UPDATE mode.
502 // 1 = Device is in CONFIG_UPDATE mode.
503 FIELD_RO(val0, CFGUPDATE, 0x05, 0x01)
504 // This bit indicates whether the ALERT pin is asserted (pulled low).
505 // 0 = ALERT pin is not asserted (stays in hi-Z mode).
506 // 1 = ALERT pin is asserted (pulled low)
507 FIELD_RO(val0, ALERTPIN, 0x04, 0x01)
508 // This bit indicates whether the CHG driver is enabled.
509 // 0 = CHG driver is disabled.
510 // 1 = CHG driver is enabled
511 FIELD_RO(val0, CHG, 0x03, 0x01)
512 // This bit indicates whether the DSG driver is enabled.
513 // 0 = DSG driver is disabled.
514 // 1 = DSG driver is enabled
515 FIELD_RO(val0, DSG, 0x02, 0x01)
516 // This bit indicates the value of the debounced CHG Detector signal.
517 // 0 = CHG Detector debounced signal is low.
518 // 1 = CHG Detector debounced signal is high.
519 FIELD_RO(val0, CHGDETFLAG, 0x01, 0x01)
520
521 // This flag asserts if the device is in SLEEP mode
522 // 0 = Device is not in SLEEP mode
523 // 1 = Device is in SLEEP mode
524 FIELD_RO(val1, SLEEP, 0x07, 0x01)
525 // This flag asserts if the device is in DEEPSLEEP mode
526 // 0 = Device is not in DEEPSLEEP mode
527 // 1 = Device is in DEEPSLEEP mode
528 FIELD_RO(val1, DEEPSLEEP, 0x06, 0x01)
529 // This flag asserts if an enabled safety alert is present.
530 // 0 = Indicates an enabled safety alert is not present
531 // 1 = Indicates an enabled safety alert is present
532 FIELD_RO(val1, SA, 0x05, 0x01)
533 // This flag asserts if an enabled safety fault is present.
534 // 0 = Indicates an enabled safety fault is not present
535 // 1 = Indicates an enabled safety fault is present
536 FIELD_RO(val1, SS, 0x04, 0x01)
537 // SEC1:0 indicate the present security state of the device.
538 // When in SEALED mode, device configuration cannot be read or written and some
539 // commands are restricted.
540 // When in FULLACCESS mode, unrestricted read and write access is allowed and all
541 // commands are accepted.
542 // 0 = 0: Device has not initialized yet.
543 // 1 = 1: Device is in FULLACCESS mode.
544 // 2 = 2: Unused.
545 // 3 = 3: Device is in SEALED mode.
546 FIELD_RO(val1, SEC, 0x02, 0x02)
547 // This bit is set when the device is in autonomous FET control mode. The default value of this bit is set by the
548 // Settings:FET Options[FET_EN] bit in Data Memory upon exit of CONFIG_UPDATE mode. Its value can be modified
549 // during operation using the FET_ENABLE() subcommand.
550 // 0 = Device is not in autonomous FET control mode, FETs are only enabled through manual command.
551 // 1 = Device is in autonomous FET control mode, FETs can be enabled by the device if no conditions or commands
552 // prevent them being enabled.
553 FIELD_RO(val1, FET_EN, 0x00, 0x01)
554 } batteryStatus;
555
556 // Latched signal used to assert the ALERT pin. Write a bit high to clear the latched bit.
558 {
559 uint8_t addr = ALARM_STATUS_ADDR;
560 byte val0 = 0x00;
561 byte val1 = 0x00;
562
563 // This bit is latched when a full scan is complete (including cell voltages, top-of-stack voltage, temperature,
564 // and diagnostic measurements), and the bit is included in the mask. The bit is cleared when written with a "1".
565 // A bit set here causes the ALERT pin to be asserted low.
566 // 0 = Flag is not set
567 // 1 = Flag is set
568 FIELD(val0, FULLSCAN, 0x07, 0x01)
569 // This bit is latched when a voltage ADC measurement scan is complete (this includes the cell voltage
570 // measurements and one additional measurement), and the bit is included in the mask. The bit is cleared when
571 // written with a "1". A bit set here causes the ALERT pin to be asserted low.
572 // 0 = Flag is not set
573 // 1 = Flag is set
574 FIELD(val0, ADSCAN, 0x06, 0x01)
575 // This bit is latched when the device is wakened from SLEEP mode, and the bit is included in the mask. The bit is
576 // cleared when written with a "1". A bit set here causes the ALERT pin to be asserted low.
577 // 0 = Flag is not set
578 // 1 = Flag is set
579 FIELD(val0, WAKE, 0x05, 0x01)
580 // This bit is latched when the device enters SLEEP mode, and the bit is included in the mask. The bit is cleared
581 // when written with a "1". A bit set here causes the ALERT pin to be asserted low.
582 // 0 = Flag is not set
583 // 1 = Flag is set
584 FIELD(val0, SLEEP, 0x04, 0x01)
585 // This bit is latched when the programmable timer expires, and the bit is included in the mask. The bit is
586 // cleared when written with a "1". A bit set here causes the ALERT pin to be asserted low.
587 // 0 = Flag is not set
588 // 1 = Flag is set
589 FIELD(val0, TIMER_ALARM, 0x03, 0x01)
590 // This bit is latched when the device completes the startup measurement sequence (which runs after an initial
591 // powerup, after a device reset, when the device exits CONFIG_UPDATE mode, and when it exits DEEPSLEEP mode) and
592 // the bit is included in the mask. The bit is cleared when written with a "1". A bit set here causes the ALERT
593 // pin to be asserted low.
594 // 0 = Flag is not set
595 // 1 = Flag is set
596 FIELD(val0, INITCOMP, 0x02, 0x01)
597 // This bit is latched when the debounced CHG Detector signal is different from the last debounced value.
598 // 0 = Flag is not set
599 // 1 = Flag is set
600 FIELD(val0, CDTOGGLE, 0x01, 0x01)
601 // This bit is latched when the POR bit in Battery Status is asserted.
602 // 0 = Flag is not set
603 // 1 = Flag is set
604 FIELD(val0, POR, 0x00, 0x01)
605
606 // This bit is latched when a bit in Safety Status B() is set, and the bit is included in the mask. The bit is
607 // cleared when written with a "1". A bit set here causes the ALERT pin to be asserted low.
608 // 0 = Flag is not set
609 // 1 = Flag is set
610 FIELD(val1, SSB, 0x06, 0x01)
611 // This bit is latched when a bit in Safety Alert A() is set, and the bit is included in the mask. The bit is
612 // cleared when written with a "1". A bit set here causes the ALERT pin to be asserted low.
613 // 0 = Flag is not set
614 // 1 = Flag is set
615 FIELD(val1, SAA, 0x05, 0x01)
616 // This bit is latched when a bit in Safety Alert B() is set, and the bit is included in the mask. The bit is
617 // cleared when written with a "1". A bit set here causes the ALERT pin to be asserted low.
618 // 0 = Flag is not set
619 // 1 = Flag is set
620 FIELD(val1, SAB, 0x04, 0x01)
621 // This bit is latched when the CHG driver is disabled, and the bit is included in the mask. The bit is cleared
622 // when written with a "1". A bit set here causes the ALERT pin to be asserted low.
623 // 0 = Flag is not set
624 // 1 = Flag is set
625 FIELD(val1, XCHG, 0x03, 0x01)
626 // This bit is latched when the DSG driver is disabled, and the bit is included in the mask. The bit is cleared
627 // when written with a "1". A bit set here causes the ALERT pin to be asserted low.
628 // 0 = Flag is not set
629 // 1 = Flag is set
630 FIELD(val1, XDSG, 0x02, 0x01)
631 // This bit is latched when either a cell voltage has been measured below Shutdown Cell Voltage, or the stack
632 // voltage has been measured below Shutdown Stack Voltage. The bit is cleared when written with a "1". A bit set
633 // here causes the ALERT pin to be asserted low.
634 // 0 = Flag is not set
635 // 1 = Flag is set
636 FIELD(val1, SHUTV, 0x01, 0x01)
637 // This bit is latched when cell balancing is active, and the bit is included in the mask. The bit is cleared when
638 // written with a "1". A bit set here causes the ALERT pin to be asserted low.
639 // 0 = Flag is not set
640 // 1 = Flag is set
641 FIELD(val1, CB, 0x00, 0x01)
642 } alarmStatus;
643
644 // Unlatched value of flags which can be selected to be latched (using Alarm Enable()) and used to assert the ALERT
645 // pin.
647 {
648 uint8_t addr = ALARM_RAW_STATUS_ADDR;
649 byte val0 = 0x00;
650 byte val1 = 0x00;
651
652 // This bit pulses high briefly when a full scan is complete (including cell voltages, top-of-stack voltage,
653 // temperature, and diagnostic measurements).
654 FIELD_RO(val0, FULLSCAN, 0x07, 0x01)
655 // This bit pulses high briefly when a voltage ADC measurement scan is complete (this includes the cell voltage
656 // measurements and one additional measurement).
657 FIELD_RO(val0, ADSCAN, 0x06, 0x01)
658 // This bit pulses high briefly when the device is wakened from SLEEP mode.
659 FIELD_RO(val0, WAKE, 0x05, 0x01)
660 // This bit pulses high briefly when the device enters SLEEP mode.
661 // 0 = Flag is not set
662 // 1 = Flag is set
663 FIELD_RO(val0, SLEEP, 0x04, 0x01)
664 // This bit pulses high briefly when the programmable timer expires.
665 FIELD_RO(val0, TIMER_ALARM, 0x03, 0x01)
666 // This bit pulses high briefly when the device has completed the startup measurement sequence (after powerup or
667 // reset or exit of CONFIG_UPDATE mode or exit of DEEPSLEEP).
668 FIELD_RO(val0, INITCOMP, 0x02, 0x01)
669 // This bit is set when the CHG Detector output is set, indicating that the CHG pin has been detected above a
670 // level of approximately 2 V.
671 // 0 = CHG Detector output is not set
672 // 1 = CHG Detector output is set
673 FIELD_RO(val0, CDRAW, 0x01, 0x01)
674 // This bit is set if the POR bit in Battery Status is asserted.
675 // 0 = Flag is not set
676 // 1 = Flag is set
677 FIELD_RO(val0, POR, 0x00, 0x01)
678
679 // This bit is set when a bit in Safety Status A() is set.
680 // 0 = Flag is not set
681 // 1 = Flag is set
682 FIELD_RO(val1, SSA, 0x07, 0x01)
683 // This bit is set when a bit in Safety Status B() is set.
684 // 0 = Flag is not set
685 // 1 = Flag is set
686 FIELD_RO(val1, SSB, 0x06, 0x01)
687 // This bit is set when a bit in Safety Alert A() is set.
688 // 0 = Flag is not set
689 // 1 = Flag is set
690 FIELD_RO(val1, SAA, 0x05, 0x01)
691 // This bit is set when a bit in Safety Alert B() is set.
692 // 0 = Flag is not set
693 // 1 = Flag is set
694 FIELD_RO(val1, SAB, 0x04, 0x01)
695 // This bit is set when the CHG driver is disabled.
696 // 0 = Flag is not set
697 // 1 = Flag is set
698 FIELD_RO(val1, XCHG, 0x03, 0x01)
699 // This bit is set when the DSG driver is disabled.
700 // 0 = Flag is not set
701 // 1 = Flag is set
702 FIELD_RO(val1, XDSG, 0x02, 0x01)
703 // This bit is set when either a cell voltage has been measured below Shutdown Cell Voltage, or the stack voltage
704 // has been measured below Shutdown Stack Voltage. The bit is cleared when written with a "1". A bit set here
705 // causes the ALERT pin to be asserted low.
706 // 0 = Flag is not set
707 // 1 = Flag is set
708 FIELD_RO(val1, SHUTV, 0x01, 0x01)
709 // This bit is set when cell balancing is active.
710 // 0 = Flag is not set
711 // 1 = Flag is set
712 FIELD_RO(val1, CB, 0x00, 0x01)
713
714 } alarmRawStatus;
715
716 // Mask for Alarm Status(). Can be written to change during operation to change which alarm sources are enabled. The
717 // default value of this parameter is set by Settings:Configuration:Default Alarm Mask
719 {
720 uint8_t addr = ALARM_ENABLE_ADDR;
721 byte val0 = 0x00;
722 byte val1 = 0x00;
723
724 // Setting this bit allows the corresponding bit in Alarm Raw Status() to be mapped to the corresponding bit in
725 // Alarm Status() and to control the ALERT pin.
726 // 0 = This bit in Alarm Raw Status() is not included in Alarm Status()
727 // 1 = This bit in Alarm Raw Status() is included in Alarm Status()
728 FIELD(val0, FULLSCAN, 0x07, 0x01)
729 // Setting this bit allows the corresponding bit in Alarm Raw Status() to be mapped to the corresponding bit in
730 // Alarm Status() and to control the ALERT pin.
731 // 0 = This bit in Alarm Raw Status() is not included in Alarm Status()
732 // 1 = This bit in Alarm Raw Status() is included in Alarm Status()
733 FIELD(val0, ADSCAN, 0x06, 0x01)
734 // Setting this bit allows the corresponding bit in Alarm Raw Status() to be mapped to the corresponding bit in
735 // Alarm Status() and to control the ALERT pin.
736 // 0 = This bit in Alarm Raw Status() is not included in Alarm Status()
737 // 1 = This bit in Alarm Raw Status() is included in Alarm Status()
738 FIELD(val0, WAKE, 0x05, 0x01)
739 // Setting this bit allows the corresponding bit in Alarm Raw Status() to be mapped to the corresponding bit in
740 // Alarm Status() and to control the ALERT pin.
741 // 0 = This bit in Alarm Raw Status() is not included in Alarm Status()
742 // 1 = This bit in Alarm Raw Status() is included in Alarm Status()
743 FIELD(val0, SLEEP, 0x04, 0x01)
744 // Setting this bit allows the corresponding bit in Alarm Raw Status() to be mapped to the corresponding bit in
745 // Alarm Status() and to control the ALERT pin.
746 // 0 = This bit in Alarm Raw Status() is not included in Alarm Status()
747 // 1 = This bit in Alarm Raw Status() is included in Alarm Status()
748 FIELD(val0, TIMER_ALARM, 0x03, 0x01)
749 // Setting this bit allows the corresponding bit in Alarm Raw Status() to be mapped to the corresponding bit in
750 // Alarm Status() and to control the ALERT pin.
751 // 0 = This bit in Alarm Raw Status() is not included in Alarm Status()
752 // 1 = This bit in Alarm Raw Status() is included in Alarm Status()
753 FIELD(val0, INITCOMP, 0x02, 0x01)
754 // Setting this bit allows the internally determined value of CDTOGGLE to be mapped to the corresponding bit in
755 // Alarm Status() and to control the ALERT pin.
756 // This flag is set whenever the debounced CHG Detector signal differs from the previous debounced value.
757 // 0 = The CDTOGGLE signal is not included in Alarm Status()
758 // 1 = The CDTOGGLE signal is included in Alarm Status()
759 FIELD(val0, CDTOGGLE, 0x01, 0x01)
760 // Setting this bit allows the corresponding bit in Alarm Raw Status() to be mapped to the corresponding bit in
761 // Alarm Status() and to control the ALERT pin.
762 // 0 = This bit in Alarm Raw Status() is not included in Alarm Status()
763 // 1 = This bit in Alarm Raw Status() is included in Alarm Status()
764 FIELD(val0, POR, 0x00, 0x01)
765
766 // Setting this bit allows the corresponding bit in Alarm Raw Status() to be mapped to the corresponding bit in
767 // Alarm Status() and to control the ALERT pin.
768 // 0 = This bit in Alarm Raw Status() is not included in Alarm Status()
769 // 1 = This bit in Alarm Raw Status() is included in Alarm Status()
770 FIELD(val1, SSA, 0x07, 0x01)
771 // Setting this bit allows the corresponding bit in Alarm Raw Status() to be mapped to the corresponding bit in
772 // Alarm Status() and to control the ALERT pin.
773 // 0 = This bit in Alarm Raw Status() is not included in Alarm Status()
774 // 1 = This bit in Alarm Raw Status() is included in Alarm Status()
775 FIELD(val1, SSB, 0x06, 0x01)
776 // Setting this bit allows the corresponding bit in Alarm Raw Status() to be mapped to the corresponding bit in
777 // Alarm Status() and to control the ALERT pin.
778 // 0 = This bit in Alarm Raw Status() is not included in Alarm Status()
779 // 1 = This bit in Alarm Raw Status() is included in Alarm Status()
780 FIELD(val1, SAA, 0x05, 0x01)
781 // Setting this bit allows the corresponding bit in Alarm Raw Status() to be mapped to the corresponding bit in
782 // Alarm Status() and to control the ALERT pin.
783 // 0 = This bit in Alarm Raw Status() is not included in Alarm Status()
784 // 1 = This bit in Alarm Raw Status() is included in Alarm Status()
785 FIELD(val1, SAB, 0x04, 0x01)
786 // Setting this bit allows the corresponding bit in Alarm Raw Status() to be mapped to the corresponding bit in
787 // Alarm Status() and to control the ALERT pin.
788 // 0 = This bit in Alarm Raw Status() is not included in Alarm Status()
789 // 1 = This bit in Alarm Raw Status() is included in Alarm Status()
790 FIELD(val1, XCHG, 0x03, 0x01)
791 // Setting this bit allows the corresponding bit in Alarm Raw Status() to be mapped to the corresponding bit in
792 // Alarm Status() and to control the ALERT pin.
793 // 0 = This bit in Alarm Raw Status() is not included in Alarm Status()
794 // 1 = This bit in Alarm Raw Status() is included in Alarm Status()
795 FIELD(val1, XDSG, 0x02, 0x01)
796 // Setting this bit allows the corresponding bit in Alarm Raw Status() to be mapped to the corresponding bit in
797 // Alarm Status() and to control the ALERT pin.
798 // 0 = This bit in Alarm Raw Status() is not included in Alarm Status()
799 // 1 = This bit in Alarm Raw Status() is included in Alarm Status()
800 FIELD(val1, SHUTV, 0x01, 0x01)
801 // Setting this bit allows the corresponding bit in Alarm Raw Status() to be mapped to the corresponding bit in
802 // Alarm Status() and to control the ALERT pin.
803 // 0 = This bit in Alarm Raw Status() is not included in Alarm Status()
804 // 1 = This bit in Alarm Raw Status() is included in Alarm Status()
805 FIELD(val1, CB, 0x00, 0x01)
806 } alarmEnable;
807
808 // FET Control: Allows host control of individual FET drivers.
810 {
811 uint8_t addr = FET_CONTROL_ADDR;
812 byte val0 = 0x00;
813
814 // CHG FET driver control. This bit only operates if the HOST_FETOFF_EN bit in data memory is set.
815 // 0 = CHG FET driver is allowed to turn on if other conditions are met.
816 // 1 = CHG FET driver is forced off.
817 FIELD(val0, CHG_OFF, 0x03, 0x01)
818 // DSG FET driver control. This bit only operates if the HOST_FETOFF_EN bit in data memory is set.
819 // 0 = DSG FET driver is allowed to turn on if other conditions are met.
820 // 1 = DSG FET driver is forced off.
821 FIELD(val0, DSG_OFF, 0x02, 0x01)
822 // CHG FET driver control. This bit only operates if the HOST_FETON_EN bit in data memory is set.
823 // 0 = CHG FET driver is allowed to turn on if other conditions are met.
824 // 1 = CHG FET driver is forced on
825 FIELD(val0, CHG_ON, 0x01, 0x01)
826 // DSG FET driver control. This bit only operates if the HOST_FETON_EN bit in data memory is set.
827 // 0 = DSG FET driver is allowed to turn on if other conditions are met.
828 // 1 = DSG FET driver is forced on.
829 FIELD(val0, DSG_ON, 0x00, 0x01)
830 } fetControl;
831
832 // REGOUT Control: Changes voltage regulator settings.
834 {
835 uint8_t addr = REGOUT_CONTROL_ADDR;
836 byte val0 = 0x00;
837 byte val1 = 0x00;
838
839 // Control for TS pullup to stay biased continuously.
840 // 0 = TS pullup resistor is not continuously connected.
841 // 1 = TS pullup resistor is continuously connected.
842 FIELD(val0, TS_ON, 0x04, 0x01)
843 // REGOUT LDO enable.
844 // 0 = REGOUT LDO is disabled
845 // 1 = REGOUT LDO is enabled
846 FIELD(val0, REG_EN, 0x03, 0x01)
847 // REGOUT LDO voltage control.
848 // 0 = REGOUT LDO is set to 1.8V
849 // 1 = REGOUT LDO is set to 1.8V
850 // 2 = REGOUT LDO is set to 1.8V
851 // 3 = REGOUT LDO is set to 1.8V
852 // 4 = REGOUT LDO is set to 2.5 V
853 // 5 = REGOUT LDO is set to 3.0 V
854 // 6 = REGOUT LDO is set to 3.3 V
855 // 7 = REGOUT LDO is set to 5 V
856 FIELD(val0, REGOUTV, 0x00, 0x03)
857
858 } regoutControl;
859
860 // Controls the PWM mode of the DSG FET driver. Values are not used until the second byte is written.
862 {
863 uint8_t addr = DSG_FET_DRIVER_PWM_CONTROL_ADDR;
864 byte val0 = 0x00;
865 byte val1 = 0x00;
866
867 // Time the DSG FET driver is disabled each cycle when PWM mode is enabled.
868 // Settings from 122.1 μs to 31.128 ms in steps of 122.1 μs
869 // A setting of 0 disables PWM mode, such that this command has no effect
870 FIELD(val0, DSGPWMOFF, 0x00, 0x08)
871
872 // DSG FET driver PWM mode control
873 // 0 = DSG FET driver PWM mode is disabled
874 // 1 = DSG FET driver PWM mode is enabled
875 FIELD(val1, DSGPWMEN, 0x07, 0x01)
876 // Time the DSG FET driver is enabled when PWM mode is enabled.
877 // Settings from 30.52 μs to 3.876 ms in steps of 30.52 μs
878 // A setting of 0 disables PWM mode, such that this command has no effect
879 FIELD(val1, DSGPWMON, 0x00, 0x07)
880 } dsgFetDriverPwmControl;
881
882 // Controls the PWM mode of the CHG FET driver. Values are not used until the second byte is written.
884 {
885 uint8_t addr = CHG_FET_DRIVER_PWM_CONTROL_ADDR;
886 byte val0 = 0x00;
887 byte val1 = 0x00;
888
889 // Time the CHG FET driver is disabled each cycle when PWM mode is enabled.
890 // Settings from 488.4 μs to 124.512 ms in steps of 488.4 μs
891 // A setting of 0 disables PWM mode, such that this command has no effect.
892 FIELD(val0, CHGPWMOFF, 0x00, 0x08)
893
894 // CHG FET driver PWM mode control
895 // 0 = CHG FET driver PWM mode is disabled
896 // 1 = CHG FET driver PWM mode is enabled
897 FIELD(val1, DSGPWMEN, 0x07, 0x01)
898 // Time the CHG FET driver is enabled when PWM mode is enabled.
899 // Settings from 30.52 μs to 3.876 ms in steps of 30.52 μs
900 // A setting of 0 disables PWM mode, such that this command has no effect.
901 FIELD(val1, CHGPWMON, 0x00, 0x07)
902 } chFetDriverPwmControl;
903
904 // 16-bit voltage on cell 1 (mV)
906 {
907 uint16_t address() const override { return CELL_1_VOLTAGE_ADDR; };
908 } cell1Voltage;
909
910 // 16-bit voltage on cell 2 (mV)
912 {
913 uint16_t address() const override { return CELL_2_VOLTAGE_ADDR; };
914 } cell2Voltage;
915
916 // 16-bit voltage on cell 3 (mV)
918 {
919 uint16_t address() const override { return CELL_3_VOLTAGE_ADDR; };
920 } cell3Voltage;
921
922 // 16-bit voltage on cell 4 (mV)
924 {
925 uint16_t address() const override { return CELL_4_VOLTAGE_ADDR; };
926 } cell4Voltage;
927
928 // 16-bit voltage on cell 5 (mV)
930 {
931 uint16_t address() const override { return CELL_5_VOLTAGE_ADDR; };
932 } cell5Voltage;
933
934 // Internal 1.8V regulator voltage measured using bandgap reference, used for diagnostic of VREF1 vs VREF2.
936 {
937 uint16_t address() const override { return REG_18_VOLTAGE_ADDR; };
938 } reg18Voltage;
939
940 // Measurement of VSS using ADC, used for diagnostic of ADC input mux (mV)
942 {
943 uint16_t address() const override { return VSS_VOLTAGE_ADDR; };
944 } VSSVoltage;
945
946 // 16-bit voltage on top of stack (mV)
948 {
949 uint16_t address() const override { return STACK_VOLTAGE_ADDR; };
950 } stackVoltage;
951
952 // This is the most recent measured internal die temperature (degrees).
954 {
955 uint16_t address() const override { return INT_TEMPERATURE_ADDR; };
956 } intTemperatureVoltage;
957
958 // ADC measurement of the TS pin
960 {
961 uint16_t address() const override { return TS_MEASURMENT_ADDR; };
962 } tsMeasurmentVoltage;
963
970 // The DEVICE_NUMBER subcommand reports the device number that identifies the product. The data is returned in
971 // little-endian format
973 {
974 uint16_t command_address() const override { return SUBCOMMAND_DEVICE_NUMBER_ADDR; }
975
976 uint16_t get()
977 {
978 raw_read();
979 const uint16_t number = get_read_results() & UINT16_MAX;
980 return number;
981 }
982 } deviceNumber;
983
984 // The FW_VERSION subcommand returns three 16-bit word values.
986 {
987 uint16_t command_address() const override { return SUBCOMMAND_FW_VERSION_ADDR; }
988
989 // Bytes 0-1: Device Number (Big-Endian): Device number in big-endian format for compatibility with legacy
990 // products.
991 uint16_t get_device_number()
992 {
993 raw_read_big_endian();
994 // first two bytes
995 const uint16_t number = get_read_results() & UINT16_MAX;
996 return number;
997 }
998
999 // Bytes 3-2: Firmware Version (Big-Endian): Device firmware major and minor version number (Big-Endian).
1000 uint16_t get_firmware_version()
1001 {
1002 raw_read_big_endian();
1003 // first two bytes
1004 const uint16_t number = (get_read_results() >> 16) & UINT16_MAX;
1005 return number;
1006 }
1007
1008 // not supported yet
1009 // Bytes 5-4: Build Number (Big-Endian): Firmware build number in big-endian, binary coded decimal format for
1010 // compatibility with legacy products. uint16_t get_build_number();
1011 } firmwareVersion;
1012
1013 // Hardware Version: Reports the device hardware version number
1015 {
1016 uint16_t command_address() const override { return SUBCOMMAND_HW_VERSION_ADDR; }
1017
1018 uint16_t get()
1019 {
1020 raw_read();
1021 const uint16_t number = get_read_results() & UINT16_MAX;
1022 return number;
1023 }
1024 } hardwareVersion;
1025
1027 {
1028 uint16_t command_address() const override { return SUBCOMMAND_PASSQ_ADDR; }
1029
1030 // Accumulated charge lower 32-bits (little-endian byte-by-byte). Lower 32 bits of signed 48-bit result, with the
1031 // full 48-bit field having units of userA- seconds
1032 uint32_t get_PassQLsb()
1033 {
1034 raw_read();
1035 const uint32_t number = get_read_results() & UINT32_MAX;
1036 return number;
1037 }
1038
1039 // Accumulated charge upper 16-bits sign-extended to a 32-bit field (little-endian byte-by-byte). Upper bits of
1040 // signed 48-bit result, with the full 48-bit field having units of userA-seconds.
1041 // not supported
1042 /*
1043 uint16_t get_PassQMsb()
1044 {
1045 raw_read();
1046 const uint16_t number = (get_read_results() >> 32) & UINT16_MAX;
1047 return number;
1048 }
1049 */
1050
1051 // Accumulated Time (little-endian byte-by-byte), 32-bit unsigned integer in units of 250 ms.
1052 // not supported
1053 /*
1054 uint32_t get_PassTime()
1055 {
1056 raw_read();
1057 const uint32_t number = (get_read_results() >> 48) & UINT32_MAX;
1058 return number;
1059 }
1060 */
1061 } passQ;
1062
1063 // This command resets the accumulated charge and timer
1065 {
1066 uint16_t command_address() const override { return SUBCOMMAND_RESET_PASSQ_ADDR; }
1067
1068 void send() { raw_send(); }
1069 } resetPassQ;
1070
1071 // This command is sent to exit DEEPSLEEP mode.
1073 {
1074 uint16_t command_address() const override { return SUBCOMMAND_EXIT_DEEPSLEEP_ADDR; }
1075
1076 void send() { raw_send(); }
1077 } exitDeepSleep;
1078
1079 // This command is sent to enter DEEPSLEEP mode. Must be sent twice in a row within 4s to take effect
1081 {
1082 uint16_t command_address() const override { return SUBCOMMAND_DEEPSLEEP_ADDR; }
1083
1084 void send() { raw_send(); }
1085 } deepSleep;
1086
1087 // This command is sent to start SHUTDOWN sequence. Must be sent twice in a row within 4s to take effect. If sent a
1088 // third time, the shutdown delay is skipped
1089 /* DO NOT USE, no way to wake up without disconecting the battery
1090 struct Shutdownt : public ISubcommandRegister
1091 {
1092 uint16_t command_address() const override { return SUBCOMMAND_SHUTDOWN_ADDR; }
1093
1094 void send() { raw_send(); }
1095 } Shutdown;
1096 */
1097
1098 // This command is sent to reset the device
1100 {
1101 uint16_t command_address() const override { return SUBCOMMAND_RESET_ADDR; }
1102
1103 void send() { raw_send(); }
1104 } reset;
1105
1106 // This command is sent to toggle the FET_EN bit in Battery Status(). FET_EN=0 means manual FET control. FET_EN=1
1107 // means autonomous device FET control
1109 {
1110 uint16_t command_address() const override { return SUBCOMMAND_FET_ENABLE_ADDR; }
1111
1112 void send() { raw_send(); }
1113 } fetEnable;
1114
1115 // This command is sent to place the device in SEALED mode
1117 {
1118 uint16_t command_address() const override { return SUBCOMMAND_SEAL_ADDR; }
1119
1120 void send() { raw_send(); }
1121 } seal;
1122
1123 // WRITE ONLY
1125 {
1126 uint16_t command_address() const override { return SUBCOMMAND_SECURITY_KEYS_ADDR; }
1127
1128 // Full Access Key Step 1:
1129 // This is the first word of the security key that must be sent to transition from SEALED to FULLACCESS mode.
1130 // Do not choose a word identical to a subcommand address.
1131 // Full Access Key Step 2:
1132 // This is the second word of the security key that must be sent to transition from SEALED to FULLACCESS mode.
1133 // Do not choose a word identical to a subcommand address or the same as the first word. It must be sent within 5
1134 // seconds of the first word of the key and with no other commands in between.
1135 void send(const uint16_t FaKey1, const uint16_t FaKey2)
1136 {
1137 uint8_t data[4];
1138 data[0] = FaKey1 | UINT8_MAX;
1139 data[1] = (FaKey1 >> 8) | UINT8_MAX;
1140 data[2] = FaKey2 | UINT8_MAX;
1141 data[3] = (FaKey2 >> 8) | UINT8_MAX;
1142
1143 // TODO
1144 // raw_write(4, data);
1145 }
1146 } securityKeys;
1147
1148 // Cell balancing active cells: When read, reports a bit mask of which cells are being actively balanced.
1149 // When written, starts balancing on the specified cells.
1150 // Write 0x00 to disable balancing
1152 {
1153 uint16_t command_address() const override { return SUBCOMMAND_CB_ACTIVE_CELLS_ADDR; }
1154
1155 uint8_t val0;
1156
1157 void read_reg()
1158 {
1159 raw_read();
1160 val0 = valBytes[0];
1161 }
1162
1163 void write() { raw_write8(val0); }
1164
1165 // Cell balancing active cells: When read, reports a bit mask of which cells are being actively balanced. When
1166 // written, starts balancing on the specified cells.
1167 // Write 0x00 to turn balancing off.
1168 // Bit 7 is reserved, read/write 0 to this bit
1169 // Bit 6 is reserved, read/write 0 to this bit
1170 // Bit 5 corresponds to the fifth active cell
1171 FIELD(val0, CBCELLS_4, 0x05, 0x01);
1172 // Bit 4 corresponds to the fourth active cell
1173 FIELD(val0, CBCELLS_3, 0x04, 0x01);
1174 // Bit 3 corresponds to the third active cell
1175 FIELD(val0, CBCELLS_2, 0x03, 0x01);
1176 // Bit 2 corresponds to the second active cell
1177 FIELD(val0, CBCELLS_1, 0x02, 0x01);
1178 // Bit 1 corresponds to the first active cell (connected between VC1 and VC0)
1179 FIELD(val0, CBCELLS_0, 0x01, 0x01);
1180 // Bit 0 is reserved, read/write 0 to this bit
1181
1182 } cbActiveCells;
1183
1184 // This command is sent to place the device in CONFIG_UPDATE mode
1186 {
1187 uint16_t command_address() const override { return SUBCOMMAND_SET_CFGUPDATE_ADDR; }
1188
1189 void send() { raw_send(); }
1190 } setCfgUpdate;
1191
1192 // This command is sent to exit CONFIG_UPDATE mode
1194 {
1195 uint16_t command_address() const override { return SUBCOMMAND_EXIT_CFGUPDATE_ADDR; }
1196
1197 void send() { raw_send(); }
1198 } exitCfgUpdate;
1199
1200 // Programmable timer, which allows the REGOUT LDO to be disabled and wakened after a programmed time or by alarm
1202 {
1203 uint16_t command_address() const override { return SUBCOMMAND_PROG_TIMER_ADDR; }
1204
1205 // Control to determine if REGOUT is wakened when an Alarm Status() bit asserts.
1206 // 0 = Do not re-enable the REGOUT LDO if any bit in Alarm Status() asserts while the timer is running
1207 // (default).
1208 // 1 = If [REGOUT_SD]=1 and any bit in Alarm Status() asserts while the timer is running, reenable the
1209 // REGOUT LDO
1210 // based on the setting of REGOUT Control()
1211 FIELD(val1, REGOUT_ALARM_WK, 0x03, 0x02);
1212
1213 // Delay before REGOUT is disabled when the timer is initiated while REGOUT is powered, and [REGOUT_SD]=1.
1214 // 0 = Zero delay (default).
1215 // 1 = 250ms delay.
1216 // 2 = 1-sec delay.
1217 // 3 = 4-sec delay
1218 FIELD(val1, REGOUT_SD_DLY, 0x01, 0x02)
1219
1220 // Control to determine if REGOUT is disabled when the command is sent.
1221 // 0 = do not disable the REGOUT LDO when command is sent (default).
1222 // 1 = disable the REGOUT LDO when the timer is initiated, after delay of
1223 // [REGOUT_SD_DLY]. When the timer expires, re-enable the REGOUT LDO based on the status of REGOUT
1224 // Control().
1225 FIELD(val1, REGOUT_SD, 0x00, 0x01)
1226
1227 // Timer value programmable from 250 ms to 4 seconds in 250 ms increments (settings 1 to 16), and from 5
1228 // seconds to 243 seconds in 1 second increments (settings 17 to 255). A setting of zero disables the
1229 // timer. Whenever this field is written with a non-zero value, it initiates the timer
1230 FIELD(val0, PROG_TMR, 0x00, 0x08)
1231
1232 } progTimer;
1233
1234 // This command is sent to allow the device to enter SLEEP mode
1236 {
1237 uint16_t command_address() const override { return SUBCOMMAND_SLEEP_ENABLE_ADDR; }
1238
1239 void send() { raw_send(); }
1240 } sleepEnable;
1241
1242 // This command is sent to block the device from entering SLEEP mode
1244 {
1245 uint16_t command_address() const override { return SUBCOMMAND_SLEEP_DISABLE_ADDR; }
1246
1247 void send() { raw_send(); }
1248 } sleepDisable;
1249
1250 // This command enables the host to allow recovery of selected protection faults
1252 {
1253 uint8_t val0;
1254
1255 void read_reg()
1256 {
1257 raw_read();
1258 val0 = valBytes[0];
1259 }
1260
1261 void write() { raw_write8(val0); }
1262
1263 uint16_t command_address() const override { return SUBCOMMAND_PROT_RECOVERY_ADDR; }
1264
1265 // Cell Overvoltage or Cell Undervoltage fault recovery
1266 // 0 = Recovery of an COV/CUV fault is not triggered
1267 // 1 = Recovery of an COV/CUV fault is triggered.
1268 FIELD(val0, VOLTREC, 0x07, 0x01);
1269
1270 // Recovery for a VSS or VREF fault from Safety Status B()
1271 // 0 = Recovery of a VSS or VREF fault is not triggered
1272 // 1 = Recovery of a VSS or VREF fault is triggered
1273 FIELD(val0, DIAGREC, 0x06, 0x01);
1274
1275 // Short Circuit in Discharge fault recovery
1276 // 0 = Recovery of an SCD fault is not triggered
1277 // 1 = Recovery of an SCD fault is triggered
1278 FIELD(val0, SCDREC, 0x05, 0x01);
1279
1280 // Overcurrent in Discharge 1 fault recovery
1281 // 0 = Recovery of an OCD1 fault is not triggered
1282 // 1 = Recovery of an OCD1 fault is triggered
1283 FIELD(val0, OCD1REC, 0x04, 0x01);
1284
1285 // Overcurrent in Discharge 2 fault recovery
1286 // 0 = Recovery of an OCD2 fault is not triggered
1287 // 1 = Recovery of an OCD2 fault is triggered.
1288 FIELD(val0, OCD2REC, 0x03, 0x01);
1289
1290 // Overcurrent in Charge fault recovery
1291 // 0 = Recovery of an OCC fault is not triggered
1292 // 1 = Recovery of an OCC fault is triggered.
1293 FIELD(val0, OCCREC, 0x02, 0x01);
1294
1295 // Temperature fault recovery
1296 // 0 = Recovery of a temperature fault is not triggered
1297 // 1 = Recovery of a temperature fault is triggered.
1298 FIELD(val0, TEMPREC, 0x01, 0x01);
1299 } protRecovery;
1300
1302 {
1303 uint16_t command_address() const override { return SUBCOMMAND_CONFIGURATION_DA_ADDR; }
1304
1305 // This bit controls whether the TS pin is used for external thermistor measurement or as a general purpose ADC
1306 // input.
1307 // 0 = TS pin is used for external thermistor measurement, with the internal pullup resistor enabled during
1308 // measurement, and the ADC used in ratiometric mode, using the internal REG18 LDO voltage for the pullup
1309 // resistor bias and for the ADC reference.
1310 // 1 = TS pin is used for general purpose ADC voltage measurement, with the internal pullup resistor disabled
1311 // during measurement, and the ADC using the internal bandgap for its reference.
1312 FIELD(val1, TSMODE, 0x00, 0x01);
1313
1314 // Selects coulomb counter mode. Note that CC1 Current() and accumulated charge integration only operates in modes
1315 // where the coulomb counter is running continuously (0x00 NORMAL mode, or 0x01 NORMAL mode while no idle slots
1316 // are being introduced, or 0x02 NORMAL mode)
1317 FIELD(val0, CCMODE, 0x06, 0x02);
1318
1319 // Selects ADC conversion speed for cell voltage measurements. Higher speed results in higher noise in
1320 // conversions.
1321 // 0 = 2.93 ms per conversion (default)
1322 // 1 = 1.46 ms per conversion
1323 // 2 = 732 μs per conversion
1324 // 3 = 366 μs per conversion
1325 FIELD(val0, CVADCSPEED, 0x04, 0x02);
1326
1327 // Selects ADC conversion speed for current measurements. Higher speed results in higher noise in conversions.
1328 // 0 = 2.93 ms per conversion (default)
1329 // 1 = 1.46 ms per conversion
1330 // 2 = 732 μs per conversion
1331 // 3 = 366 μs per conversion
1332 FIELD(val0, IADCSPEED, 0x02, 0x02);
1333
1334 // Selects ADC conversion speed for Shared Slot measurements. Higher speed results in higher noise in conversions.
1335 // 0 = 2.93 ms per conversion (default)
1336 // 1 = 1.46 ms per conversion
1337 // 2 = 732 μs per conversion
1338 // 3 = 366 μs per conversion
1339 FIELD(val0, SSADCSPEED, 0x00, 0x02);
1340
1341 } settingConfiguration_DA;
1342
1343 // Not every system uses all of the cell input pins. If the system has fewer cells than the device supports, some VC
1344 // input pins must be shorted together. To prevent action being taken for cell undervoltage conditions on pins that
1345 // are shorted, set these bits appropriately.
1346 // 0 = All cell inputs are used for actual cells.
1347 // 1 = All cell inputs are used for actual cells.
1348 // 2 = Two actual cells are in use (VC5-VC4A, VC1-VC0), unused cell pins can be shorted to an adjacent cell pin at
1349 // the device or connected through RC to the cells.
1350 // 3 = Three actual cells are in use (VC5-VC4A, VC2-VC1, VC1-VC0), unused cell pins can be shorted to an adjacent
1351 // cell pin at the device or connected through RC to the cells.
1352 // 4 = Four actual cells are in use (VC5-VC4A, VC4B-VC3A, VC2-VC1, VC1-VC0), unused cell pins can be shorted to an
1353 // adjacent cell pin at the device or connected through RC to the cells.
1354 // 5 = All cell inputs are used for actual cells.
1356 {
1357 uint16_t command_address() const override { return SUBCOMMAND_CONFIGURATION_VCELL_MODE_ADDR; }
1358
1359 uint8_t val0;
1360
1361 void read_reg()
1362 {
1363 raw_read();
1364 val0 = valBytes[0];
1365 }
1366
1367 void write() { raw_write8(val0); }
1368
1369 // Not every system uses all of the cell input pins. If the system has fewer cells than the device supports, some
1370 // VC input pins must be shorted together. To prevent action being taken for cell undervoltage conditions on pins
1371 // that are shorted, set these bits appropriately.
1372 // 0 = All cell inputs are used for actual cells.
1373 // 1 = All cell inputs are used for actual cells.
1374 // 2 = Two actual cells are in use (VC5-VC4A, VC1-VC0), unused cell pins can be shorted to an adjacent cell pin at
1375 // the device or connected through RC to the cells.
1376 // 3 = Three actual cells are in use (VC5-VC4A, VC2-VC1, VC1-VC0), unused cell pins can be shorted to an adjacent
1377 // cell pin at the device or connected through RC to the cells.
1378 // 4 = Four actual cells are in use (VC5-VC4A, VC4B-VC3A, VC2-VC1, VC1-VC0), unused cell pins can be shorted to an
1379 // adjacent cell pin at the device or connected through RC to the cells.
1380 // 5 = All cell inputs are used for actual cells.
1381 FIELD(val0, VCELL, 0x00, 0x03);
1382
1383 } configurateVcell;
1384
1386 {
1387 uint16_t command_address() const override { return SUBCOMMAND_CONFIGURATION_TS_OFFSET_ADDR; }
1388
1389 // signed to unsigned raw covertion
1390 void set(int16_t offset) { raw_write16((int16_t)offset); }
1391 } tsOffset;
1392 };
1393
1394private:
1395 static void delay_us(uint64_t dwUs)
1396 {
1397 // IMPLEMENT THIS FUNCTION
1399 }
1400
1401 static bool readDataReg(const byte regAddress, byte* dataVal, const uint8_t arrLen)
1402 {
1403 // IMPLEMENT THIS FUNCTION
1404 return ::lampda::platform::i2c::i2c_readData(
1405 i2cObjectIndex, BQ76905addr, regAddress, arrLen, dataVal, usesStopBit ? 1 : 0) == 0;
1406 }
1407
1408 static bool writeData(const byte regAddress, uint8_t lenght, uint8_t* data)
1409 {
1410 // IMPLEMENT THIS FUNCTION
1411 return ::lampda::platform::i2c::i2c_writeData(
1412 i2cObjectIndex, BQ76905addr, regAddress, lenght, data, usesStopBit ? 1 : 0) == 0;
1413 }
1414
1415 static bool writeData16(const byte regAddress, uint16_t val)
1416 {
1417 uint8_t data[2];
1418 data[0] = val & 0xFF;
1419 data[1] = (val >> 8) & 0xFF;
1420
1421 return writeData(regAddress, 2, data);
1422 }
1423};
1424
1425} // namespace bq76905
1426
1427#endif
Definition: BQ76905.h:118
void delay_us(uint64_t dwUs)
Pauses the program for the amount of time (in microseconds) specified as parameter.
Definition: time.cpp:24
Definition: BQ76905.h:173
Definition: BQ76905.h:199
Definition: BQ76905.h:719
Definition: BQ76905.h:558
Definition: BQ76905.h:1152
Definition: BQ76905.h:906
Definition: BQ76905.h:912
Definition: BQ76905.h:918
Definition: BQ76905.h:924
Definition: BQ76905.h:930
Definition: BQ76905.h:1081
Definition: BQ76905.h:973
Definition: BQ76905.h:1194
Definition: BQ76905.h:1073
Definition: BQ76905.h:810
Definition: BQ76905.h:1109
Definition: BQ76905.h:1027
Definition: BQ76905.h:1202
Definition: BQ76905.h:1252
Definition: BQ76905.h:936
Definition: BQ76905.h:1065
Definition: BQ76905.h:1100
Definition: BQ76905.h:340
Definition: BQ76905.h:407
Definition: BQ76905.h:1117
Definition: BQ76905.h:1125
Definition: BQ76905.h:1186
Definition: BQ76905.h:1244
Definition: BQ76905.h:1236
Definition: BQ76905.h:948
Definition: BQ76905.h:1386
Definition: BQ76905.h:942
Definition: BQ76905.h:336