| Linduino 1.3.0 Linear Technology Arduino-Compatible Demonstration Board

DC2515.ino
Go to the documentation of this file.
1 /*! Analog Devices DC2515 Demonstration Board.
2 * LTC6810: 6-Channel Battery Stack Monitors
3 *
4 *@verbatim
5 *NOTES
6 * Setup:
7 * Set the terminal baud rate to 115200 and select the newline terminator.
8 * Ensure all jumpers on the demo board are installed in their default positions from the factory.
9 * Refer to Demo Manual.
10 *
11 *USER INPUT DATA FORMAT:
12 * decimal : 1024
13 * hex : 0x400
14 * octal : 02000 (leading 0)
15 * binary : B10000000000
16 * float : 1024.0
17 *@endverbatim
18 *
19 * https://www.analog.com/en/products/ltc6810-1.html
20 *
21 *********************************************************************************
22 * Copyright 2019(c) Analog Devices, Inc.
23 *
24 * All rights reserved.
25 *
26 * Redistribution and use in source and binary forms, with or without
27 * modification, are permitted provided that the following conditions are met:
28 * - Redistributions of source code must retain the above copyright
29 * notice, this list of conditions and the following disclaimer.
30 * - Redistributions in binary form must reproduce the above copyright
31 * notice, this list of conditions and the following disclaimer in
32 * the documentation and/or other materials provided with the
33 * distribution.
34 * - Neither the name of Analog Devices, Inc. nor the names of its
35 * contributors may be used to endorse or promote products derived
36 * from this software without specific prior written permission.
37 * - The use of this software may or may not infringe the patent rights
38 * of one or more patent holders. This license does not release you
39 * from the requirement that you obtain separate licenses from these
40 * patent holders to use this software.
41 * - Use of the software either in source or binary form, must be run
42 * on or directly connected to an Analog Devices Inc. component.
43 *
44 * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
45 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
46 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
47 * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
48 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
50 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
51 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
52 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 ********************************************************************************/
55
56 /*! @file
57 @ingroup LTC6810-1
58 */
59
60 /************************************* Read me *******************************************
61 In this sketch book:
62 -All Global Variables are in Upper casing
63 -All Local Variables are in lower casing
64 -The Function wakeup_sleep(TOTAL_IC) : is used to wake the LTC681x from sleep state.
65 It is defined in LTC681x.cpp
66 -The Function wakeup_idle(TOTAL_IC) : is used to wake the ICs connected in daisy chain
67 via the LTC6820 by initiating a dummy SPI communication. It is defined in LTC681x.cpp
68 *******************************************************************************************/
69
70 /************************* Includes ***************************/
71 #include <Arduino.h>
72 #include <stdint.h>
73 #include <SPI.h>
74 #include "Linduino.h"
75 #include "LT_SPI.h"
76 #include "UserInterface.h"
77 #include "LTC681x.h"
78 #include "LTC6810.h"
79
80 /************************* Defines *****************************/
81 #define ENABLED 1
82 #define DISABLED 0
83 #define DATALOG_ENABLED 1
84 #define DATALOG_DISABLED 0
85
86 /**************** Local Function Declaration *******************/
87 void measurement_loop(uint8_t datalog_en);
88 void print_menu(void);
89 void print_wrconfig(void);
90 void print_rxconfig(void);
91 void print_cells(uint8_t datalog_en);
92 void print_aux(uint8_t datalog_en);
93 void print_stat(void);
94 void print_sumofcells(void);
95 void print_svolt(uint8_t datalog_en);
96 void check_mux_fail(void);
97 void print_selftest_errors(uint8_t adc_reg ,int8_t error);
98 void print_digital_redundancy_errors(uint8_t adc_reg ,int8_t error);
99 void print_open_wires(void);
100 void print_pec_error_count(void);
101 int8_t select_s_pin(void);
102 void print_wrpwm(void);
103 void print_rxpwm(void);
104 void print_wrcomm(void);
105 void print_rxcomm(void);
106 void print_sid(void);
107 void reverse_isospi_direction(void);
108 void check_mute_bit(void);
109 void print_conv_time(uint32_t conv_time);
110 void check_error(int error);
111 void serial_print_text(char data[]);
112 void serial_print_hex(uint8_t data);
113 char read_hex(void);
114 char get_char(void);
115
116 /********************************************************************
117 Setup Variables
118 The following variables can be modified to configure the software.
119 *********************************************************************/
120 const uint8_t TOTAL_IC = 2;//!< Number of ICs in the daisy chain
121
122 //ADC Command Configurations. See LTC681x.h for options.
123 const uint8_t ADC_OPT = ADC_OPT_DISABLED; //!< ADC Mode option bit
124 const uint8_t ADC_CONVERSION_MODE = MD_7KHZ_3KHZ; //!< ADC Mode
125 const uint8_t ADC_DCP = DCP_DISABLED; //!< Discharge Permitted
126 const uint8_t CELL_CH_TO_CONVERT = CELL_CH_ALL; //!< Channel Selection for ADC conversion
127 const uint8_t AUX_CH_TO_CONVERT = AUX_CH_ALL; //!< Channel Selection for ADC conversion
128 const uint8_t STAT_CH_TO_CONVERT = STAT_CH_ALL; //!< Channel Selection for ADC conversion
129 const uint8_t SEL_ALL_REG = REG_ALL; //!< Register Selection
130 const uint8_t SEL_REG_A = REG_1; //!< Register Selection
131 const uint8_t SEL_REG_B = REG_2; //!< Register Selection
132
133 //Under Voltage and Over Voltage Thresholds
134 const uint16_t OV_THRESHOLD = 41000; //!< Over voltage threshold ADC Code. LSB = 0.0001 ---(4.1V)
135 const uint16_t UV_THRESHOLD = 30000; //!< Under voltage threshold ADC Code. LSB = 0.0001 ---(1V)
136
137 const uint16_t MEASUREMENT_LOOP_TIME = 500; //!< Loop Time in milliseconds(ms)
138
139 //Loop Measurement Setup. These Variables are ENABLED or DISABLED Remember ALL CAPS
140 const uint8_t WRITE_CONFIG = DISABLED; //!< This is to ENABLED or DISABLED writing into to configuration registers in a continuous loop
141 const uint8_t READ_CONFIG = DISABLED; //!< This is to ENABLED or DISABLED reading the configuration registers in a continuous loop
142 const uint8_t MEASURE_CELL = ENABLED; //!< This is to ENABLED or DISABLED measuring the cell voltages in a continuous loop
143 const uint8_t MEASURE_AUX = DISABLED; //!< This is to ENABLED or DISABLED reading the auxiliary registers in a continuous loop
144 const uint8_t MEASURE_STAT = DISABLED; //!< This is to ENABLED or DISABLED reading the status registers in a continuous loop
145 const uint8_t PRINT_PEC = DISABLED; //!< This is to ENABLED or DISABLED printing the PEC Error Count in a continuous loop
146 /************************************
147 END SETUP
148 *************************************/
149
150 /******************************************************
151 Global Battery Variables received from 681x commands
152 These variables store the results from the LTC6810
153 register reads and the array lengths must be based
154 on the number of ICs on the stack
155 ******************************************************/
156 cell_asic BMS_IC[TOTAL_IC];//!< Global Battery Variable
157
158 bool ISOSPI_DIR=BMS_IC[0].isospi_reverse;
159
160 /*************************************************************************
161 Set configuration register. Refer to the data sheet
162 **************************************************************************/
163 bool ADCOPT = false; //!< ADC Mode option bit
164 bool REFON = true; //!< Reference Powered Up Bit
165 bool GPIOBITS[4] = {false,true,true,true}; //!< GPIO Pin Control // Gpio 1,2,3,4
166 uint16_t UV=UV_THRESHOLD; //!< Under voltage Comparison Voltage
167 uint16_t OV=OV_THRESHOLD; //!< Over voltage Comparison Voltage
168 bool DCCBITS[6] = {false,false,false,false,false,false}; //!< Discharge cell switch //Dcc 1,2,3,4,5,6
169 bool DCCBIT_0= false; //!< Discharge cell switch //Dcc 0 // For discharging optional 7th cell
170 bool MCAL = false; //!< Enable Multi-Calibration
171 bool EN_DTMEN = true; //!< Enable Discharge timer monitor
172 bool DIS_RED = false; //!< Disable Digital Redundancy Check
173 bool FDRF = false; //!< Force digital Redundancy Failure
174 bool SCONV = true; //!< Enable Cell Measurement Redundancy using S Pin
175 bool DCTOBITS[4] = {true,false,true,false}; //!< Discharge Time Out Value //Dcto 0,1,2,3 // Programed for 4 min
176 /*Ensure that Dcto bits are set according to the required discharge time. Refer to the data sheet */
177
178 /*!**********************************************************************
179 \brief Initializes hardware and variables
180 @return void
181 ***********************************************************************/
182 void setup()
183 {
184 Serial.begin(115200);
185 quikeval_SPI_connect();
186 spi_enable(SPI_CLOCK_DIV16); // This will set the Linduino to have a 1MHz Clock
187 LTC6810_init_cfg(TOTAL_IC, BMS_IC);
188 for (uint8_t current_ic = 0; current_ic<TOTAL_IC; current_ic++)
189 {
190 LTC6810_set_cfgr(current_ic, BMS_IC, REFON, ADCOPT, GPIOBITS, DCCBITS, DCCBIT_0, MCAL, EN_DTMEN, DIS_RED, FDRF, SCONV, DCTOBITS, UV, OV);
191 }
192 LTC6810_reset_crc_count(TOTAL_IC,BMS_IC);
193 LTC6810_init_reg_limits(TOTAL_IC,BMS_IC);
194 print_menu();
195 }
196
197 /*!*********************************************************************
198 \brief main loop
199 @return void
200 ***********************************************************************/
201 void loop()
202 {
203 if (Serial.available()) // Check for user input
204 {
205 uint32_t user_command;
206 user_command = read_int(); // Read the user command
207 Serial.println(user_command);
208 run_command(user_command);
209 }
210 }
211
212 /*!*****************************************
213 \brief executes the user command
214 @return void
215 *******************************************/
216 void run_command(uint32_t cmd)
217 {
218 int8_t error = 0;
219 uint32_t conv_time = 0;
220 int8_t s_pin_read=0;
221
222 switch (cmd)
223 {
224 case 1: // Write and Read Configuration Register
225 wakeup_sleep(TOTAL_IC);
226 LTC6810_wrcfg(TOTAL_IC,BMS_IC); // Write into Configuration Register
227 print_wrconfig();
228 wakeup_idle(TOTAL_IC);
229 error = LTC6810_rdcfg(TOTAL_IC,BMS_IC); // Read Configuration Register
230 check_error(error);
231 print_rxconfig();
232 break;
233
234 case 2: // Read Configuration Register
235 wakeup_sleep(TOTAL_IC);
236 error = LTC6810_rdcfg(TOTAL_IC,BMS_IC);
237 check_error(error);
238 print_rxconfig();
239 break;
240
241 case 3: // Start Cell ADC Measurement
242 wakeup_sleep(TOTAL_IC);
243 LTC6810_adcv(ADC_CONVERSION_MODE,ADC_DCP,CELL_CH_TO_CONVERT);
244 conv_time = LTC6810_pollAdc();
245 print_conv_time(conv_time);
246 break;
247
248 case 4: // Read Cell Voltage Registers
249 wakeup_sleep(TOTAL_IC);
250 error = LTC6810_rdcv(SEL_ALL_REG,TOTAL_IC,BMS_IC); // Set to read back all cell voltage registers
251 check_error(error);
252 print_cells(DATALOG_DISABLED);
253 break;
254
255 case 5: // Start GPIO ADC Measurement
256 wakeup_sleep(TOTAL_IC);
257 LTC6810_adax(ADC_CONVERSION_MODE, AUX_CH_TO_CONVERT);
258 conv_time = LTC6810_pollAdc();
259 print_conv_time(conv_time);
260 break;
261
262 case 6: // Read AUX Voltage Registers
263 wakeup_sleep(TOTAL_IC);
264 error = LTC6810_rdaux(SEL_ALL_REG, TOTAL_IC,BMS_IC); // Set to read back all aux registers
265 check_error(error);
266 print_aux(DATALOG_DISABLED);
267 break;
268
269 case 7: // Start Status ADC Measurement
270 wakeup_sleep(TOTAL_IC);
271 LTC6810_adstat(ADC_CONVERSION_MODE, STAT_CH_TO_CONVERT);
272 conv_time=LTC6810_pollAdc();
273 print_conv_time(conv_time);
274 break;
275
276 case 8: // Read Status registers
277 wakeup_sleep(TOTAL_IC);
278 error = LTC6810_rdstat(SEL_ALL_REG,TOTAL_IC,BMS_IC); // Set to read back all Status registers
279 check_error(error);
280 print_stat();
281 break;
282
283 case 9:// Start Combined Cell Voltage and Cell 0, GPIO1 Conversion and Poll Status
284 wakeup_sleep(TOTAL_IC);
285 LTC6810_adcvax(ADC_CONVERSION_MODE,ADC_DCP);
286 conv_time = LTC6810_pollAdc();
287 print_conv_time(conv_time);
288 wakeup_idle(TOTAL_IC);
289 error =LTC6810_rdcv(SEL_ALL_REG, TOTAL_IC,BMS_IC); // Set to read back all cell voltage registers
290 check_error(error);
291 print_cells(DATALOG_DISABLED);
292 wakeup_idle(TOTAL_IC);
293 error = LTC6810_rdaux(SEL_REG_A,TOTAL_IC,BMS_IC); // Set to read back aux register A
294 check_error(error);
295 print_aux(DATALOG_DISABLED);
296 break;
297
298 case 10: //Start Combined Cell Voltage and Sum of cells
299 wakeup_sleep(TOTAL_IC);
300 LTC6810_adcvsc(ADC_CONVERSION_MODE,ADC_DCP);
301 conv_time = LTC6810_pollAdc();
302 print_conv_time(conv_time);
303 wakeup_idle(TOTAL_IC);
304 error = LTC6810_rdcv(SEL_ALL_REG,TOTAL_IC,BMS_IC); // Set to read back all cell voltage registers
305 check_error(error);
306 print_cells(DATALOG_DISABLED);
307 wakeup_idle(TOTAL_IC);
308 error = LTC6810_rdstat(SEL_REG_A,TOTAL_IC,BMS_IC); // Set to read back stat register A
309 check_error(error);
310 print_sumofcells();
311 break;
312
313 case 11: // Read S Voltage Registers
314 /****************************************************************
315 Ensure that the SCONV bit in the configuration register is set.
316 ****************************************************************/
317 wakeup_sleep(TOTAL_IC);
318 LTC6810_wrcfg(TOTAL_IC,BMS_IC); // Write into Configuration Register
319 LTC6810_adcv(ADC_CONVERSION_MODE,ADC_DCP,CELL_CH_TO_CONVERT);
320 conv_time = LTC6810_pollAdc();
321 print_conv_time(conv_time);
322 wakeup_idle(TOTAL_IC);
323 error = LTC6810_rds(SEL_ALL_REG, TOTAL_IC,BMS_IC); // Set to read back all S voltage registers
324 check_error(error);
325 print_svolt(DATALOG_DISABLED);
326 break;
327
328 case 12: // Loop Measurements of configuration register or cell voltages or auxiliary register or status register without data-log output
329 wakeup_sleep(TOTAL_IC);
330 LTC6810_wrcfg(TOTAL_IC,BMS_IC);
331 measurement_loop(DATALOG_DISABLED);
332 print_menu();
333 break;
334
335 case 13: // Data-log print option Loop Measurements of configuration register or cell voltages or auxiliary register or status register
336 wakeup_sleep(TOTAL_IC);
337 LTC6810_wrcfg(TOTAL_IC,BMS_IC);
338 measurement_loop(DATALOG_ENABLED);
339 print_menu();
340 break;
341
342 case 14: // Clear all ADC measurement registers
343 wakeup_sleep(TOTAL_IC);
344 LTC6810_clrcell();
345 LTC6810_clraux();
346 LTC6810_clrstat();
347 wakeup_sleep(TOTAL_IC);
348 LTC6810_rdcv(SEL_ALL_REG, TOTAL_IC,BMS_IC); // Set to read back all cell voltage registers
349 print_cells(DATALOG_DISABLED);
350
351 wakeup_idle(TOTAL_IC);
352 LTC6810_rdaux(SEL_ALL_REG,TOTAL_IC,BMS_IC); // Set to read back all aux registers
353 print_aux(DATALOG_DISABLED);
354
355 wakeup_idle(TOTAL_IC);
356 LTC6810_rdstat(SEL_ALL_REG,TOTAL_IC,BMS_IC); // Set to read back all status registers
357 print_stat();
358 break;
359
360 case 15: // Run the Mux Decoder Self Test
361 wakeup_sleep(TOTAL_IC);
362 LTC6810_diagn();
363 conv_time = LTC6810_pollAdc();
364 print_conv_time(conv_time);
365 error = LTC6810_rdstat(SEL_REG_B,TOTAL_IC,BMS_IC); // Set to read back Status registers B
366 check_error(error);
367 check_mux_fail();
368 break;
369
370 case 16: // Run the ADC/Memory Self Test
371 error =0;
372 wakeup_sleep(TOTAL_IC);
373 error = LTC6810_run_cell_adc_st(CELL,TOTAL_IC,BMS_IC,ADC_CONVERSION_MODE, ADCOPT );
374 print_selftest_errors(CELL, error);
375
376 error =0;
377 wakeup_sleep(TOTAL_IC);
378 error = LTC6810_run_cell_adc_st(AUX,TOTAL_IC,BMS_IC,ADC_CONVERSION_MODE, ADCOPT);
379 print_selftest_errors(AUX, error);
380
381 error =0;
382 wakeup_sleep(TOTAL_IC);
383 error = LTC6810_run_cell_adc_st(STAT,TOTAL_IC,BMS_IC,ADC_CONVERSION_MODE, ADCOPT);
384 print_selftest_errors(STAT, error);
385 print_menu();
386 break;
387
388 case 17: // Run ADC Digital Redundancy test
389 error =0;
390 wakeup_sleep(TOTAL_IC);
391 error = LTC6810_run_adc_redundancy_st(ADC_CONVERSION_MODE,AUX,TOTAL_IC, BMS_IC);
392 print_digital_redundancy_errors(AUX , error);
393
394 error =0;
395 wakeup_sleep(TOTAL_IC);
396 error = LTC6810_run_adc_redundancy_st(ADC_CONVERSION_MODE,STAT,TOTAL_IC, BMS_IC);
397 print_digital_redundancy_errors(STAT , error);
398 break;
399
400 case 18: // Open Wire test for single cell detection
401 wakeup_sleep(TOTAL_IC);
402 LTC6810_run_openwire_single(TOTAL_IC,BMS_IC);
403 print_open_wires();
404 break;
405
406 case 19: // Open Wire test for multiple cell and two consecutive cells detection
407 wakeup_sleep(TOTAL_IC);
408 LTC6810_run_openwire_multi(TOTAL_IC,BMS_IC);
409 break;
410
411 case 20: // Open wire Diagnostic for Auxiliary Measurements
412 wakeup_sleep(TOTAL_IC);
413 LTC6810_run_gpio_openwire(TOTAL_IC,BMS_IC);
414 print_open_wires();
415 break;
416
417 case 21: // PEC Errors Detected
418 print_pec_error_count();
419 break;
420
421 case 22: //Reset PEC Counter
422 LTC6810_reset_crc_count(TOTAL_IC,BMS_IC);
423 print_pec_error_count();
424 break;
425
426 case 23: // Enable a discharge transistor
427 s_pin_read = select_s_pin();
428 LTC6810_set_discharge(s_pin_read,TOTAL_IC,BMS_IC);
429 wakeup_sleep(TOTAL_IC);
430 LTC6810_wrcfg(TOTAL_IC,BMS_IC);
431 print_wrconfig();
432 wakeup_idle(TOTAL_IC);
433 error = LTC6810_rdcfg(TOTAL_IC,BMS_IC);
434 check_error(error);
435 print_rxconfig();
436 break;
437
438 case 24: // Clear all discharge transistors
439 LTC6810_clear_discharge(TOTAL_IC,BMS_IC);
440 wakeup_sleep(TOTAL_IC);
441 LTC6810_wrcfg(TOTAL_IC,BMS_IC);
442 print_wrconfig();
443 wakeup_idle(TOTAL_IC);
444 error = LTC6810_rdcfg(TOTAL_IC,BMS_IC);
445 check_error(error);
446 print_rxconfig();
447 break;
448
449 case 25://Write and read pwm configuration
450 /*****************************************************
451 Choose the value to be configured depending on the
452 required duty cycle. Refer to the data sheet.
453 Ensure that the DCTO value in the Configuration
454 Register Group is set to a non-zero value.
455 *******************************************************/
456 wakeup_sleep(TOTAL_IC);
457
458 for (uint8_t current_ic = 0; current_ic<TOTAL_IC;current_ic++)
459 {
460 BMS_IC[current_ic].pwm.tx_data[0]= 0x88; // PWM Duty cycle for cell 2 and 1
461 BMS_IC[current_ic].pwm.tx_data[1]= 0x88; // PWM Duty cycle for cell 4 and 3
462 BMS_IC[current_ic].pwm.tx_data[2]= 0x88; // PWM Duty cycle for cell 6 and 5
463 }
464 LTC6810_wrpwm(TOTAL_IC,0,BMS_IC);
465 print_wrpwm();
466
467 wakeup_idle(TOTAL_IC);
468 error=LTC6810_rdpwm(TOTAL_IC,0,BMS_IC);
469 check_error(error);
470 print_rxpwm();
471 break;
472
473 case 26://SPI Communication
474 /**************************************************************
475 Ensure to set the GPIO bits to 1 in the CFG register group.
476 ****************************************************************/
477 for (uint8_t current_ic = 0; current_ic<TOTAL_IC;current_ic++)
478 {
479 //Communication control bits and communication data bytes. Refer to the data sheet.
480 BMS_IC[current_ic].com.tx_data[0]= 0x81; // Icom CSBM Low(8) + data D0 (0x11)
481 BMS_IC[current_ic].com.tx_data[1]= 0x10; // Fcom CSBM Low(0)
482 BMS_IC[current_ic].com.tx_data[2]= 0xA2; // Icom CSBM Falling Edge (A) + D1 (0x25)
483 BMS_IC[current_ic].com.tx_data[3]= 0x50; // Fcom CSBM Low(0)
484 BMS_IC[current_ic].com.tx_data[4]= 0xA1; // Icom CSBM Falling Edge (A) + D2 (0x17)
485 BMS_IC[current_ic].com.tx_data[5]= 0x79; // Fcom CSBM High(9)
486 }
487 wakeup_sleep(TOTAL_IC);
488 LTC6810_wrcomm(TOTAL_IC,BMS_IC); // write to comm register
489 print_wrcomm(); // print data in the comm register
490
491 wakeup_idle(TOTAL_IC);
492 LTC6810_stcomm(3); // data length=3 // initiates communication between master and the I2C slave
493
494 wakeup_idle(TOTAL_IC);
495 error = LTC6810_rdcomm(TOTAL_IC,BMS_IC); // read from comm register
496 check_error(error);
497 print_rxcomm(); // print received data into the comm register
498 break;
499
500 case 27: // Write byte I2C Communication on the GPIO Ports(using I2C eeprom 24LC025)
501 /************************************************************
502 Ensure to set the GPIO bits to 1 in the CFG register group.
503 *************************************************************/
504 for (uint8_t current_ic = 0; current_ic<TOTAL_IC;current_ic++)
505 {
506 //Communication control bits and communication data bytes. Refer to the data sheet.
507 BMS_IC[current_ic].com.tx_data[0]= 0x6A; // Icom Start(6) + I2C_address D0 (0xA0)
508 BMS_IC[current_ic].com.tx_data[1]= 0x08; // Fcom master NACK(8)
509 BMS_IC[current_ic].com.tx_data[2]= 0x00; // Icom Blank (0) + eeprom address D1 (0x00)
510 BMS_IC[current_ic].com.tx_data[3]= 0x08; // Fcom master NACK(8)
511 BMS_IC[current_ic].com.tx_data[4]= 0x01; // Icom Blank (0) + data D2 (0x10)
512 BMS_IC[current_ic].com.tx_data[5]= 0x09; // Fcom master NACK + Stop(9)
513 }
514 wakeup_sleep(TOTAL_IC);
515 LTC6810_wrcomm(TOTAL_IC,BMS_IC);// write to comm register
516 print_wrcomm(); // print data from the comm register
517
518 wakeup_idle(TOTAL_IC);
519 LTC6810_stcomm(3); // data length=3 // initiates communication between master and the I2C slave
520
521 wakeup_idle(TOTAL_IC);
522 error = LTC6810_rdcomm(TOTAL_IC,BMS_IC); // read from comm register
523 check_error(error);
524 print_rxcomm(); // print received data into the comm register
525 break;
526
527 case 28: // Read byte data I2C Communication on the GPIO Ports(using I2C eeprom 24LC025 )
528 /************************************************************
529 Ensure to set the GPIO bits to 1 in the CFG register group.
530 *************************************************************/
531 for (uint8_t current_ic = 0; current_ic<TOTAL_IC;current_ic++)
532 {
533 //Communication control bits and communication data bytes. Refer to the data sheet.
534 BMS_IC[current_ic].com.tx_data[0]= 0x6A; // Icom Start (6) + I2C_address D0 (A0) (Write operation to set the word address)
535 BMS_IC[current_ic].com.tx_data[1]= 0x08; // Fcom master NACK(8)
536 BMS_IC[current_ic].com.tx_data[2]= 0x00; // Icom Blank (0) + eeprom address(word address) D1 (0x00)
537 BMS_IC[current_ic].com.tx_data[3]= 0x08; // Fcom master NACK(8)
538 BMS_IC[current_ic].com.tx_data[4]= 0x6A; // Icom Start (6) + I2C_address D2 (0xA1)(Read operation)
539 BMS_IC[current_ic].com.tx_data[5]= 0x18; // Fcom master NACK(8)
540 }
541 wakeup_sleep(TOTAL_IC);
542 LTC6810_wrcomm(TOTAL_IC,BMS_IC); // write to comm register
543
544 wakeup_idle(TOTAL_IC);
545 LTC6810_stcomm(3); // data length=3 // initiates communication between master and the I2C slave
546
547 for (uint8_t current_ic = 0; current_ic<TOTAL_IC;current_ic++)
548 {
549 //Communication control bits and communication data bytes. Refer to the data sheet.
550 BMS_IC[current_ic].com.tx_data[0]= 0x0F; // Icom Blank (0) + data D0 (FF)
551 BMS_IC[current_ic].com.tx_data[1]= 0xF9; // Fcom master NACK + Stop(9)
552 BMS_IC[current_ic].com.tx_data[2]= 0x7F; // Icom No Transmit (7) + data D1 (FF)
553 BMS_IC[current_ic].com.tx_data[3]= 0xF9; // Fcom master NACK + Stop(9)
554 BMS_IC[current_ic].com.tx_data[4]= 0x7F; // Icom No Transmit (7) + data D2 (FF)
555 BMS_IC[current_ic].com.tx_data[5]= 0xF9; // Fcom master NACK + Stop(9)
556 }
557 wakeup_idle(TOTAL_IC);
558 LTC6810_wrcomm(TOTAL_IC,BMS_IC); // write to comm register
559
560 wakeup_idle(TOTAL_IC);
561 LTC6810_stcomm(1); // data length=1 // initiates communication between master and the I2C slave
562
563 wakeup_idle(TOTAL_IC);
564 error = LTC6810_rdcomm(TOTAL_IC,BMS_IC); // read from comm register
565 check_error(error);
566 print_rxcomm(); // print received data from the comm register
567 break;
568
569 case 29: // To Reverse the direction of ISOSPI communication in a daisy chain connection
570 reverse_isospi_direction();
571 break;
572
573 case 30: // Read SID Register Group
574 wakeup_sleep(TOTAL_IC);
575 error = LTC6810_rdsid(TOTAL_IC,BMS_IC);
576 check_error(error);
577 print_sid();
578 break;
579
580 case 31: // To Mute discharging
581 wakeup_sleep(TOTAL_IC);
582 LTC6810_mute();
583 wakeup_idle(TOTAL_IC);
584 error = LTC6810_rdstat(SEL_REG_B,TOTAL_IC,BMS_IC); // Set to read back Status registers B
585 check_error(error);
586 check_mute_bit();
587 break;
588
589 case 32: // To Unmute discharging
590 wakeup_sleep(TOTAL_IC);
591 LTC6810_unmute();
592 wakeup_idle(TOTAL_IC);
593 error = LTC6810_rdstat(SEL_REG_B,TOTAL_IC,BMS_IC); // Set to read back Status registers B
594 check_error(error);
595 check_mute_bit();
596 break;
597
598 case 33: // Set or reset the gpio pins(to drive output on gpio pins)
599 /***********************************************************************
600 Please ensure you have set the GPIO bits according to your requirement
601 in the configuration register.( check the global variable GPIOBITS )
602 ************************************************************************/
603 wakeup_sleep(TOTAL_IC);
604 for (uint8_t current_ic = 0; current_ic<TOTAL_IC;current_ic++)
605 {
606 LTC6810_set_cfgr(current_ic, BMS_IC, REFON, ADCOPT, GPIOBITS, DCCBITS, DCCBIT_0, MCAL, EN_DTMEN, DIS_RED, FDRF, SCONV, DCTOBITS, UV, OV);
607 }
608 wakeup_idle(TOTAL_IC);
609 LTC6810_wrcfg(TOTAL_IC,BMS_IC);
610 print_wrconfig();
611 break;
612
613 case 'm': //prints menu
614 print_menu();
615 break;
616
617 default:
618 char str_error[]="Incorrect Option \n";
619 serial_print_text(str_error);
620 break;
621 }
622 }
623
624 /*!**********************************************************************************************************************************************
625 \brief For writing/reading configuration data or measuring cell voltages or reading aux register or reading status register in a continuous loop
626 @return void
627 *************************************************************************************************************************************************/
628 void measurement_loop(uint8_t datalog_en)
629 {
630 int8_t error = 0;
631 char input = 0;
632
633 Serial.println(F("Transmit 'm' to quit"));
634
635 while (input != 'm')
636 {
637 if (Serial.available() > 0)
638 {
639 input = read_char();
640 }
641
642 if (WRITE_CONFIG == ENABLED)
643 {
644 wakeup_idle(TOTAL_IC);
645 LTC6810_wrcfg(TOTAL_IC,BMS_IC);
646 print_wrconfig();
647 }
648
649 if (READ_CONFIG == ENABLED)
650 {
651 wakeup_idle(TOTAL_IC);
652 error = LTC6810_rdcfg(TOTAL_IC,BMS_IC);
653 check_error(error);
654 print_rxconfig();
655 }
656
657 if (MEASURE_CELL == ENABLED)
658 {
659 wakeup_idle(TOTAL_IC);
660 LTC6810_adcv(ADC_CONVERSION_MODE,ADC_DCP,CELL_CH_TO_CONVERT);
661 LTC6810_pollAdc();
662 wakeup_idle(TOTAL_IC);
663 error = LTC6810_rdcv(SEL_ALL_REG, TOTAL_IC,BMS_IC);
664 check_error(error);
665 print_cells(datalog_en);
666 }
667
668 if (MEASURE_AUX == ENABLED)
669 {
670 wakeup_idle(TOTAL_IC);
671 LTC6810_adax(ADC_CONVERSION_MODE , AUX_CH_ALL);
672 LTC6810_pollAdc();
673 wakeup_idle(TOTAL_IC);
674 error = LTC6810_rdaux(SEL_ALL_REG,TOTAL_IC,BMS_IC); // Set to read back all aux registers
675 check_error(error);
676 print_aux(datalog_en);
677 }
678
679 if (MEASURE_STAT == ENABLED)
680 {
681 wakeup_idle(TOTAL_IC);
682 LTC6810_adstat(ADC_CONVERSION_MODE, STAT_CH_ALL);
683 LTC6810_pollAdc();
684 wakeup_idle(TOTAL_IC);
685 error = LTC6810_rdstat(SEL_ALL_REG,TOTAL_IC,BMS_IC); // Set to read back all stat registers
686 check_error(error);
687 print_stat();
688 }
689
690 if(PRINT_PEC == ENABLED)
691 {
692 print_pec_error_count();
693 }
694 delay(MEASUREMENT_LOOP_TIME);
695 }
696 }
697
698 /*!*********************************
699 \brief Prints the main menu
700 @return void
701 ***********************************/
702 void print_menu(void)
703 {
704 Serial.println(F("Please enter LTC6810 Command"));
705 Serial.println(F("Write and Read Configuration: 1 |Loop Measurements: 12 |Set Discharge: 23"));
706 Serial.println(F("Read Configuration: 2 |Loop Measurements with Data Log output : 13 |Clear Discharge: 24"));
707 Serial.println(F("Start Cell Voltage Conversion: 3 |Clear all ADC Measurement Registers: 14 |Write and Read of PWM : 25"));
708 Serial.println(F("Read Cell Voltages: 4 |Run Mux Self Test: 15 |SPI Communication : 26"));
709 Serial.println(F("Start Aux Voltage Conversion: 5 |Run ADC Self Test: 16 |I2C Communication Write to Slave :27"));
710 Serial.println(F("Read Aux Voltages: 6 |Run Digital Redundancy Test: 17 |I2C Communication Read from Slave :28"));
711 Serial.println(F("Start Stat Voltage Conversion: 7 |Open Wire Test for single cell detection: 18 |Reverse ISOSPI : 29"));
712 Serial.println(F("Read Stat Voltages: 8 |Open Wire Test for multiple cell or two consecutive cells detection: 19|Read Serial ID : 30"));
713 Serial.println(F("Start Combined Cell Voltage and Cell 0, GPIO2 Conversion: 9|Open wire for Auxiliary Measurement: 20 |Enable MUTE : 31"));
714 Serial.println(F("Start Cell Voltage and Sum of cells: 10 |Print PEC Counter: 21 |Disable MUTE : 32"));
715 Serial.println(F("Read S Voltage Registers: 11 |Reset PEC Counter: 22 |Set or reset the gpio pins: 33 \n"));
716 Serial.println(F("Print 'm' for menu"));
717 Serial.println(F("Please enter command: \n"));
718 }
719
720 /*!******************************************************************************
721 \brief Prints the configuration data that is going to be written to the LTC6810
722 to the serial port.
723 @return void
724 ********************************************************************************/
725 void print_wrconfig(void)
726 {
727 int cfg_pec;
728
729 Serial.println(F("Written Configuration: "));
730 for (int current_ic = 0; current_ic<TOTAL_IC; current_ic++)
731 {
732 Serial.print(F("CFGA IC "));
733 Serial.print(current_ic+1,DEC);
734 for(int i = 0;i<6;i++)
735 {
736 Serial.print(F(", 0x"));
737 serial_print_hex(BMS_IC[current_ic].config.tx_data[i]);
738 }
739 Serial.print(F(", Calculated PEC: 0x"));
740 cfg_pec = pec15_calc(6,&BMS_IC[current_ic].config.tx_data[0]);
741 serial_print_hex((uint8_t)(cfg_pec>>8));
742 Serial.print(F(", 0x"));
743 serial_print_hex((uint8_t)(cfg_pec));
744 Serial.println("\n");
745 }
746 }
747
748 /*!*****************************************************************
749 \brief Prints the configuration data that was read back from the
750 LTC6810 to the serial port.
751 @return void
752 *******************************************************************/
753 void print_rxconfig(void)
754 {
755 Serial.println(F("Received Configuration "));
756 for (int current_ic=0; current_ic<TOTAL_IC; current_ic++)
757 {
758 Serial.print(F("CFGA IC "));
759 Serial.print(current_ic+1,DEC);
760 for(int i = 0; i < 6; i++)
761 {
762 Serial.print(F(", 0x"));
763 serial_print_hex(BMS_IC[current_ic].config.rx_data[i]);
764 }
765 Serial.print(F(", Received PEC: 0x"));
766 serial_print_hex(BMS_IC[current_ic].config.rx_data[6]);
767 Serial.print(F(", 0x"));
768 serial_print_hex(BMS_IC[current_ic].config.rx_data[7]);
769 Serial.println("\n");
770 }
771 }
772
773 /*!************************************************************
774 \brief Prints cell voltage codes to the serial port
775 @return void
776 *************************************************************/
777 void print_cells(uint8_t datalog_en)
778 {
779 for (int current_ic = 0 ; current_ic < TOTAL_IC; current_ic++)
780 {
781 if (datalog_en == 0)
782 {
783 Serial.print(" IC ");
784 Serial.print(current_ic+1,DEC);
785 Serial.print(": "); for (int i=0; i< BMS_IC[0].ic_reg.cell_channels; i++)
786 {
787 Serial.print(" C");
788 Serial.print(i+1,DEC);
789 Serial.print(":");
790 Serial.print(BMS_IC[current_ic].cells.c_codes[i]*0.0001,4);
791 Serial.print(",");
792 }
793 Serial.println();
794 }
795 else
796 {
797 Serial.print(" Cells :");
798 for (int i=0; i<BMS_IC[0].ic_reg.cell_channels; i++)
799 {
800 Serial.print(BMS_IC[current_ic].cells.c_codes[i]*0.0001,4);
801 Serial.print(",");
802 }
803 }
804 }
805 Serial.println("\n");
806 }
807
808 /*!****************************************************************************
809 \brief Prints GPIO voltage codes and Vref2 voltage code onto the serial port
810 @return void
811 *****************************************************************************/
812 void print_aux(uint8_t datalog_en)
813 {
814 for (int current_ic =0 ; current_ic < TOTAL_IC; current_ic++)
815 {
816 if (datalog_en == 0)
817 {
818 Serial.print(" IC ");
819 Serial.print(current_ic+1,DEC);
820 Serial.print(F(": S0_V :"));
821 Serial.print(BMS_IC[current_ic].aux.a_codes[0]*0.0001,4);
822 Serial.print(",");
823 for (int i = 1; i < 5; i++)
824 {
825 Serial.print(F(" GPIO-"));
826 Serial.print(i,DEC);
827 Serial.print(":");
828 Serial.print(BMS_IC[current_ic].aux.a_codes[i]*0.0001,4);
829 Serial.print(",");
830 }
831 Serial.print(F(" Vref2 :"));
832 Serial.print(BMS_IC[current_ic].aux.a_codes[5]*0.0001,4);
833 Serial.println();
834 }
835 else
836 {
837 Serial.print("AUX :");
838
839 for (int i=0; i < 6; i++)
840 {
841 Serial.print(BMS_IC[current_ic].aux.a_codes[i]*0.0001,4);
842 Serial.print(",");
843 }
844 }
845 }
846 Serial.println("\n");
847 }
848
849 /*!*****************************************************************************
850 \brief Prints Status voltage codes and Vref2 voltage code onto the serial port
851 @return void
852 ******************************************************************************/
853 void print_stat(void)
854 {
855 double itmp;
856 for (int current_ic =0 ; current_ic < TOTAL_IC; current_ic++)
857 {
858 Serial.print(F(" IC "));
859 Serial.print(current_ic+1,DEC);
860 Serial.print(F(" SOC:"));
861 Serial.print(BMS_IC[current_ic].stat.stat_codes[0]*0.0001*10,4);
862 Serial.print(F(", Itemp:"));
863 itmp = (double)((BMS_IC[current_ic].stat.stat_codes[1] * (0.0001 / 0.0075)) - 273); //Internal Die Temperature(°C) = ITMP • (100 µV / 7.5mV)°C - 273°C
864 Serial.print(itmp,4);
865 Serial.print(F(", VregA:"));
866 Serial.print(BMS_IC[current_ic].stat.stat_codes[2]*0.0001,4);
867 Serial.print(F(", VregD:"));
868 Serial.println(BMS_IC[current_ic].stat.stat_codes[3]*0.0001,4);
869 Serial.print(F(" Flag bits: 0x"));
870 serial_print_hex(BMS_IC[current_ic].stat.flags[0]);
871 Serial.print(F(",\t Flag bits and Mute bit:"));
872 Serial.print(F(" 0x"));
873 serial_print_hex((BMS_IC[current_ic].stat.flags[1])&(0x1F));
874 Serial.print(F(",\t Mux fail flag:"));
875 Serial.print(F(" 0x"));
876 serial_print_hex(BMS_IC[current_ic].stat.mux_fail[0]);
877 Serial.print(F(",\t THSD:"));
878 Serial.print(F(" 0x"));
879 serial_print_hex(BMS_IC[current_ic].stat.thsd[0]);
880 Serial.println("\n");
881 }
882 }
883
884 /*!****************************************************************************
885 \brief Prints Status voltage codes for SOC onto the serial port
886 @return void
887 *****************************************************************************/
888 void print_sumofcells(void)
889 {
890 for (int current_ic =0 ; current_ic < TOTAL_IC; current_ic++)
891 {
892 Serial.print(F(" IC "));
893 Serial.print(current_ic+1,DEC);
894 Serial.print(F(": SOC:"));
895 Serial.print(BMS_IC[current_ic].stat.stat_codes[0]*0.0001*10,4);
896 Serial.print(F(","));
897 }
898 Serial.println("\n");
899 }
900
901 /*!************************************************************
902 \brief Prints S voltage codes to the serial port
903 @return void
904 *************************************************************/
905 void print_svolt(uint8_t datalog_en)
906 {
907 for (int current_ic = 0 ; current_ic < TOTAL_IC; current_ic++)
908 {
909 if (datalog_en == 0)
910 {
911 Serial.print(" IC ");
912 Serial.print(current_ic+1,DEC);
913 Serial.print(": ");
914 int j=1;
915 for (int i=6; i<12; i++)
916 {
917 Serial.print(" S");
918 Serial.print(j,DEC);
919 Serial.print(":");
920 Serial.print(BMS_IC[current_ic].cells.c_codes[i]*0.0001,4);
921 Serial.print(",");
922 j++;
923 }
924 Serial.println();
925 }
926 else
927 {
928 Serial.print("S pin:, ");
929 for (int i=6; i<12; i++)
930 {
931 Serial.print(BMS_IC[current_ic].cells.c_codes[i]*0.0001,4);
932 Serial.print(",");
933 }
934 }
935 }
936 Serial.println("\n");
937 }
938
939 /*!****************************************************************
940 \brief Function to check the MUX fail bit in the Status Register
941 @return void
942 *******************************************************************/
943 void check_mux_fail(void)
944 {
945 int8_t error = 0;
946 for (int ic = 0; ic<TOTAL_IC; ic++)
947 {
948 Serial.print(" IC ");
949 Serial.println(ic+1,DEC);
950 if (BMS_IC[ic].stat.mux_fail[0] != 0) error++;
951
952 if (error==0) Serial.println(F("Mux Test: PASS \n"));
953 else Serial.println(F("Mux Test: FAIL \n"));
954 }
955 }
956
957 /*!************************************************************
958 \brief Prints Errors Detected during self test
959 @return void
960 *************************************************************/
961 void print_selftest_errors(uint8_t adc_reg ,int8_t error)
962 {
963 if(adc_reg==1)
964 {
965 Serial.println("Cell ");
966 }
967 else if(adc_reg==2)
968 {
969 Serial.println("Aux ");
970 }
971 else if(adc_reg==3)
972 {
973 Serial.println("Stat ");
974 }
975 Serial.print(error, DEC);
976 Serial.println(F(" : errors detected in Digital Filter and Memory \n"));
977 }
978
979 /*!************************************************************
980 \brief Prints Errors Detected during Digital Redundancy test
981 @return void
982 *************************************************************/
983 void print_digital_redundancy_errors(uint8_t adc_reg ,int8_t error)
984 {
985 if(adc_reg==2)
986 {
987 Serial.println("Aux ");
988 }
989 else if(adc_reg==3)
990 {
991 Serial.println("Stat ");
992 }
993
994 Serial.print(error, DEC);
995 Serial.println(F(" : errors detected in Measurement \n"));
996 }
997
998 /*!****************************************************************************
999 \brief Prints Open wire test results to the serial port
1000 @return void
1001 *****************************************************************************/
1002 void print_open_wires(void)
1003 {
1004 for (int current_ic =0 ; current_ic < TOTAL_IC; current_ic++)
1005 {
1006 if (BMS_IC[current_ic].system_open_wire == 65535)
1007 {
1008 Serial.print("No Opens Detected on IC ");
1009 Serial.print(current_ic+1, DEC);
1010 }
1011 else
1012 {
1013 Serial.print(F("There is an open wire on IC "));
1014 Serial.print(current_ic + 1,DEC);
1015 Serial.print(F(" Channel: "));
1016 Serial.println(BMS_IC[current_ic].system_open_wire);
1017 }
1018 Serial.println("\n");
1019 }
1020 }
1021
1022 /*!****************************************************************************
1023 \brief Function to print the number of PEC Errors
1024 @return void
1025 *****************************************************************************/
1026 void print_pec_error_count(void)
1027 {
1028 for (int current_ic=0; current_ic<TOTAL_IC; current_ic++)
1029 {
1030 Serial.println("");
1031 Serial.print(BMS_IC[current_ic].crc_count.pec_count,DEC);
1032 Serial.print(F(" : PEC Errors Detected on IC"));
1033 Serial.println(current_ic+1,DEC);
1034 }
1035 Serial.println("\n");
1036 }
1037
1038 /*!****************************************************
1039 \brief Function to select the S pin for discharge
1040 @return void
1041 ******************************************************/
1042 int8_t select_s_pin(void)
1043 {
1044 int8_t read_s_pin=0;
1045
1046 Serial.print(F("Please enter the Spin number: "));
1047 read_s_pin = (int8_t)read_int();
1048 Serial.println(read_s_pin);
1049 return(read_s_pin);
1050 }
1051
1052 /*!***********************************************************************************
1053 \brief Prints PWM the configuration data that is going to be written to the LTC6810
1054 to the serial port.
1055 @return void
1056 ************************************************************************************/
1057 void print_wrpwm(void)
1058 {
1059 int pwm_pec;
1060
1061 Serial.println(F("Written PWM Configuration: "));
1062 for (uint8_t current_ic = 0; current_ic<TOTAL_IC; current_ic++)
1063 {
1064 Serial.print(F("IC "));
1065 Serial.print(current_ic+1,DEC);
1066 for(int i = 0; i < 6; i++)
1067 {
1068 Serial.print(F(", 0x"));
1069 serial_print_hex(BMS_IC[current_ic].pwm.tx_data[i]);
1070 }
1071 Serial.print(F(", Calculated PEC: 0x"));
1072 pwm_pec = pec15_calc(6,&BMS_IC[current_ic].pwm.tx_data[0]);
1073 serial_print_hex((uint8_t)(pwm_pec>>8));
1074 Serial.print(F(", 0x"));
1075 serial_print_hex((uint8_t)(pwm_pec));
1076 Serial.println("\n");
1077 }
1078 }
1079
1080 /*!*****************************************************************
1081 \brief Prints the PWM configuration data that was read back from the
1082 LTC6810 to the serial port.
1083 @return void
1084 *******************************************************************/
1085 void print_rxpwm(void)
1086 {
1087 Serial.println(F("Received pwm Configuration:"));
1088 for (uint8_t current_ic=0; current_ic<TOTAL_IC; current_ic++)
1089 {
1090 Serial.print(F("IC "));
1091 Serial.print(current_ic+1,DEC);
1092 for(int i = 0; i < 6; i++)
1093 {
1094 Serial.print(F(", 0x"));
1095 serial_print_hex(BMS_IC[current_ic].pwm.rx_data[i]);
1096 }
1097 Serial.print(F(", Received PEC: 0x"));
1098 serial_print_hex(BMS_IC[current_ic].pwm.rx_data[6]);
1099 Serial.print(F(", 0x"));
1100 serial_print_hex(BMS_IC[current_ic].pwm.rx_data[7]);
1101 Serial.println("\n");
1102 }
1103 }
1104
1105 /*!****************************************************************************
1106 /prints data which is written on COMM register onto the serial port
1107 @return void
1108 *****************************************************************************/
1109 void print_wrcomm(void)
1110 {
1111 int comm_pec;
1112
1113 Serial.println(F("Written Data in COMM Register: "));
1114 for (int current_ic = 0; current_ic<TOTAL_IC; current_ic++)
1115 {
1116 Serial.print(F(" IC- "));
1117 Serial.print(current_ic+1,DEC);
1118
1119 for(int i = 0; i < 6; i++)
1120 {
1121 Serial.print(F(", 0x"));
1122 serial_print_hex(BMS_IC[current_ic].com.tx_data[i]);
1123 }
1124 Serial.print(F(", Calculated PEC: 0x"));
1125 comm_pec = pec15_calc(6,&BMS_IC[current_ic].com.tx_data[0]);
1126 serial_print_hex((uint8_t)(comm_pec>>8));
1127 Serial.print(F(", 0x"));
1128 serial_print_hex((uint8_t)(comm_pec));
1129 Serial.println("\n");
1130 }
1131 }
1132
1133 /*!****************************************************************************
1134 \brief Prints received data from COMM register onto the serial port
1135 @return void
1136 *****************************************************************************/
1137 void print_rxcomm(void)
1138 {
1139 Serial.println(F("Received Data in COMM register:"));
1140 for (int current_ic=0; current_ic<TOTAL_IC; current_ic++)
1141 {
1142 Serial.print(F(" IC- "));
1143 Serial.print(current_ic+1,DEC);
1144
1145 for(int i = 0; i < 6; i++)
1146 {
1147 Serial.print(F(", 0x"));
1148 serial_print_hex(BMS_IC[current_ic].com.rx_data[i]);
1149 }
1150 Serial.print(F(", Received PEC: 0x"));
1151 serial_print_hex(BMS_IC[current_ic].com.rx_data[6]);
1152 Serial.print(F(", 0x"));
1153 serial_print_hex(BMS_IC[current_ic].com.rx_data[7]);
1154 Serial.println("\n");
1155 }
1156 }
1157
1158 /*!******************************************************************************
1159 \brief Prints Serial ID to the serial port.
1160 @return void
1161 ********************************************************************************/
1162 void print_sid(void)
1163 {
1164 int sid_pec;
1165
1166 Serial.println(F("Serial ID: "));
1167 for (uint8_t current_ic = 0; current_ic<TOTAL_IC; current_ic++)
1168 {
1169 Serial.print(F("IC "));
1170 Serial.print(current_ic+1,DEC);
1171
1172 for(int i = 0; i < 6; i++)
1173 {
1174 Serial.print(F(", 0x"));
1175 serial_print_hex(BMS_IC[current_ic].sid[i]);
1176 }
1177 Serial.print(F(", Calculated PEC: 0x"));
1178 sid_pec = pec15_calc(6,&BMS_IC[current_ic].sid[0]);
1179 serial_print_hex((uint8_t)(sid_pec>>8));
1180 Serial.print(F(", 0x"));
1181 serial_print_hex((uint8_t)(sid_pec));
1182 Serial.println("\n");
1183 }
1184 }
1185
1186 /*!****************************************************************
1187 \brief Function to reverse the direction of ISOSPI communication
1188 when the ICs are connected in daisy chain
1189 @return void
1190 *******************************************************************/
1191 void reverse_isospi_direction(void)
1192 {
1193 Serial.print(F("ISOSPI: "));
1194 Serial.println(ISOSPI_DIR);
1195 BMS_IC[0].isospi_reverse =(bool)(!( ISOSPI_DIR));
1196 ISOSPI_DIR=BMS_IC[0].isospi_reverse;
1197 Serial.print(F("Current ISOSPI Direction: "));
1198 Serial.println(BMS_IC[0].isospi_reverse);
1199 Serial.println("\n");
1200 }
1201
1202 /*!****************************************************************
1203 \brief Function to check the Mute bit in the Status Register
1204 @return void
1205 *******************************************************************/
1206 void check_mute_bit(void)
1207 {
1208 for (int current_ic = 0 ; current_ic < TOTAL_IC; current_ic++)
1209 {
1210 Serial.print(F(" Mute bit in Status Register B: 0x"));
1211 serial_print_hex((BMS_IC[current_ic].stat.flags[1])&(0x10));
1212 Serial.println("\n");
1213 }
1214 }
1215
1216 /*!****************************************************************************
1217 \brief Function to print the Conversion Time
1218 @return void
1219 *****************************************************************************/
1220 void print_conv_time(uint32_t conv_time)
1221 {
1222 uint16_t m_factor=1000; // to print in ms
1223
1224 Serial.print(F("Conversion completed in:"));
1225 Serial.print(((float)conv_time/m_factor), 1);
1226 Serial.println(F("ms \n"));
1227 }
1228
1229 /*!****************************************************************************
1230 \brief Function to check error flag and print PEC error message
1231 @return void
1232 *****************************************************************************/
1233 void check_error(int error)
1234 {
1235 if (error == -1)
1236 {
1237 Serial.println(F("A PEC error was detected in the received data"));
1238 }
1239 }
1240
1241 /*!************************************************************
1242 \brief Function to print text on serial monitor
1243 @return void
1244 *************************************************************/
1245 void serial_print_text(char data[])
1246 {
1247 Serial.println(data);
1248 }
1249
1250 /*!************************************************************
1251 \brief Function to print in HEX form
1252 @return void
1253 *************************************************************/
1254 void serial_print_hex(uint8_t data)
1255 {
1256 if (data< 16)
1257 {
1258 Serial.print("0");
1259 Serial.print((byte)data,HEX);
1260 }
1261 else
1262 Serial.print((byte)data,HEX);
1263 }
1264
1265 /*!************************************************************
1266 \brief Hex conversion constants
1267 *************************************************************/
1268 char hex_digits[16]=
1269 {
1270 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
1271 };
1272
1273 /*!************************************************************
1274 \brief Global Variables
1275 *************************************************************/
1276 char hex_to_byte_buffer[5]=
1277 {
1278 '0', 'x', '0', '0', '\0'
1279 };
1280
1281 /*!************************************************************
1282 \brief Buffer for ASCII hex to byte conversion
1283 *************************************************************/
1284 char byte_to_hex_buffer[3]=
1285 {
1286 '\0','\0','\0'
1287 };
1288
1289 /*!****************************************************************************
1290 \brief Read 2 hex characters from the serial buffer and convert them to a byte
1291 @return char data Read Data
1292 *****************************************************************************/
1293 char read_hex(void)
1294 {
1295 byte data;
1296 hex_to_byte_buffer[2]=get_char();
1297 hex_to_byte_buffer[3]=get_char();
1298 get_char();
1299 get_char();
1300 data = strtol(hex_to_byte_buffer, NULL, 0);
1301 return(data);
1302 }
1303
1304 /*!************************************************************
1305 \brief Read a command from the serial port
1306 @return char
1307 *************************************************************/
1308 char get_char(void)
1309 {
1310 // read a command from the serial port
1311 while (Serial.available() <= 0);
1312 return(Serial.read());
1313 }
DCCBITS
bool DCCBITS[6]
Discharge cell switch //Dcc 1,2,3,4,5,6.
Definition: DC2515.ino:168
print_open_wires
static void print_open_wires(void)
Definition: DC2515.ino:1002
MEASURE_AUX
const uint8_t MEASURE_AUX
This is to ENABLED or DISABLED reading the auxiliary registers in a continuous loop.
Definition: DC2515.ino:143
LTC6810_run_cell_adc_st
int16_t LTC6810_run_cell_adc_st(uint8_t adc_reg, uint8_t total_ic, cell_asic *ic, uint8_t md, bool adcopt)
Helper function that runs the ADC Self Tests.
Definition: LTC6810.cpp:368
print_conv_time
static void print_conv_time(uint32_t conv_time)
Definition: DC2515.ino:1220
LTC6810_rdcv
uint8_t LTC6810_rdcv(uint8_t reg, uint8_t total_ic, cell_asic *ic)
Reads and parses the LTC6810 cell voltage registers.
Definition: LTC6810.cpp:150
LTC6810_set_cfgr
void LTC6810_set_cfgr(uint8_t nIC, cell_asic *ic, bool refon, bool adcopt, bool gpio[4], bool dcc[6], bool dcc_0, bool mcal, bool en_dtmen, bool dis_red, bool fdrf, bool sconv, bool dcto[4], uint16_t uv, uint16_t ov)
Helper function to set appropriate bits in CFGR register based on bit function.
Definition: LTC6810.cpp:666
LTC681x.h
General BMS Library.
wakeup_sleep
void wakeup_sleep()
Definition: LTC68041.cpp:969
user_command
unsigned char user_command
Definition: Serial_EEPROM_Test.ino:75
ic_register::tx_data
uint8_t tx_data[6]
Stores data to be transmitted.
Definition: LTC681x.h:143
TOTAL_IC
const uint8_t TOTAL_IC
Number of ICs in the daisy chain.
Definition: DC2515.ino:120
CELL_CH_ALL
#define CELL_CH_ALL
CH Dec Channels to convert 0000 All Cells 0011 Cell 1 and Cell 7 0102 Cell 2 and Cell 8 0113 Cell 3 ...
Definition: LTC68041.h:142
setup
static void setup()
Definition: DC2515.ino:182
print_aux
static void print_aux(uint8_t datalog_en)
Definition: DC2515.ino:812
print_selftest_errors
static void print_selftest_errors(uint8_t adc_reg, int8_t error)
Definition: DC2515.ino:961
DATALOG_ENABLED
#define DATALOG_ENABLED
Definition: DC2515.ino:83
READ_CONFIG
const uint8_t READ_CONFIG
This is to ENABLED or DISABLED reading the configuration registers in a continuous loop...
Definition: DC2515.ino:141
LTC6810_rdcomm
int8_t LTC6810_rdcomm(uint8_t total_ic, cell_asic *ic)
Reads comm registers of a LTC6810 in daisy chain.
Definition: LTC6810.cpp:569
LTC6810.h
LTC6810: 6-Channel Battery Stack Monitors.
DISABLED
#define DISABLED
Definition: DC2515.ino:82
print_sumofcells
static void print_sumofcells(void)
Definition: DC2515.ino:888
AUX
#define AUX
Definition: LTC6810.h:63
MEASUREMENT_LOOP_TIME
const uint16_t MEASUREMENT_LOOP_TIME
Loop Time in milliseconds(ms)
Definition: DC2515.ino:137
ADC_DCP
const uint8_t ADC_DCP
Discharge Permitted.
Definition: DC2515.ino:125
SEL_ALL_REG
const uint8_t SEL_ALL_REG
Register Selection.
Definition: DC2515.ino:129
Linduino.h
Header File for Linduino Libraries and Demo Code.
cell_asic
Cell variable structure.
Definition: LTC681x.h:170
BMS_IC
cell_asic BMS_IC[TOTAL_IC]
Global Battery Variable.
Definition: DC2515.ino:156
select_s_pin
static int8_t select_s_pin(void)
Definition: DC2515.ino:1042
STAT_CH_ALL
#define STAT_CH_ALL
Definition: LTC681x.h:88
AUX_CH_ALL
#define AUX_CH_ALL
CHG Dec Channels to convert 000 0 All GPIOS and 2nd Ref 001 1 GPIO 1 010 2 GPIO 2 011 3 GPIO 3 100 4...
Definition: LTC68041.h:164
get_char
char get_char(void)
Definition: DC2515.ino:1308
ISOSPI_DIR
bool ISOSPI_DIR
Definition: DC2515.ino:158
LTC6810_rdcfg
int8_t LTC6810_rdcfg(uint8_t total_ic, cell_asic *ic)
Reads configuration registers of a LTC6810 daisy chain.
Definition: LTC6810.cpp:94
print_rxcomm
static void print_rxcomm(void)
Definition: DC2515.ino:1137
CELL
#define CELL
Definition: LTC6810.h:62
SEL_REG_B
const uint8_t SEL_REG_B
Register Selection.
Definition: DC2515.ino:131
print_menu
static void print_menu(void)
Definition: DC2515.ino:702
cell_asic::ic_reg
register_cfg ic_reg
Definition: LTC681x.h:185
spi_enable
void spi_enable(uint8_t spi_clock_divider)
Setup the processor for hardware SPI communication.
Definition: LT_SPI.cpp:160
print_cells
static void print_cells(uint8_t datalog_en)
Definition: DC2515.ino:777
cell_asic::com
ic_register com
Definition: LTC681x.h:177
OV
static uint16_t OV
Over voltage Comparison Voltage.
Definition: DC2515.ino:167
LTC6810_clrstat
void LTC6810_clrstat()
Clears the LTC6810 Stat registers.
Definition: LTC6810.cpp:316
ADCOPT
bool ADCOPT
ADC Mode option bit.
Definition: DC2515.ino:163
GPIOBITS
bool GPIOBITS[4]
GPIO Pin Control // Gpio 1,2,3,4.
Definition: DC2515.ino:165
read_hex
char read_hex(void)
Definition: DC2515.ino:1293
LTC6810_rdpwm
int8_t LTC6810_rdpwm(uint8_t total_ic, uint8_t pwmReg, cell_asic *ic)
Reads pwm registers of the LTC6810 in daisy chain.
Definition: LTC6810.cpp:549
print_stat
static void print_stat(void)
Definition: DC2515.ino:853
LTC6810_mute
void LTC6810_mute()
Mutes the LTC6810 discharge transistors.
Definition: LTC6810.cpp:622
print_wrconfig
static void print_wrconfig(void)
Definition: DC2515.ino:725
DATALOG_DISABLED
#define DATALOG_DISABLED
Definition: DC2515.ino:84
SCONV
bool SCONV
Enable Cell Measurement Redundancy using S Pin.
Definition: DC2515.ino:174
EN_DTMEN
bool EN_DTMEN
Enable Discharge timer monitor.
Definition: DC2515.ino:171
data
union LT_union_int32_4bytes data
Definition: DC2094A.ino:138
LTC6810_adcvsc
void LTC6810_adcvsc(uint8_t MD, uint8_t DCP)
Starts cell voltage and SOC conversion.
Definition: LTC6810.cpp:129
byte_to_hex_buffer
char byte_to_hex_buffer[3]
Definition: DC2515.ino:1284
measurement_loop
static void measurement_loop(uint8_t datalog_en)
Definition: DC2515.ino:628
STAT
#define STAT
Definition: LTC6810.h:64
UV_THRESHOLD
const uint16_t UV_THRESHOLD
Under voltage threshold ADC Code.
Definition: DC2515.ino:135
print_rxconfig
static void print_rxconfig(void)
Definition: DC2515.ino:753
print_pec_error_count
static void print_pec_error_count(void)
Definition: DC2515.ino:1026
hex_digits
char hex_digits[16]
Definition: DC2515.ino:1268
reverse_isospi_direction
static void reverse_isospi_direction(void)
Definition: DC2515.ino:1191
ADC_OPT_DISABLED
#define ADC_OPT_DISABLED
Definition: LTC681x.h:67
OV_THRESHOLD
const uint16_t OV_THRESHOLD
Over voltage threshold ADC Code.
Definition: DC2515.ino:134
DCTOBITS
bool DCTOBITS[4]
Discharge Time Out Value //Dcto 0,1,2,3 // Programed for 4 min.
Definition: DC2515.ino:175
LTC6810_stcomm
void LTC6810_stcomm(uint8_t len)
Issues a stcomm command and clocks data out of the COMM register.
Definition: LTC6810.cpp:579
cell_asic::pwm
ic_register pwm
Definition: LTC681x.h:178
LTC6810_adcv
void LTC6810_adcv(uint8_t MD, uint8_t DCP, uint8_t CH)
Starts cell voltage conversion.
Definition: LTC6810.cpp:104
LTC6810_clear_discharge
void LTC6810_clear_discharge(uint8_t total_ic, cell_asic *ic)
Clears all of the DCC bits in the configuration registers.
Definition: LTC6810.cpp:529
UV
static uint16_t UV
Under voltage Comparison Voltage.
Definition: DC2515.ino:166
wakeup_idle
void wakeup_idle()
Definition: LTC68041.cpp:957
SEL_REG_A
const uint8_t SEL_REG_A
Register Selection.
Definition: DC2515.ino:130
REG_ALL
#define REG_ALL
Definition: LTC681x.h:94
serial_print_text
static void serial_print_text(char data[])
Definition: DC2515.ino:1245
REG_2
#define REG_2
Definition: LTC681x.h:96
check_error
static void check_error(int error)
Definition: DC2515.ino:1233
input
#define input(pin)
Return the state of pin "pin".
Definition: Linduino.h:79
LTC6810_clraux
void LTC6810_clraux()
Clears the LTC6810 Auxiliary registers.
Definition: LTC6810.cpp:306
register_cfg::cell_channels
uint8_t cell_channels
Number of Cell channels.
Definition: LTC681x.h:161
LTC6810_unmute
void LTC6810_unmute()
Clears the LTC6810 Mute Discharge.
Definition: LTC6810.cpp:633
run_command
static void run_command(uint32_t cmd)
Definition: DC2515.ino:216
error
static int error
Definition: LT1054_voltage_mode_buck.ino:64
LTC6810_reset_crc_count
void LTC6810_reset_crc_count(uint8_t total_ic, cell_asic *ic)
Helper Function that resets the PEC error counters.
Definition: LTC6810.cpp:652
print_wrcomm
static void print_wrcomm(void)
/prints data which is written on COMM register onto the serial port
Definition: DC2515.ino:1109
LTC6810_rdstat
int8_t LTC6810_rdstat(uint8_t reg, uint8_t total_ic, cell_asic *ic)
Reads and parses the LTC6810 stat registers.
Definition: LTC6810.cpp:182
LTC6810_init_cfg
void LTC6810_init_cfg(uint8_t total_ic, cell_asic *ic)
Helper Function to initialize the CFGR data structures.
Definition: LTC6810.cpp:660
MEASURE_CELL
const uint8_t MEASURE_CELL
This is to ENABLED or DISABLED measuring the cell voltages in a continuous loop.
Definition: DC2515.ino:142
LTC6810_rds
uint8_t LTC6810_rds(uint8_t reg, uint8_t total_ic, cell_asic *ic)
Reads and parses the LTC6810 S voltage registers.
Definition: LTC6810.cpp:198
REFON
bool REFON
Reference Powered Up Bit.
Definition: DC2515.ino:164
LTC6810_clrcell
void LTC6810_clrcell()
Clears the LTC6810 cell voltage registers.
Definition: LTC6810.cpp:296
AUX_CH_TO_CONVERT
const uint8_t AUX_CH_TO_CONVERT
Channel Selection for ADC conversion.
Definition: DC2515.ino:127
pec15_calc
uint16_t pec15_calc(uint8_t len, uint8_t *data)
Definition: LTC68041.cpp:985
check_mux_fail
static void check_mux_fail(void)
Definition: DC2515.ino:943
MCAL
bool MCAL
Enable Multi-Calibration.
Definition: DC2515.ino:170
LT_SPI.h
LT_SPI: Routines to communicate with ATmega328P&#39;s hardware SPI port.
MEASURE_STAT
const uint8_t MEASURE_STAT
This is to ENABLED or DISABLED reading the status registers in a continuous loop. ...
Definition: DC2515.ino:144
LTC6810_wrcomm
void LTC6810_wrcomm(uint8_t total_ic, cell_asic *ic)
Write the LTC6810 COMM register.
Definition: LTC6810.cpp:561
MD_7KHZ_3KHZ
#define MD_7KHZ_3KHZ
Definition: LTC681x.h:63
ENABLED
#define ENABLED
Definition: DC2515.ino:81
LTC6810_run_gpio_openwire
void LTC6810_run_gpio_openwire(uint8_t total_ic, cell_asic ic[])
Definition: LTC6810.cpp:427
LTC6810_adax
void LTC6810_adax(uint8_t MD, uint8_t CHG)
Start a GPIO, cell 0 and Vref2 Conversion.
Definition: LTC6810.cpp:113
LTC6810_adstat
void LTC6810_adstat(uint8_t MD, uint8_t CHST)
Start a Status ADC Conversion.
Definition: LTC6810.cpp:121
WRITE_CONFIG
const uint8_t WRITE_CONFIG
This is to ENABLED or DISABLED writing into to configuration registers in a continuous loop...
Definition: DC2515.ino:140
LTC6810_adcvax
void LTC6810_adcvax(uint8_t MD, uint8_t DCP)
Starts cell voltage, Cell 0 and GPIO 1 conversion.
Definition: LTC6810.cpp:137
quikeval_SPI_connect
void quikeval_SPI_connect()
Connect SPI pins to QuikEval connector through the Linduino MUX. This will disconnect I2C...
Definition: LT_SPI.cpp:138
REG_1
#define REG_1
Definition: LTC681x.h:95
UserInterface.h
read_int
int32_t read_int()
Definition: UserInterface.cpp:93
LTC6810_wrcfg
void LTC6810_wrcfg(uint8_t total_ic, cell_asic *ic)
Write the LTC6810 configuration register.
Definition: LTC6810.cpp:86
loop
static void loop()
Definition: DC2515.ino:201
LTC6810_rdaux
int8_t LTC6810_rdaux(uint8_t reg, uint8_t total_ic, cell_asic *ic)
Reads and parses the LTC6810 auxiliary registers.
Definition: LTC6810.cpp:166
ADC_CONVERSION_MODE
const uint8_t ADC_CONVERSION_MODE
ADC Mode.
Definition: DC2515.ino:124
DCP_DISABLED
#define DCP_DISABLED
Definition: LTC68041.h:183
STAT_CH_TO_CONVERT
const uint8_t STAT_CH_TO_CONVERT
Channel Selection for ADC conversion.
Definition: DC2515.ino:128
LTC6810_diagn
void LTC6810_diagn()
Starts the Mux Decoder diagnostic self test.
Definition: LTC6810.cpp:322
print_wrpwm
static void print_wrpwm(void)
Definition: DC2515.ino:1057
print_sid
static void print_sid(void)
Definition: DC2515.ino:1162
LTC6810_rdsid
uint8_t LTC6810_rdsid(uint8_t total_ic, cell_asic *ic)
Reads Serial ID registers group.
Definition: LTC6810.cpp:585
DCCBIT_0
bool DCCBIT_0
Discharge cell switch //Dcc 0 // For discharging optional 7th cell.
Definition: DC2515.ino:169
LTC6810_run_adc_redundancy_st
int16_t LTC6810_run_adc_redundancy_st(uint8_t adc_mode, uint8_t adc_reg, uint8_t total_ic, cell_asic *ic)
Helper function that runs the ADC Digital Redundancy commands and checks output for errors...
Definition: LTC6810.cpp:381
ADC_OPT
const uint8_t ADC_OPT
ADC Mode option bit.
Definition: DC2515.ino:123
LTC6810_run_openwire_single
void LTC6810_run_openwire_single(uint8_t total_ic, cell_asic *ic)
Helper function that runs the data sheet open wire algorithm for single cell detection.
Definition: LTC6810.cpp:411
hex_to_byte_buffer
char hex_to_byte_buffer[5]
Definition: DC2515.ino:1276
i
static int i
Definition: DC2430A.ino:184
print_rxpwm
static void print_rxpwm(void)
Definition: DC2515.ino:1085
PRINT_PEC
const uint8_t PRINT_PEC
This is to ENABLED or DISABLED printing the PEC Error Count in a continuous loop. ...
Definition: DC2515.ino:145
FDRF
bool FDRF
Force digital Redundancy Failure.
Definition: DC2515.ino:173
LTC6810_init_reg_limits
void LTC6810_init_reg_limits(uint8_t total_ic, cell_asic *ic)
Initialize the Register limits.
Definition: LTC6810.cpp:66
check_mute_bit
static void check_mute_bit(void)
Definition: DC2515.ino:1206
serial_print_hex
static void serial_print_hex(uint8_t data)
Definition: DC2515.ino:1254
read_char
int8_t read_char()
Definition: UserInterface.cpp:116
print_svolt
static void print_svolt(uint8_t datalog_en)
Definition: DC2515.ino:905
cell_asic::isospi_reverse
bool isospi_reverse
Definition: LTC681x.h:183
CELL_CH_TO_CONVERT
const uint8_t CELL_CH_TO_CONVERT
Channel Selection for ADC conversion.
Definition: DC2515.ino:126
LTC6810_run_openwire_multi
void LTC6810_run_openwire_multi(uint8_t total_ic, cell_asic *ic)
Runs the data sheet algorithm for open wire for multiple cell and two consecutive cells detection...
Definition: LTC6810.cpp:419
LTC6810_wrpwm
void LTC6810_wrpwm(uint8_t total_ic, uint8_t pwmReg, cell_asic *ic)
Writes to the LTC6810 PWM register of LTC6810.
Definition: LTC6810.cpp:540
LTC6810_pollAdc
uint32_t LTC6810_pollAdc()
This function will block operation until the ADC has finished it&#39;s conversion.
Definition: LTC6810.cpp:286
print_digital_redundancy_errors
static void print_digital_redundancy_errors(uint8_t adc_reg, int8_t error)
Definition: DC2515.ino:983
DIS_RED
bool DIS_RED
Disable Digital Redundancy Check.
Definition: DC2515.ino:172
LTC6810_set_discharge
void LTC6810_set_discharge(int Cell, uint8_t total_ic, cell_asic *ic)
Helper function to set discharge bit in CFG register.
Definition: LTC6810.cpp:510