| Linduino 1.3.0 Linear Technology Arduino-Compatible Demonstration Board

DC2350AA.ino
Go to the documentation of this file.
1 /*! Analog Devices DC2350A-A Demonstration Board.
2 *LTC6812: Multicell Battery 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/ltc6812-1.html
20 * The schematic of DC2350A : https://www.analog.com/media/en/technical-documentation/eval-board-schematic/DC2350A-4-SCH.PDF
21 * ( Ensure that you modify the DC2350A board as mentioned on the schematic to work for LTC6812 (DC2350A-A) )
22 *
23 ********************************************************************************
24 * Copyright 2019(c) Analog Devices, Inc.
25 *
26 * All rights reserved.
27 *
28 * Redistribution and use in source and binary forms, with or without
29 * modification, are permitted provided that the following conditions are met:
30 * - Redistributions of source code must retain the above copyright
31 * notice, this list of conditions and the following disclaimer.
32 * - Redistributions in binary form must reproduce the above copyright
33 * notice, this list of conditions and the following disclaimer in
34 * the documentation and/or other materials provided with the
35 * distribution.
36 * - Neither the name of Analog Devices, Inc. nor the names of its
37 * contributors may be used to endorse or promote products derived
38 * from this software without specific prior written permission.
39 * - The use of this software may or may not infringe the patent rights
40 * of one or more patent holders. This license does not release you
41 * from the requirement that you obtain separate licenses from these
42 * patent holders to use this software.
43 * - Use of the software either in source or binary form, must be run
44 * on or directly connected to an Analog Devices Inc. component.
45 *
46 * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
47 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
48 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
49 * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
50 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
51 * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
52 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
53 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
54 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
55 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
56 *******************************************************************************/
57
58 /*! @file
59 @ingroup LTC6812-1
60 */
61
62 /************************************* Read me *******************************************
63 In this sketch book:
64 -All Global Variables are in Upper casing
65 -All Local Variables are in lower casing
66 -The Function wakeup_sleep(TOTAL_IC) : is used to wake the LTC681x from sleep state.
67 It is defined in LTC681x.cpp
68 -The Function wakeup_idle(TOTAL_IC) : is used to wake the ICs connected in daisy chain
69 via the LTC6820 by initiating a dummy SPI communication. It is defined in LTC681x.cpp
70 *******************************************************************************************/
71
72 /************************* Includes ***************************/
73 #include <Arduino.h>
74 #include <stdint.h>
75 #include <SPI.h>
76 #include "Linduino.h"
77 #include "LT_SPI.h"
78 #include "UserInterface.h"
79 #include "LTC681x.h"
80 #include "LTC6812.h"
81
82 /************************* Defines *****************************/
83 #define ENABLED 1
84 #define DISABLED 0
85 #define DATALOG_ENABLED 1
86 #define DATALOG_DISABLED 0
87 #define PWM 1
88 #define SCTL 2
89
90 /**************** Local Function Declaration *******************/
91 void measurement_loop(uint8_t datalog_en);
92 void print_menu(void);
93 void print_wrconfig(void);
94 void print_wrconfigb(void);
95 void print_rxconfig(void);
96 void print_rxconfigb(void);
97 void print_cells(uint8_t datalog_en);
98 void print_aux(uint8_t datalog_en);
99 void print_stat(void);
100 void print_aux1(void);
101 void print_sumofcells(void);
102 void check_mux_fail(void);
103 void print_selftest_errors(uint8_t adc_reg ,int8_t error);
104 void print_overlap_results(int8_t error);
105 void print_digital_redundancy_errors(uint8_t adc_reg ,int8_t error);
106 void print_open_wires(void);
107 void print_pec_error_count(void);
108 int8_t select_s_pin(void);
109 void print_wrpwm(void);
110 void print_rxpwm(void);
111 void print_wrsctrl(void);
112 void print_rxsctrl(void);
113 void print_wrpsb(uint8_t type);
114 void print_rxpsb(uint8_t type);
115 void print_wrcomm(void);
116 void print_rxcomm(void);
117 void check_mute_bit(void);
118 void print_conv_time(uint32_t conv_time);
119 void check_error(int error);
120 void serial_print_text(char data[]);
121 void serial_print_hex(uint8_t data);
122 char read_hex(void);
123 char get_char(void);
124
125 /*******************************************************************
126 Setup Variables
127 The following variables can be modified to configure the software.
128 ********************************************************************/
129 const uint8_t TOTAL_IC = 2; //!< Number of ICs in the daisy chain
130
131 //ADC Command Configurations. See LTC681x.h for options.
132 const uint8_t ADC_OPT = ADC_OPT_DISABLED; //!< ADC Mode option bit
133 const uint8_t ADC_CONVERSION_MODE = MD_7KHZ_3KHZ; //!< ADC Mode
134 const uint8_t ADC_DCP = DCP_DISABLED; //!< Discharge Permitted
135 const uint8_t CELL_CH_TO_CONVERT = CELL_CH_ALL; //!< Channel Selection for ADC conversion
136 const uint8_t AUX_CH_TO_CONVERT = AUX_CH_ALL; //!< Channel Selection for ADC conversion
137 const uint8_t STAT_CH_TO_CONVERT = STAT_CH_ALL; //!< Channel Selection for ADC conversion
138 const uint8_t SEL_ALL_REG = REG_ALL; //!< Register Selection
139 const uint8_t SEL_REG_A = REG_1; //!< Register Selection
140 const uint8_t SEL_REG_B = REG_2; //!< Register Selection
141
142 const uint16_t MEASUREMENT_LOOP_TIME = 500; //!< Loop Time in milliseconds(ms)
143
144 //Under Voltage and Over Voltage Thresholds
145 const uint16_t OV_THRESHOLD = 41000; //!< Over voltage threshold ADC Code. LSB = 0.0001 ---(4.1V)
146 const uint16_t UV_THRESHOLD = 30000; //!< Under voltage threshold ADC Code. LSB = 0.0001 ---(3V)
147
148 //Loop Measurement Setup. These Variables are ENABLED or DISABLED. Remember ALL CAPS
149 const uint8_t WRITE_CONFIG = DISABLED; //!< This is to ENABLED or DISABLED writing into to configuration registers in a continuous loop
150 const uint8_t READ_CONFIG = DISABLED; //!< This is to ENABLED or DISABLED reading the configuration registers in a continuous loop
151 const uint8_t MEASURE_CELL = ENABLED; //!< This is to ENABLED or DISABLED measuring the cell voltages in a continuous loop
152 const uint8_t MEASURE_AUX = DISABLED; //!< This is to ENABLED or DISABLED reading the auxiliary registers in a continuous loop
153 const uint8_t MEASURE_STAT = DISABLED; //!< This is to ENABLED or DISABLED reading the status registers in a continuous loop
154 const uint8_t PRINT_PEC = DISABLED; //!< This is to ENABLED or DISABLED printing the PEC Error Count in a continuous loop
155 /************************************
156 END SETUP
157 *************************************/
158
159 /******************************************************
160 Global Battery Variables received from 681x commands
161 These variables store the results from the LTC6812
162 register reads and the array lengths must be based
163 on the number of ICs on the stack
164 ******************************************************/
165 cell_asic BMS_IC[TOTAL_IC]; //!< Global Battery Variable
166
167 /*************************************************************************
168 Set configuration register. Refer to the data sheet
169 **************************************************************************/
170 bool REFON = true; //!< Reference Powered Up Bit
171 bool ADCOPT = false; //!< ADC Mode option bit
172 bool GPIOBITS_A[5] = {false,false,true,true,true}; //!< GPIO Pin Control // Gpio 1,2,3,4,5
173 bool GPIOBITS_B[4] = {false,false,false,false}; //!< GPIO Pin Control // Gpio 6,7,8,9
174 uint16_t UV=UV_THRESHOLD; //!< Under voltage Comparison Voltage
175 uint16_t OV=OV_THRESHOLD; //!< Over voltage Comparison Voltage
176 bool DCCBITS_A[12] = {false,false,false,false,false,false,false,false,false,false,false,false}; //!< Discharge cell switch //Dcc 1,2,3,4,5,6,7,8,9,10,11,12
177 bool DCCBITS_B[7]= {false,false,false,false}; //!< Discharge cell switch //Dcc 0,13,14,15
178 bool DCTOBITS[4] = {true,false,true,false}; //!< Discharge time value //Dcto 0,1,2,3 // Programed for 4 min
179 /*Ensure that Dcto bits are set according to the required discharge time. Refer to the data sheet */
180 bool FDRF = false; //!< Force Digital Redundancy Failure Bit
181 bool DTMEN = true; //!< Enable Discharge Timer Monitor
182 bool PSBits[2]= {false,false}; //!< Digital Redundancy Path Selection//ps-0,1
183
184 /*!**********************************************************************
185 \brief Initializes hardware and variables
186 @return void
187 ***********************************************************************/
188 void setup()
189 {
190 Serial.begin(115200);
191 quikeval_SPI_connect();
192 spi_enable(SPI_CLOCK_DIV16); // This will set the Linduino to have a 1MHz Clock
193 LTC6812_init_cfg(TOTAL_IC, BMS_IC);
194 LTC6812_init_cfgb(TOTAL_IC,BMS_IC);
195 for (uint8_t current_ic = 0; current_ic<TOTAL_IC;current_ic++)
196 {
197 LTC6812_set_cfgr(current_ic,BMS_IC,REFON,ADCOPT,GPIOBITS_A,DCCBITS_A, DCTOBITS, UV, OV);
198 LTC6812_set_cfgrb(current_ic,BMS_IC,FDRF,DTMEN,PSBits,GPIOBITS_B,DCCBITS_B);
199 }
200 LTC6812_reset_crc_count(TOTAL_IC,BMS_IC);
201 LTC6812_init_reg_limits(TOTAL_IC,BMS_IC);
202 print_menu();
203 }
204
205 /*!*********************************************************************
206 \brief Main loop
207 @return void
208 ***********************************************************************/
209 void loop()
210 {
211 if (Serial.available()) // Check for user input
212 {
213 uint32_t user_command;
214 user_command = read_int(); // Read the user command
215 if(user_command=='m')
216 {
217 print_menu();
218 }
219 else
220 {
221 Serial.println(user_command);
222 run_command(user_command);
223 }
224 }
225 }
226
227 /*!*****************************************
228 \brief Executes the user command
229 @return void
230 *******************************************/
231 void run_command(uint32_t cmd)
232 {
233 uint8_t streg=0;
234 int8_t error = 0;
235 uint32_t conv_time = 0;
236 int8_t s_pin_read=0;
237
238 switch (cmd)
239 {
240 case 1: // Write and read Configuration Register
241 wakeup_sleep(TOTAL_IC);
242 LTC6812_wrcfg(TOTAL_IC,BMS_IC); // Write into Configuration Register
243 LTC6812_wrcfgb(TOTAL_IC,BMS_IC); // Write into Configuration Register B
244 print_wrconfig();
245 print_wrconfigb();
246
247 wakeup_idle(TOTAL_IC);
248 error = LTC6812_rdcfg(TOTAL_IC,BMS_IC); // Read Configuration Register
249 check_error(error);
250 error = LTC6812_rdcfgb(TOTAL_IC,BMS_IC); // Read Configuration Register B
251 check_error(error);
252 print_rxconfig();
253 print_rxconfigb();
254 break;
255
256 case 2: // Read Configuration Register
257 wakeup_sleep(TOTAL_IC);
258 error = LTC6812_rdcfg(TOTAL_IC,BMS_IC);
259 check_error(error);
260 error = LTC6812_rdcfgb(TOTAL_IC,BMS_IC);
261 check_error(error);
262 print_rxconfig();
263 print_rxconfigb();
264 break;
265
266 case 3: // Start Cell ADC Measurement
267 wakeup_sleep(TOTAL_IC);
268 LTC6812_adcv(ADC_CONVERSION_MODE,ADC_DCP,CELL_CH_TO_CONVERT);
269 conv_time = LTC6812_pollAdc();
270 print_conv_time(conv_time);
271 break;
272
273 case 4: // Read Cell Voltage Registers
274 wakeup_sleep(TOTAL_IC);
275 error = LTC6812_rdcv(SEL_ALL_REG, TOTAL_IC,BMS_IC); // Set to read back all cell voltage registers
276 check_error(error);
277 print_cells(DATALOG_DISABLED);
278 break;
279
280 case 5: // Start GPIO ADC Measurement
281 wakeup_sleep(TOTAL_IC);
282 LTC6812_adax(ADC_CONVERSION_MODE, AUX_CH_TO_CONVERT);
283 conv_time= LTC6812_pollAdc();
284 print_conv_time(conv_time);
285 break;
286
287 case 6: // Read AUX Voltage Registers
288 wakeup_sleep(TOTAL_IC);
289 error = LTC6812_rdaux(SEL_ALL_REG,TOTAL_IC,BMS_IC); // Set to read back all aux registers
290 check_error(error);
291 print_aux(DATALOG_DISABLED);
292 break;
293
294 case 7: // Start Status ADC Measurement
295 wakeup_sleep(TOTAL_IC);
296 LTC6812_adstat(ADC_CONVERSION_MODE, STAT_CH_TO_CONVERT);
297 conv_time=LTC6812_pollAdc();
298 print_conv_time(conv_time);
299 break;
300
301 case 8: // Read Status registers
302 wakeup_sleep(TOTAL_IC);
303 error = LTC6812_rdstat(SEL_ALL_REG,TOTAL_IC,BMS_IC); // Set to read back all stat registers
304 check_error(error);
305 print_stat();
306 break;
307
308 case 9 : // Start Combined Cell Voltage and GPIO1, GPIO2 Conversion and Poll Status
309 wakeup_sleep(TOTAL_IC);
310 LTC6812_adcvax(ADC_CONVERSION_MODE,ADC_DCP);
311 conv_time = LTC6812_pollAdc();
312 print_conv_time(conv_time);
313 wakeup_idle(TOTAL_IC);
314 error = LTC6812_rdcv(SEL_ALL_REG, TOTAL_IC,BMS_IC); // Set to read back all cell voltage registers
315 check_error(error);
316 print_cells(DATALOG_DISABLED);
317 wakeup_idle(TOTAL_IC);
318 error = LTC6812_rdaux(SEL_REG_A, TOTAL_IC,BMS_IC); // Set to read back aux register A
319 check_error(error);
320 print_aux1(DATALOG_DISABLED);
321 break;
322
323 case 10 : // Start Combined Cell Voltage and Sum of cells
324 wakeup_sleep(TOTAL_IC);
325 LTC6812_adcvsc(ADC_CONVERSION_MODE,ADC_DCP);
326 conv_time = LTC6812_pollAdc();
327 print_conv_time(conv_time);
328 wakeup_idle(TOTAL_IC);
329 error = LTC6812_rdcv(SEL_ALL_REG, TOTAL_IC,BMS_IC); // Set to read back all cell voltage registers
330 check_error(error);
331 print_cells(DATALOG_DISABLED);
332 wakeup_idle(TOTAL_IC);
333 error = LTC6812_rdstat(SEL_REG_A,TOTAL_IC,BMS_IC); // Set to read back stat register A
334 check_error(error);
335 print_sumofcells();
336 break;
337
338 case 11: // Loop Measurements of configuration register or cell voltages or auxiliary register or status register without data-log output
339 wakeup_sleep(TOTAL_IC);
340 LTC6812_wrcfg(TOTAL_IC,BMS_IC);
341 LTC6812_wrcfgb(TOTAL_IC,BMS_IC);
342 measurement_loop(DATALOG_DISABLED);
343 print_menu();
344 break;
345
346 case 12: // Data-log print option Loop Measurements of configuration register or cell voltages or auxiliary register or status register
347 wakeup_sleep(TOTAL_IC);
348 LTC6812_wrcfg(TOTAL_IC,BMS_IC);
349 LTC6812_wrcfgb(TOTAL_IC,BMS_IC);
350 measurement_loop(DATALOG_ENABLED);
351 print_menu();
352 break;
353
354 case 13: // Clear all ADC measurement registers
355 wakeup_sleep(TOTAL_IC);
356 LTC6812_clrcell();
357 LTC6812_clraux();
358 LTC6812_clrstat();
359 wakeup_idle(TOTAL_IC);
360 LTC6812_rdcv(SEL_ALL_REG, TOTAL_IC,BMS_IC); // read back all cell voltage registers
361 print_cells(DATALOG_DISABLED);
362 LTC6812_rdaux(SEL_ALL_REG,TOTAL_IC,BMS_IC); // read back all auxiliary registers
363 print_aux(DATALOG_DISABLED);
364 LTC6812_rdstat(SEL_ALL_REG,TOTAL_IC,BMS_IC); // read back all status registers
365 print_stat();
366 break;
367
368 case 14: // Run the Mux Decoder Self Test
369 wakeup_sleep(TOTAL_IC);
370 LTC6812_diagn();
371 LTC6812_pollAdc();
372 error = LTC6812_rdstat(SEL_REG_B,TOTAL_IC,BMS_IC); // Set to read back stat register B
373 check_error(error);
374 check_mux_fail();
375 break;
376
377 case 15: // Run the ADC/Memory Self Test
378 error = 0;
379 wakeup_sleep(TOTAL_IC);
380 error = LTC6812_run_cell_adc_st(CELL,TOTAL_IC,BMS_IC, ADC_CONVERSION_MODE,ADCOPT);
381 print_selftest_errors(CELL, error);
382
383 error = 0;
384 wakeup_sleep(TOTAL_IC);
385 error = LTC6812_run_cell_adc_st(AUX,TOTAL_IC, BMS_IC, ADC_CONVERSION_MODE,ADCOPT);
386 print_selftest_errors(AUX, error);
387
388 error = 0;
389 wakeup_sleep(TOTAL_IC);
390 error = LTC6812_run_cell_adc_st(STAT,TOTAL_IC, BMS_IC, ADC_CONVERSION_MODE,ADCOPT);
391 print_selftest_errors(STAT, error);
392 break;
393
394 case 16: // Run ADC Overlap self test
395 wakeup_sleep(TOTAL_IC);
396 error = (int8_t)LTC6812_run_adc_overlap(TOTAL_IC,BMS_IC);
397 print_overlap_results(error);
398 break;
399
400 case 17: // Run ADC Digital Redundancy self test
401 wakeup_sleep(TOTAL_IC);
402 error = LTC6812_run_adc_redundancy_st(ADC_CONVERSION_MODE,AUX,TOTAL_IC, BMS_IC);
403 print_digital_redundancy_errors(AUX, error);
404
405 wakeup_sleep(TOTAL_IC);
406 error = LTC6812_run_adc_redundancy_st(ADC_CONVERSION_MODE,STAT,TOTAL_IC, BMS_IC);
407 print_digital_redundancy_errors(STAT, error);
408 break;
409
410 case 18: // Run open wire self test for single cell detection
411 wakeup_sleep(TOTAL_IC);
412 LTC6812_run_openwire_single(TOTAL_IC, BMS_IC);
413 print_open_wires();
414 break;
415
416 case 19: // Run open wire self test for multiple cell and two consecutive cells detection
417 wakeup_sleep(TOTAL_IC);
418 LTC6812_run_openwire_multi(TOTAL_IC, BMS_IC);
419 break;
420
421 case 20: // Open wire Diagnostic for Auxiliary Measurements
422 wakeup_sleep(TOTAL_IC);
423 LTC6812_run_gpio_openwire(TOTAL_IC, BMS_IC);
424 print_open_wires();
425 break;
426
427 case 21: //print pec counter
428 print_pec_error_count();
429 break;
430
431 case 22: // Reset pec counter
432 LTC6812_reset_crc_count(TOTAL_IC,BMS_IC);
433 print_pec_error_count();
434 break;
435
436 case 23: // Enable a discharge transistor
437 s_pin_read = select_s_pin();
438 wakeup_sleep(TOTAL_IC);
439 LTC6812_set_discharge(s_pin_read,TOTAL_IC,BMS_IC);
440 LTC6812_wrcfg(TOTAL_IC,BMS_IC);
441 LTC6812_wrcfgb(TOTAL_IC,BMS_IC);
442 print_wrconfig();
443 print_wrconfigb();
444 wakeup_idle(TOTAL_IC);
445 error = LTC6812_rdcfg(TOTAL_IC,BMS_IC);
446 check_error(error);
447 error = LTC6812_rdcfgb(TOTAL_IC,BMS_IC);
448 check_error(error);
449 print_rxconfig();
450 print_rxconfigb();
451 break;
452
453 case 24: // Clear all discharge transistors
454 wakeup_sleep(TOTAL_IC);
455 LTC6812_clear_discharge(TOTAL_IC,BMS_IC);
456 LTC6812_wrcfg(TOTAL_IC,BMS_IC);
457 LTC6812_wrcfgb(TOTAL_IC,BMS_IC);
458 print_wrconfig();
459 print_wrconfigb();
460 wakeup_idle(TOTAL_IC);
461 error = LTC6812_rdcfg(TOTAL_IC,BMS_IC);
462 check_error(error);
463 error = LTC6812_rdcfgb(TOTAL_IC,BMS_IC);
464 check_error(error);
465 print_rxconfig();
466 print_rxconfigb();
467 break;
468
469 case 25:// Write read pwm configuration
470 /*****************************************************
471 PWM configuration data.
472 1)Set the corresponding DCC bit to one for pwm operation.
473 2)Set the DCTO bits to the required discharge time.
474 3)Choose the value to be configured depending on the
475 required duty cycle.
476 Refer to the data sheet.
477 *******************************************************/
478 wakeup_sleep(TOTAL_IC);
479
480 for (uint8_t current_ic = 0; current_ic<TOTAL_IC;current_ic++)
481 {
482 BMS_IC[current_ic].pwm.tx_data[0]= 0x88; //Duty cycle for S pin 2 and 1
483 BMS_IC[current_ic].pwm.tx_data[1]= 0x88; //Duty cycle for S pin 4 and 3
484 BMS_IC[current_ic].pwm.tx_data[2]= 0x88; //Duty cycle for S pin 6 and 5
485 BMS_IC[current_ic].pwm.tx_data[3]= 0x88; //Duty cycle for S pin 8 and 7
486 BMS_IC[current_ic].pwm.tx_data[4]= 0x88; //Duty cycle for S pin 10 and 9
487 BMS_IC[current_ic].pwm.tx_data[5]= 0x88; //Duty cycle for S pin 12 and 11
488 }
489
490 LTC6812_wrpwm(TOTAL_IC,0,BMS_IC); //Write pwm configuration
491
492 for (uint8_t current_ic = 0; current_ic<TOTAL_IC;current_ic++)
493 {
494 BMS_IC[current_ic].pwmb.tx_data[0]= 0x88; //Duty cycle for S pin 14 and 13
495 BMS_IC[current_ic].pwmb.tx_data[1]= 0x08; //Duty cycle for S pin 15
496 BMS_IC[current_ic].pwmb.tx_data[2]= 0x00;
497 BMS_IC[current_ic].pwmb.tx_data[3]= 0x00;
498 BMS_IC[current_ic].pwmb.tx_data[4]= 0x00;
499 BMS_IC[current_ic].pwmb.tx_data[5]= 0x00;
500 }
501 wakeup_idle(TOTAL_IC);
502 LTC6812_wrpsb(TOTAL_IC,BMS_IC); // Write PWM/S control register group B
503 print_wrpwm();
504 print_wrpsb(PWM);
505
506 wakeup_idle(TOTAL_IC);
507 error=LTC6812_rdpwm(TOTAL_IC,0,BMS_IC); // Read pwm configuration
508 check_error(error);
509
510 error=LTC6812_rdpsb(TOTAL_IC,BMS_IC); // Read PWM/S Control Register Group
511 check_error(error);
512 print_rxpwm();
513 print_rxpsb(PWM);
514 break;
515
516 case 26: // Write and read S Control Register Group
517 /**************************************************************************************
518 S pin control.
519 1)Ensure that the pwm is set according to the requirement using the previous case.
520 2)Choose the value depending on the required number of pulses on S pin.
521 Refer to the data sheet.
522 ***************************************************************************************/
523 wakeup_sleep(TOTAL_IC);
524 for (uint8_t current_ic = 0; current_ic<TOTAL_IC;current_ic++)
525 {
526 BMS_IC[current_ic].sctrl.tx_data[0]= 0xFF; // No. of high pulses on S pin 2 and 1
527 BMS_IC[current_ic].sctrl.tx_data[1]= 0xFF; // No. of high pulses on S pin 4 and 3
528 BMS_IC[current_ic].sctrl.tx_data[2]= 0xFF; // No. of high pulses on S pin 6 and 5
529 BMS_IC[current_ic].sctrl.tx_data[3]= 0xFF; // No. of high pulses on S pin 8 and 7
530 BMS_IC[current_ic].sctrl.tx_data[4]= 0xFF; // No. of high pulses on S pin 10 and 9
531 BMS_IC[current_ic].sctrl.tx_data[5]= 0xFF; // No. of high pulses on S pin 12 and 11
532 }
533
534 LTC6812_wrsctrl(TOTAL_IC,streg,BMS_IC);// Write S Control Register Group
535
536 for (uint8_t current_ic = 0; current_ic<TOTAL_IC;current_ic++)
537 {
538 BMS_IC[current_ic].sctrlb.tx_data[0]= 0x00;
539 BMS_IC[current_ic].sctrlb.tx_data[1]= 0x00;
540 BMS_IC[current_ic].sctrlb.tx_data[2]= 0x00;
541 BMS_IC[current_ic].sctrlb.tx_data[3]= 0xFF; // No. of high pulses on S pin 14 and 13
542 BMS_IC[current_ic].sctrlb.tx_data[4]= 0x0F; // No. of high pulses on S pin 15
543 BMS_IC[current_ic].sctrlb.tx_data[5]= 0x00;
544 }
545 wakeup_idle(TOTAL_IC);
546 LTC6812_wrpsb(TOTAL_IC,BMS_IC); // Write PWM/S control register group B
547 print_wrsctrl();
548 print_wrpsb(SCTL);
549
550 wakeup_idle(TOTAL_IC);
551 LTC6812_stsctrl(); // start S Control pulsing
552
553 wakeup_idle(TOTAL_IC);
554 error=LTC6812_rdsctrl(TOTAL_IC,streg,BMS_IC); // Read S Control Register Group
555 check_error(error);
556
557 error=LTC6812_rdpsb(TOTAL_IC,BMS_IC); // Read PWM/S Control Register Group
558 check_error(error);
559 print_rxsctrl();
560 print_rxpsb(SCTL);
561 break;
562
563 case 27: // Clear S Control Register Group
564 wakeup_sleep(TOTAL_IC);
565 LTC6812_clrsctrl();
566 wakeup_idle(TOTAL_IC);
567 error=LTC6812_rdsctrl(TOTAL_IC,streg,BMS_IC);
568 check_error(error);
569 LTC6812_rdpsb(TOTAL_IC,BMS_IC);
570 print_rxsctrl();
571 print_rxpsb(SCTL);
572 break;
573
574 case 28:// SPI Communication
575 /************************************************************
576 Ensure to set the GPIO bits to 1 in the CFG register group.
577 *************************************************************/
578 for (uint8_t current_ic = 0; current_ic<TOTAL_IC;current_ic++)
579 {
580 //Communication control bits and communication data bytes. Refer to the data sheet.
581 BMS_IC[current_ic].com.tx_data[0]= 0x81; // Icom CSBM Low(8) + data D0 (0x11)
582 BMS_IC[current_ic].com.tx_data[1]= 0x10; // Fcom CSBM Low(0)
583 BMS_IC[current_ic].com.tx_data[2]= 0xA2; // Icom CSBM Falling Edge (A) + data D1 (0x25)
584 BMS_IC[current_ic].com.tx_data[3]= 0x50; // Fcom CSBM Low(0)
585 BMS_IC[current_ic].com.tx_data[4]= 0xA1; // Icom CSBM Falling Edge (A) + data D2 (0x17)
586 BMS_IC[current_ic].com.tx_data[5]= 0x79; // Fcom CSBM High(9)
587 }
588 wakeup_sleep(TOTAL_IC);
589 LTC6812_wrcomm(TOTAL_IC,BMS_IC);
590 print_wrcomm();
591
592 wakeup_idle(TOTAL_IC);
593 LTC6812_stcomm(3);
594
595 wakeup_idle(TOTAL_IC);
596 error = LTC6812_rdcomm(TOTAL_IC,BMS_IC);
597 check_error(error);
598 print_rxcomm();
599 break;
600
601 case 29: // Write byte I2C Communication on the GPIO Ports(using I2C eeprom 24LC025)
602 /************************************************************
603 Ensure to set the GPIO bits to 1 in the CFG register group.
604 *************************************************************/
605 for (uint8_t current_ic = 0; current_ic<TOTAL_IC;current_ic++)
606 {
607 //Communication control bits and communication data bytes. Refer to the data sheet.
608 BMS_IC[current_ic].com.tx_data[0]= 0x6A; // Icom Start(6) + I2C_address D0 (0xA0)
609 BMS_IC[current_ic].com.tx_data[1]= 0x08; // Fcom master NACK(8)
610 BMS_IC[current_ic].com.tx_data[2]= 0x00; // Icom Blank (0) + eeprom address D1 (0x00)
611 BMS_IC[current_ic].com.tx_data[3]= 0x08; // Fcom master NACK(8)
612 BMS_IC[current_ic].com.tx_data[4]= 0x01; // Icom Blank (0) + data D2 (0x12)
613 BMS_IC[current_ic].com.tx_data[5]= 0x29; // Fcom master NACK + Stop(9)
614 }
615 wakeup_sleep(TOTAL_IC);
616 LTC6812_wrcomm(TOTAL_IC,BMS_IC); // write to comm register
617 print_wrcomm(); // print transmitted data from the comm register
618
619 wakeup_idle(TOTAL_IC);
620 LTC6812_stcomm(3); // data length=3 // initiates communication between master and the I2C slave
621
622 wakeup_idle(TOTAL_IC);
623 error = LTC6812_rdcomm(TOTAL_IC,BMS_IC); // read from comm register
624 check_error(error);
625 print_rxcomm(); // print received data into the comm register
626 break;
627
628 case 30: // Read byte data I2C Communication on the GPIO Ports(using I2C eeprom 24LC025)
629 /************************************************************
630 Ensure to set the GPIO bits to 1 in the CFG register group.
631 *************************************************************/
632 for (uint8_t current_ic = 0; current_ic<TOTAL_IC;current_ic++)
633 {
634 //Communication control bits and communication data bytes. Refer to the data sheet.
635 BMS_IC[current_ic].com.tx_data[0]= 0x6A; // Icom Start (6) + I2C_address D0 (A0) (Write operation to set the word address)
636 BMS_IC[current_ic].com.tx_data[1]= 0x08; // Fcom master NACK(8)
637 BMS_IC[current_ic].com.tx_data[2]= 0x00; // Icom Blank (0) + eeprom address(word address) D1 (0x00)
638 BMS_IC[current_ic].com.tx_data[3]= 0x08; // Fcom master NACK(8)
639 BMS_IC[current_ic].com.tx_data[4]= 0x6A; // Icom Start (6) + I2C_address D2 (0xA1)(Read operation)
640 BMS_IC[current_ic].com.tx_data[5]= 0x18; // Fcom master NACK(8)
641 }
642 wakeup_sleep(TOTAL_IC);
643 LTC6812_wrcomm(TOTAL_IC,BMS_IC); // write to comm register
644
645 wakeup_idle(TOTAL_IC);
646 LTC6812_stcomm(3); // data length=3 // initiates communication between master and the I2C slave
647
648 for (uint8_t current_ic = 0; current_ic<TOTAL_IC;current_ic++)
649 {
650 //Communication control bits and communication data bytes. Refer to the data sheet.
651 BMS_IC[current_ic].com.tx_data[0]= 0x0F; // Icom Blank (0) + data D0 (FF)
652 BMS_IC[current_ic].com.tx_data[1]= 0xF9; // Fcom master NACK + Stop(9)
653 BMS_IC[current_ic].com.tx_data[2]= 0x7F; // Icom No Transmit (7) + data D1 (FF)
654 BMS_IC[current_ic].com.tx_data[3]= 0xF9; // Fcom master NACK + Stop(9)
655 BMS_IC[current_ic].com.tx_data[4]= 0x7F; // Icom No Transmit (7) + data D2 (FF)
656 BMS_IC[current_ic].com.tx_data[5]= 0xF9; // Fcom master NACK + Stop(9)
657 }
658 wakeup_idle(TOTAL_IC);
659 LTC6812_wrcomm(TOTAL_IC,BMS_IC); // write to comm register
660
661 wakeup_idle(TOTAL_IC);
662 LTC6812_stcomm(1); // data length=1 // initiates communication between master and the I2C slave
663
664 wakeup_idle(TOTAL_IC);
665 error = LTC6812_rdcomm(TOTAL_IC,BMS_IC); // read from comm register
666 check_error(error);
667 print_rxcomm(); // print received data from the comm register
668 break;
669
670 case 31: // Enable MUTE
671 wakeup_sleep(TOTAL_IC);
672 LTC6812_mute();
673 wakeup_idle(TOTAL_IC);
674 error = LTC6812_rdcfgb(TOTAL_IC,BMS_IC);
675 check_error(error);
676 check_mute_bit();
677 break;
678
679 case 32: // To enable UNMUTE
680 wakeup_sleep(TOTAL_IC);
681 LTC6812_unmute();
682 wakeup_idle(TOTAL_IC);
683 error = LTC6812_rdcfgb(TOTAL_IC,BMS_IC);
684 check_error(error);
685 check_mute_bit();
686 break;
687
688 case 33: // Set and reset the gpio pins(to drive output on gpio pins)
689 /***********************************************************************
690 Please ensure you have set the GPIO bits according to your requirement
691 in the configuration register.( check the global variable GPIOBITS_A )
692 ************************************************************************/
693 wakeup_sleep(TOTAL_IC);
694 for (uint8_t current_ic = 0; current_ic<TOTAL_IC;current_ic++)
695 {
696 LTC6812_set_cfgr(current_ic,BMS_IC,REFON,ADCOPT,GPIOBITS_A,DCCBITS_A, DCTOBITS, UV, OV);
697 LTC6812_set_cfgrb(current_ic,BMS_IC,FDRF,DTMEN,PSBits,GPIOBITS_B,DCCBITS_B);
698 }
699 wakeup_idle(TOTAL_IC);
700 LTC6812_wrcfg(TOTAL_IC,BMS_IC);
701 LTC6812_wrcfgb(TOTAL_IC,BMS_IC);
702 print_wrconfig();
703 print_wrconfigb();
704 break;
705
706 case 'm': //prints menu
707 print_menu();
708 break;
709
710 default:
711 char str_error[]="Incorrect Option \n";
712 serial_print_text(str_error);
713 break;
714 }
715 }
716
717 /*!**********************************************************************************************************************************************
718 \brief For writing/reading configuration data or measuring cell voltages or reading aux register or reading status register in a continuous loop
719 @return void
720 *************************************************************************************************************************************************/
721 void measurement_loop(uint8_t datalog_en)
722 {
723 int8_t error = 0;
724 char input = 0;
725
726 Serial.println(F("Transmit 'm' to quit"));
727
728 while (input != 'm')
729 {
730 if (Serial.available() > 0)
731 {
732 input = read_char();
733 }
734
735 if (WRITE_CONFIG == ENABLED)
736 {
737 wakeup_idle(TOTAL_IC);
738 LTC6812_wrcfg(TOTAL_IC,BMS_IC);
739 LTC6812_wrcfgb(TOTAL_IC,BMS_IC);
740 print_wrconfig();
741 print_wrconfigb();
742 }
743
744 if (READ_CONFIG == ENABLED)
745 {
746 wakeup_idle(TOTAL_IC);
747 error = LTC6812_rdcfg(TOTAL_IC,BMS_IC);
748 check_error(error);
749 error = LTC6812_rdcfgb(TOTAL_IC,BMS_IC);
750 check_error(error);
751 print_rxconfig();
752 print_rxconfigb();
753 }
754
755 if (MEASURE_CELL == ENABLED)
756 {
757 wakeup_idle(TOTAL_IC);
758 LTC6812_adcv(ADC_CONVERSION_MODE,ADC_DCP,CELL_CH_TO_CONVERT);
759 LTC6812_pollAdc();
760 wakeup_idle(TOTAL_IC);
761 error = LTC6812_rdcv(0, TOTAL_IC,BMS_IC);
762 check_error(error);
763 print_cells(datalog_en);
764 }
765
766 if (MEASURE_AUX == ENABLED)
767 {
768 wakeup_idle(TOTAL_IC);
769 LTC6812_adax(ADC_CONVERSION_MODE , AUX_CH_ALL);
770 LTC6812_pollAdc();
771 wakeup_idle(TOTAL_IC);
772 error = LTC6812_rdaux(0,TOTAL_IC,BMS_IC); // Set to read back all aux registers
773 check_error(error);
774 print_aux(datalog_en);
775 }
776
777 if (MEASURE_STAT == ENABLED)
778 {
779 wakeup_idle(TOTAL_IC);
780 LTC6812_adstat(ADC_CONVERSION_MODE, STAT_CH_ALL);
781 LTC6812_pollAdc();
782 wakeup_idle(TOTAL_IC);
783 error = LTC6812_rdstat(0,TOTAL_IC,BMS_IC); // Set to read back all aux registers
784 check_error(error);
785 print_stat();
786 }
787
788 if(PRINT_PEC == ENABLED)
789 {
790 print_pec_error_count();
791 }
792
793 delay(MEASUREMENT_LOOP_TIME);
794 }
795 }
796
797 /*!*********************************
798 \brief Prints the main menu
799 @return void
800 ***********************************/
801 void print_menu(void)
802 {
803 Serial.println(F("List of LTC6812 Command:"));
804 Serial.println(F("Write and Read Configuration: 1 |Loop measurements with data-log output : 12 |Set Discharge: 23 "));
805 Serial.println(F("Read Configuration: 2 |Clear Registers: 13 |Clear Discharge: 24 "));
806 Serial.println(F("Start Cell Voltage Conversion: 3 |Run Mux Self Test: 14 |Write and Read of PWM : 25"));
807 Serial.println(F("Read Cell Voltages: 4 |Run ADC Self Test: 15 |Write and Read of S control : 26"));
808 Serial.println(F("Start Aux Voltage Conversion: 5 |ADC overlap Test : 16 |Clear S control register : 27"));
809 Serial.println(F("Read Aux Voltages: 6 |Run Digital Redundancy Test: 17 |SPI Communication : 28"));
810 Serial.println(F("Start Stat Voltage Conversion: 7 |Open Wire Test for single cell detection: 18 |I2C Communication Write to Slave :29"));
811 Serial.println(F("Read Stat Voltages: 8 |Open Wire Test for multiple cell or two consecutive cells detection:19 |I2C Communication Read from Slave :30"));
812 Serial.println(F("Start Combined Cell Voltage and GPIO1, GPIO2 Conversion: 9 |Open wire for Auxiliary Measurement: 20 |Enable MUTE : 31"));
813 Serial.println(F("Start Cell Voltage and Sum of cells : 10 |Print PEC Counter: 21 |Disable MUTE : 32"));
814 Serial.println(F("Loop Measurements: 11 |Reset PEC Counter: 22 |Set or reset the gpio pins: 33 \n "));
815 Serial.println(F("Print 'm' for menu"));
816 Serial.println(F("Please enter command: \n "));
817 }
818
819 /*!******************************************************************************
820 \brief Prints the Configuration Register A data that is going to be written to
821 the LTC6812 to the serial port.
822 @return void
823 ********************************************************************************/
824 void print_wrconfig(void)
825 {
826 int cfg_pec;
827 Serial.println(F("Written Configuration A Register: "));
828 for (int current_ic = 0; current_ic<TOTAL_IC; current_ic++)
829 {
830 Serial.print(F("CFGA IC "));
831 Serial.print(current_ic+1,DEC);
832 for(int i = 0;i<6;i++)
833 {
834 Serial.print(F(", 0x"));
835 serial_print_hex(BMS_IC[current_ic].config.tx_data[i]);
836 }
837 Serial.print(F(", Calculated PEC: 0x"));
838 cfg_pec = pec15_calc(6,&BMS_IC[current_ic].config.tx_data[0]);
839 serial_print_hex((uint8_t)(cfg_pec>>8));
840 Serial.print(F(", 0x"));
841 serial_print_hex((uint8_t)(cfg_pec));
842 Serial.println("\n");
843 }
844 }
845
846 /*!******************************************************************************
847 \brief Prints the Configuration Register B data that is going to be written to
848 the LTC6812 to the serial port.
849 @return void
850 ********************************************************************************/
851 void print_wrconfigb(void)
852 {
853 int cfg_pec;
854 Serial.println(F("Written Configuration B Register: "));
855 for (int current_ic = 0; current_ic<TOTAL_IC; current_ic++)
856 {
857 Serial.print(F("CFGB IC "));
858 Serial.print(current_ic+1,DEC);
859 for(int i = 0;i<6;i++)
860 {
861 Serial.print(F(", 0x"));
862 serial_print_hex(BMS_IC[current_ic].configb.tx_data[i]);
863 }
864 Serial.print(F(", Calculated PEC: 0x"));
865 cfg_pec = pec15_calc(6,&BMS_IC[current_ic].configb.tx_data[0]);
866 serial_print_hex((uint8_t)(cfg_pec>>8));
867 Serial.print(F(", 0x"));
868 serial_print_hex((uint8_t)(cfg_pec));
869 Serial.println("\n");
870 }
871 }
872
873 /*!*****************************************************************
874 \brief Prints the Configuration Register A data that was read back
875 from the LTC6812 to the serial port.
876 @return void
877 *******************************************************************/
878 void print_rxconfig(void)
879 {
880 Serial.println(F("Received Configuration A Register: "));
881 for (int current_ic=0; current_ic<TOTAL_IC; current_ic++)
882 {
883 Serial.print(F("CFGA IC "));
884 Serial.print(current_ic+1,DEC);
885 for(int i = 0; i < 6; i++)
886 {
887 Serial.print(F(", 0x"));
888 serial_print_hex(BMS_IC[current_ic].config.rx_data[i]);
889 }
890 Serial.print(F(", Received PEC: 0x"));
891 serial_print_hex(BMS_IC[current_ic].config.rx_data[6]);
892 Serial.print(F(", 0x"));
893 serial_print_hex(BMS_IC[current_ic].config.rx_data[7]);
894 Serial.println("\n");
895 }
896 }
897
898 /*!*****************************************************************
899 \brief Prints the Configuration Register B that was read back from
900 the LTC6812 to the serial port.
901 @return void
902 *******************************************************************/
903 void print_rxconfigb(void)
904 {
905 Serial.println(F("Received Configuration B Register: "));
906 for (int current_ic=0; current_ic<TOTAL_IC; current_ic++)
907 {
908 Serial.print(F("CFGB IC "));
909 Serial.print(current_ic+1,DEC);
910 for(int i = 0; i < 6; i++)
911 {
912 Serial.print(F(", 0x"));
913 serial_print_hex(BMS_IC[current_ic].configb.rx_data[i]);
914 }
915 Serial.print(F(", Received PEC: 0x"));
916 serial_print_hex(BMS_IC[current_ic].configb.rx_data[6]);
917 Serial.print(F(", 0x"));
918 serial_print_hex(BMS_IC[current_ic].configb.rx_data[7]);
919 Serial.println("\n");
920 }
921 }
922
923 /*!************************************************************
924 \brief Prints cell voltage to the serial port
925 @return void
926 *************************************************************/
927 void print_cells(uint8_t datalog_en)
928 {
929 for (int current_ic = 0 ; current_ic < TOTAL_IC; current_ic++)
930 {
931 if (datalog_en == 0)
932 {
933 Serial.print(" IC ");
934 Serial.print(current_ic+1,DEC);
935 Serial.print(", ");
936 for (int i=0; i<BMS_IC[0].ic_reg.cell_channels; i++)
937 {
938 Serial.print(" C");
939 Serial.print(i+1,DEC);
940 Serial.print(":");
941 Serial.print(BMS_IC[current_ic].cells.c_codes[i]*0.0001,4);
942 Serial.print(",");
943 }
944 Serial.println();
945 }
946 else
947 {
948 Serial.print(" Cells, ");
949 for (int i=0; i<BMS_IC[0].ic_reg.cell_channels; i++)
950 {
951 Serial.print(BMS_IC[current_ic].cells.c_codes[i]*0.0001,4);
952 Serial.print(",");
953 }
954 }
955 }
956 Serial.println("\n");
957 }
958
959 /*!****************************************************************************
960 \brief Prints GPIO voltage and Vref2 voltage code onto the serial port
961 @return void
962 *****************************************************************************/
963 void print_aux(uint8_t datalog_en)
964 {
965 for (int current_ic =0 ; current_ic < TOTAL_IC; current_ic++)
966 {
967 if (datalog_en == 0)
968 {
969 Serial.print(" IC ");
970 Serial.print(current_ic+1,DEC);
971
972
973 for (int i = 0; i < 5; i++)
974 {
975 Serial.print(F(" GPIO-"));
976 Serial.print(i+1,DEC);
977 Serial.print(":");
978 Serial.print(BMS_IC[current_ic].aux.a_codes[i]*0.0001,4);
979 Serial.print(",");
980 }
981
982 for (int i=6; i < 10; i++)
983 {
984 Serial.print(F(" GPIO-"));
985 Serial.print(i,DEC);
986 Serial.print(":");
987 Serial.print(BMS_IC[current_ic].aux.a_codes[i]*0.0001,4);
988 Serial.print(",");
989 }
990
991 Serial.print(F(" Vref2 :"));
992 Serial.print(BMS_IC[current_ic].aux.a_codes[5]*0.0001,4);
993 Serial.println();
994
995 Serial.print(" OV/UV Flags : 0x");
996 Serial.print((uint8_t)BMS_IC[current_ic].aux.a_codes[11],HEX);
997 Serial.println();
998 }
999 else
1000 {
1001 Serial.print(" AUX : ");
1002
1003 for (int i=0; i < 12; i++)
1004 {
1005 Serial.print(BMS_IC[current_ic].aux.a_codes[i]*0.0001,4);
1006 Serial.print(",");
1007 }
1008 }
1009 }
1010 Serial.println("\n");
1011 }
1012
1013 /*!****************************************************************************
1014 \brief Prints Status voltage codes and Vref2 voltage code onto the serial port
1015 @return void
1016 *****************************************************************************/
1017 void print_stat(void)
1018 {
1019 double itmp;
1020
1021 for (int current_ic =0 ; current_ic < TOTAL_IC; current_ic++)
1022 {
1023 Serial.print(F(" IC "));
1024 Serial.print(current_ic+1,DEC);
1025 Serial.print(F(" SOC:"));
1026 Serial.print(BMS_IC[current_ic].stat.stat_codes[0]*0.0001*30,4);
1027 Serial.print(F(","));
1028 Serial.print(F(" Itemp:"));
1029 itmp = (double)((BMS_IC[current_ic].stat.stat_codes[1] * (0.0001 / 0.0076)) - 276); //Internal Die Temperature(°C) = ITMP • (100 µV / 7.6mV)°C - 276°C
1030 Serial.print(itmp,4);
1031 Serial.print(F(","));
1032 Serial.print(F(" VregA:"));
1033 Serial.print(BMS_IC[current_ic].stat.stat_codes[2]*0.0001,4);
1034 Serial.print(F(","));
1035 Serial.print(F(" VregD:"));
1036 Serial.println(BMS_IC[current_ic].stat.stat_codes[3]*0.0001,4);
1037 Serial.print(F(" OV/UV Flags: 0x"));
1038 serial_print_hex(BMS_IC[current_ic].stat.flags[0]);
1039 Serial.print(F(", 0x"));
1040 serial_print_hex(BMS_IC[current_ic].stat.flags[1]);
1041 Serial.print(F(", 0x"));
1042 serial_print_hex(BMS_IC[current_ic].stat.flags[2]);
1043 Serial.print(F(",\t Mux fail flag:"));
1044 Serial.print(F(" 0x"));
1045 serial_print_hex(BMS_IC[current_ic].stat.mux_fail[0]);
1046 Serial.print(F(",\t THSD:"));
1047 Serial.print(F(" 0x"));
1048 serial_print_hex(BMS_IC[current_ic].stat.thsd[0]);
1049 Serial.println("\n");
1050 }
1051 }
1052
1053 /*!****************************************************************************
1054 \brief Prints GPIO voltage codes (GPIO 1 & 2)
1055 @return void
1056 *****************************************************************************/
1057 void print_aux1(uint8_t datalog_en)
1058 {
1059
1060 for (int current_ic =0 ; current_ic < TOTAL_IC; current_ic++)
1061 {
1062 if (datalog_en == 0)
1063 {
1064 Serial.print(" IC ");
1065 Serial.print(current_ic+1,DEC);
1066 for (int i=0; i < 2; i++)
1067 {
1068 Serial.print(F(" GPIO-"));
1069 Serial.print(i+1,DEC);
1070 Serial.print(":");
1071 Serial.print(BMS_IC[current_ic].aux.a_codes[i]*0.0001,4);
1072 Serial.print(",");
1073 }
1074 }
1075 else
1076 {
1077 Serial.print("AUX, ");
1078
1079 for (int i=0; i < 6; i++)
1080 {
1081 Serial.print(BMS_IC[current_ic].aux.a_codes[i]*0.0001,4);
1082 Serial.print(",");
1083 }
1084 }
1085 }
1086 Serial.println("\n");
1087 }
1088
1089 /*!****************************************************************************
1090 \brief Prints Status voltage codes for SOC onto the serial port
1091 @return void
1092 *****************************************************************************/
1093 void print_sumofcells(void)
1094 {
1095 for (int current_ic =0 ; current_ic < TOTAL_IC; current_ic++)
1096 {
1097 Serial.print(F(" IC "));
1098 Serial.print(current_ic+1,DEC);
1099 Serial.print(F(": SOC:"));
1100 Serial.print(BMS_IC[current_ic].stat.stat_codes[0]*0.0001*30,4);
1101 Serial.print(F(","));
1102 }
1103 Serial.println("\n");
1104 }
1105
1106 /*!****************************************************************
1107 \brief Function to check the MUX fail bit in the Status Register
1108 @return void
1109 *******************************************************************/
1110 void check_mux_fail(void)
1111 {
1112 int8_t error = 0;
1113 for (int ic = 0; ic<TOTAL_IC; ic++)
1114 {
1115 Serial.print(" IC ");
1116 Serial.println(ic+1,DEC);
1117 if (BMS_IC[ic].stat.mux_fail[0] != 0) error++;
1118
1119 if (error==0) Serial.println(F("Mux Test: PASS \n"));
1120 else Serial.println(F("Mux Test: FAIL \n"));
1121 }
1122 }
1123
1124 /*!************************************************************
1125 \brief Prints Errors Detected during self test
1126 @return void
1127 *************************************************************/
1128 void print_selftest_errors(uint8_t adc_reg ,int8_t error)
1129 {
1130 if(adc_reg==1)
1131 {
1132 Serial.println("Cell ");
1133 }
1134 else if(adc_reg==2)
1135 {
1136 Serial.println("Aux ");
1137 }
1138 else if(adc_reg==3)
1139 {
1140 Serial.println("Stat ");
1141 }
1142 Serial.print(error, DEC);
1143 Serial.println(F(" : errors detected in Digital Filter and Memory \n"));
1144 }
1145
1146 /*!************************************************************
1147 \brief Prints the output of the ADC overlap test
1148 @return void
1149 *************************************************************/
1150 void print_overlap_results(int8_t error)
1151 {
1152 if (error==0) Serial.println(F("Overlap Test: PASS \n"));
1153 else Serial.println(F("Overlap Test: FAIL \n"));
1154 }
1155
1156 /*!************************************************************
1157 \brief Prints Errors Detected during Digital Redundancy test
1158 @return void
1159 *************************************************************/
1160 void print_digital_redundancy_errors(uint8_t adc_reg ,int8_t error)
1161 {
1162 if(adc_reg==2)
1163 {
1164 Serial.println("Aux ");
1165 }
1166 else if(adc_reg==3)
1167 {
1168 Serial.println("Stat ");
1169 }
1170
1171 Serial.print(error, DEC);
1172 Serial.println(F(" : errors detected in Measurement \n"));
1173 }
1174
1175 /*!****************************************************************************
1176 \brief Prints Open wire test results to the serial port
1177 @return void
1178 *****************************************************************************/
1179 void print_open_wires(void)
1180 {
1181 for (int current_ic =0 ; current_ic < TOTAL_IC; current_ic++)
1182 {
1183 if (BMS_IC[current_ic].system_open_wire == 65535)
1184 {
1185 Serial.print("No Opens Detected on IC ");
1186 Serial.print(current_ic+1, DEC);
1187 Serial.println();
1188 }
1189 else
1190 {
1191 Serial.print(F("There is an open wire on IC "));
1192 Serial.print(current_ic + 1,DEC);
1193 Serial.print(F(" Channel: "));
1194 Serial.println(BMS_IC[current_ic].system_open_wire);
1195 }
1196 }
1197 Serial.println("\n");
1198 }
1199
1200 /*!****************************************************************************
1201 \brief Function to print the number of PEC Errors
1202 @return void
1203 *****************************************************************************/
1204 void print_pec_error_count(void)
1205 {
1206 for (int current_ic=0; current_ic<TOTAL_IC; current_ic++)
1207 {
1208 Serial.println("");
1209 Serial.print(BMS_IC[current_ic].crc_count.pec_count,DEC);
1210 Serial.print(F(" : PEC Errors Detected on IC"));
1211 Serial.println(current_ic+1,DEC);
1212 }
1213 Serial.println("\n");
1214 }
1215
1216 /*!****************************************************
1217 \brief Function to select the S pin for discharge
1218 @return void
1219 ******************************************************/
1220 int8_t select_s_pin(void)
1221 {
1222 int8_t read_s_pin=0;
1223
1224 Serial.print(F("Please enter the Spin number: "));
1225 read_s_pin = (int8_t)read_int();
1226 Serial.println(read_s_pin);
1227 return(read_s_pin);
1228 }
1229
1230 /*!****************************************************************************
1231 \brief Prints data which is written on PWM register onto the serial port
1232 @return void
1233 *****************************************************************************/
1234 void print_wrpwm(void)
1235 {
1236 int pwm_pec;
1237
1238 Serial.println(F("Write PWM Register A: "));
1239 for (uint8_t current_ic = 0; current_ic<TOTAL_IC; current_ic++)
1240 {
1241 Serial.print(F("IC "));
1242 Serial.print(current_ic+1,DEC);
1243 for(int i = 0; i < 6; i++)
1244 {
1245 Serial.print(F(", 0x"));
1246 serial_print_hex(BMS_IC[current_ic].pwm.tx_data[i]);
1247 }
1248 Serial.print(F(", Calculated PEC: 0x"));
1249 pwm_pec = pec15_calc(6,&BMS_IC[current_ic].pwm.tx_data[0]);
1250 serial_print_hex((uint8_t)(pwm_pec>>8));
1251 Serial.print(F(", 0x"));
1252 serial_print_hex((uint8_t)(pwm_pec));
1253 Serial.println("\n");
1254 }
1255 }
1256
1257 /*!****************************************************************************
1258 \brief Prints received data from PWM register onto the serial port
1259 @return void
1260 *****************************************************************************/
1261 void print_rxpwm(void)
1262 {
1263 Serial.println(F("Receive PWM Register A data:"));
1264 for (uint8_t current_ic=0; current_ic<TOTAL_IC; current_ic++)
1265 {
1266 Serial.print(F("IC "));
1267 Serial.print(current_ic+1,DEC);
1268 for(int i = 0; i < 6; i++)
1269 {
1270 Serial.print(F(", 0x"));
1271 serial_print_hex(BMS_IC[current_ic].pwm.rx_data[i]);
1272 }
1273 Serial.print(F(", Received PEC: 0x"));
1274 serial_print_hex(BMS_IC[current_ic].pwm.rx_data[6]);
1275 Serial.print(F(", 0x"));
1276 serial_print_hex(BMS_IC[current_ic].pwm.rx_data[7]);
1277 Serial.println("\n");
1278 }
1279 }
1280
1281 /*!****************************************************************************
1282 \brief prints data which is written on S Control register
1283 @return void
1284 *****************************************************************************/
1285 void print_wrsctrl(void)
1286 {
1287 int sctrl_pec;
1288
1289 Serial.println(F("Written Data in Sctrl register A: "));
1290 for (int current_ic = 0; current_ic<TOTAL_IC; current_ic++)
1291 {
1292 Serial.print(F(" IC "));
1293 Serial.print(current_ic+1,DEC);
1294
1295 for(int i = 0; i < 6; i++)
1296 {
1297 Serial.print(F(", 0x"));
1298 serial_print_hex(BMS_IC[current_ic].sctrl.tx_data[i]);
1299 }
1300
1301 Serial.print(F(", Calculated PEC: 0x"));
1302 sctrl_pec = pec15_calc(6,&BMS_IC[current_ic].sctrl.tx_data[0]);
1303 serial_print_hex((uint8_t)(sctrl_pec>>8));
1304 Serial.print(F(", 0x"));
1305 serial_print_hex((uint8_t)(sctrl_pec));
1306 Serial.println("\n");
1307 }
1308 }
1309
1310 /*!****************************************************************************
1311 \brief Prints data which is read back from S Control register
1312 @return void
1313 *****************************************************************************/
1314 void print_rxsctrl(void)
1315 {
1316 Serial.println(F("Received Data from Sctrl register A:"));
1317 for (int current_ic=0; current_ic<TOTAL_IC; current_ic++)
1318 {
1319 Serial.print(F(" IC "));
1320 Serial.print(current_ic+1,DEC);
1321
1322 for(int i = 0; i < 6; i++)
1323 {
1324 Serial.print(F(", 0x"));
1325 serial_print_hex(BMS_IC[current_ic].sctrl.rx_data[i]);
1326 }
1327
1328 Serial.print(F(", Received PEC: 0x"));
1329 serial_print_hex(BMS_IC[current_ic].sctrl.rx_data[6]);
1330 Serial.print(F(", 0x"));
1331 serial_print_hex(BMS_IC[current_ic].sctrl.rx_data[7]);
1332 Serial.println("\n");
1333 }
1334 }
1335
1336 /*!****************************************************************************
1337 \brief Prints data which is written on PWM/S control register group B onto
1338 the serial port
1339 @return void
1340 *****************************************************************************/
1341 void print_wrpsb(uint8_t type)
1342 {
1343 int psb_pec=0;
1344
1345 Serial.println(F("PWM/S control register group B: "));
1346 for (int current_ic = 0; current_ic<TOTAL_IC; current_ic++)
1347 {
1348 if(type == 1)
1349 {
1350 Serial.print(F("IC "));
1351 Serial.print(current_ic+1,DEC);
1352 Serial.print(F(": 0x"));
1353 serial_print_hex(BMS_IC[current_ic].pwmb.tx_data[0]);
1354 Serial.print(F(", 0x"));
1355 serial_print_hex(BMS_IC[current_ic].pwmb.tx_data[1]);
1356 Serial.print(F(", 0x"));
1357 serial_print_hex(BMS_IC[current_ic].pwmb.tx_data[2]);
1358 Serial.print(F(", 0x"));
1359 serial_print_hex(BMS_IC[current_ic].pwmb.tx_data[3]);
1360 Serial.print(F(", 0x"));
1361 serial_print_hex(BMS_IC[current_ic].pwmb.tx_data[4]);
1362 Serial.print(F(", 0x"));
1363 serial_print_hex(BMS_IC[current_ic].pwmb.tx_data[5]);
1364
1365 Serial.print(F(", Calculated PEC: 0x"));
1366 psb_pec = pec15_calc(6,&BMS_IC[current_ic].pwmb.tx_data[0]);
1367 serial_print_hex((uint8_t)(psb_pec>>8));
1368 Serial.print(F(", 0x"));
1369 serial_print_hex((uint8_t)(psb_pec));
1370 Serial.println("\n");
1371 }
1372 else if(type == 2)
1373 {
1374 Serial.print(F("IC "));
1375 Serial.print(current_ic+1,DEC);
1376 Serial.print(F(": 0x"));
1377 serial_print_hex(BMS_IC[current_ic].sctrlb.tx_data[0]);
1378 Serial.print(F(", 0x"));
1379 serial_print_hex(BMS_IC[current_ic].sctrlb.tx_data[1]);
1380 Serial.print(F(", 0x"));
1381 serial_print_hex(BMS_IC[current_ic].sctrlb.tx_data[2]);
1382 Serial.print(F(", 0x"));
1383 serial_print_hex(BMS_IC[current_ic].sctrlb.tx_data[3]);
1384 Serial.print(F(", 0x"));
1385 serial_print_hex(BMS_IC[current_ic].sctrlb.tx_data[4]);
1386 Serial.print(F(", 0x"));
1387 serial_print_hex(BMS_IC[current_ic].sctrlb.tx_data[5]);
1388
1389
1390 Serial.print(F(", Calculated PEC: 0x"));
1391 psb_pec = pec15_calc(6,&BMS_IC[current_ic].sctrlb.tx_data[0]);
1392 serial_print_hex((uint8_t)(psb_pec>>8));
1393 Serial.print(F(", 0x"));
1394 serial_print_hex((uint8_t)(psb_pec));
1395 Serial.println("\n");
1396 }
1397 }
1398 }
1399
1400
1401 /*!****************************************************************************
1402 \brief Prints received data from PWM/S control register group B
1403 onto the serial port
1404 @return void
1405 *****************************************************************************/
1406 void print_rxpsb(uint8_t type)
1407 {
1408 Serial.println(F("PWM/S control register group B:"));
1409 if(type == 1)
1410 {
1411 for (int current_ic=0; current_ic<TOTAL_IC; current_ic++)
1412 {
1413 Serial.print(F("IC "));
1414 Serial.print(current_ic+1,DEC);
1415 Serial.print(F(": 0x"));
1416 serial_print_hex(BMS_IC[current_ic].pwmb.rx_data[0]);
1417 Serial.print(F(", 0x"));
1418 serial_print_hex(BMS_IC[current_ic].pwmb.rx_data[1]);
1419 Serial.print(F(", 0x"));
1420 serial_print_hex(BMS_IC[current_ic].pwmb.rx_data[2]);
1421 Serial.print(F(", 0x"));
1422 serial_print_hex(BMS_IC[current_ic].pwmb.rx_data[3]);
1423 Serial.print(F(", 0x"));
1424 serial_print_hex(BMS_IC[current_ic].pwmb.rx_data[4]);
1425 Serial.print(F(", 0x"));
1426 serial_print_hex(BMS_IC[current_ic].pwmb.rx_data[5]);
1427
1428 Serial.print(F(", Received PEC: 0x"));
1429 serial_print_hex(BMS_IC[current_ic].pwmb.rx_data[6]);
1430 Serial.print(F(", 0x"));
1431 serial_print_hex(BMS_IC[current_ic].pwmb.rx_data[7]);
1432 Serial.println("\n");
1433 }
1434 }
1435 else if(type == 2)
1436 {
1437 for (int current_ic = 0; current_ic<TOTAL_IC; current_ic++)
1438 {
1439 Serial.print(F(" IC "));
1440 Serial.print(current_ic+1,DEC);
1441 Serial.print(F(": 0x"));
1442 serial_print_hex(BMS_IC[current_ic].sctrlb.rx_data[0]);
1443 Serial.print(F(", 0x"));
1444 serial_print_hex(BMS_IC[current_ic].sctrlb.rx_data[1]);
1445 Serial.print(F(", 0x"));
1446 serial_print_hex(BMS_IC[current_ic].sctrlb.rx_data[2]);
1447 Serial.print(F(", 0x"));
1448 serial_print_hex(BMS_IC[current_ic].sctrlb.rx_data[3]);
1449 Serial.print(F(", 0x"));
1450 serial_print_hex(BMS_IC[current_ic].sctrlb.rx_data[4]);
1451 Serial.print(F(", 0x"));
1452 serial_print_hex(BMS_IC[current_ic].sctrlb.rx_data[5]);
1453
1454 Serial.print(F(", Received PEC: 0x"));
1455 serial_print_hex(BMS_IC[current_ic].sctrlb.rx_data[6]);
1456 Serial.print(F(", 0x"));
1457 serial_print_hex(BMS_IC[current_ic].sctrlb.rx_data[7]);
1458 Serial.println("\n");
1459 }
1460 }
1461 }
1462
1463 /*!****************************************************************************
1464 \brief prints data which is written on COMM register onto the serial port
1465 @return void
1466 *****************************************************************************/
1467 void print_wrcomm(void)
1468 {
1469 int comm_pec;
1470
1471 Serial.println(F("Written Data in COMM Register: "));
1472 for (int current_ic = 0; current_ic<TOTAL_IC; current_ic++)
1473 {
1474 Serial.print(F(" IC- "));
1475 Serial.print(current_ic+1,DEC);
1476
1477 for(int i = 0; i < 6; i++)
1478 {
1479 Serial.print(F(", 0x"));
1480 serial_print_hex(BMS_IC[current_ic].com.tx_data[i]);
1481 }
1482 Serial.print(F(", Calculated PEC: 0x"));
1483 comm_pec = pec15_calc(6,&BMS_IC[current_ic].com.tx_data[0]);
1484 serial_print_hex((uint8_t)(comm_pec>>8));
1485 Serial.print(F(", 0x"));
1486 serial_print_hex((uint8_t)(comm_pec));
1487 Serial.println("\n");
1488 }
1489 }
1490
1491 /*!****************************************************************************
1492 \brief Prints received data from COMM register onto the serial port
1493 @return void
1494 *****************************************************************************/
1495 void print_rxcomm(void)
1496 {
1497 Serial.println(F("Received Data in COMM register:"));
1498 for (int current_ic=0; current_ic<TOTAL_IC; current_ic++)
1499 {
1500 Serial.print(F(" IC- "));
1501 Serial.print(current_ic+1,DEC);
1502
1503 for(int i = 0; i < 6; i++)
1504 {
1505 Serial.print(F(", 0x"));
1506 serial_print_hex(BMS_IC[current_ic].com.rx_data[i]);
1507 }
1508 Serial.print(F(", Received PEC: 0x"));
1509 serial_print_hex(BMS_IC[current_ic].com.rx_data[6]);
1510 Serial.print(F(", 0x"));
1511 serial_print_hex(BMS_IC[current_ic].com.rx_data[7]);
1512 Serial.println("\n");
1513 }
1514 }
1515
1516 /*!********************************************************************
1517 \brief Function to check the Mute bit in the Configuration Register
1518 @return void
1519 **********************************************************************/
1520 void check_mute_bit(void)
1521 {
1522 for (int current_ic = 0 ; current_ic < TOTAL_IC; current_ic++)
1523 {
1524 Serial.print(F(" Mute bit in Configuration Register B: 0x"));
1525 serial_print_hex((BMS_IC[current_ic].configb.rx_data[1])&(0x80));
1526 Serial.println("\n");
1527 }
1528 }
1529
1530 /*!****************************************************************************
1531 \brief Function to print the Conversion Time
1532 @return void
1533 *****************************************************************************/
1534 void print_conv_time(uint32_t conv_time)
1535 {
1536 uint16_t m_factor=1000; // to print in ms
1537
1538 Serial.print(F("Conversion completed in:"));
1539 Serial.print(((float)conv_time/m_factor), 1);
1540 Serial.println(F("ms \n"));
1541 }
1542
1543 /*!****************************************************************************
1544 \brief Function to check error flag and print PEC error message
1545 @return void
1546 *****************************************************************************/
1547 void check_error(int error)
1548 {
1549 if (error == -1)
1550 {
1551 Serial.println(F("A PEC error was detected in the received data"));
1552 }
1553 }
1554
1555 /*!************************************************************
1556 \brief Function to print text on serial monitor
1557 @return void
1558 *************************************************************/
1559 void serial_print_text(char data[])
1560 {
1561 Serial.println(data);
1562 }
1563
1564 /*!************************************************************
1565 \brief Function to print in HEX form
1566 @return void
1567 *************************************************************/
1568 void serial_print_hex(uint8_t data)
1569 {
1570 if (data< 16)
1571 {
1572 Serial.print("0");
1573 Serial.print((byte)data,HEX);
1574 }
1575 else
1576 Serial.print((byte)data,HEX);
1577 }
1578
1579 /*!************************************************************
1580 \brief Hex conversion constants
1581 *************************************************************/
1582 char hex_digits[16]=
1583 {
1584 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
1585 };
1586
1587 /*!************************************************************
1588 \brief Global Variables
1589 *************************************************************/
1590 char hex_to_byte_buffer[5]=
1591 {
1592 '0', 'x', '0', '0', '\0'
1593 };
1594
1595 /*!************************************************************
1596 \brief Buffer for ASCII hex to byte conversion
1597 *************************************************************/
1598 char byte_to_hex_buffer[3]=
1599 {
1600 '\0','\0','\0'
1601 };
1602
1603 /*!************************************************************
1604 \brief Read 2 hex characters from the serial buffer and convert them to a byte
1605 @return char data Read Data
1606 *************************************************************/
1607 char read_hex(void)
1608 {
1609 byte data;
1610 hex_to_byte_buffer[2]=get_char();
1611 hex_to_byte_buffer[3]=get_char();
1612 get_char();
1613 get_char();
1614 data = strtol(hex_to_byte_buffer, NULL, 0);
1615 return(data);
1616 }
1617
1618 /*!************************************************************
1619 \brief Read a command from the serial port
1620 @return char
1621 *************************************************************/
1622 char get_char(void)
1623 {
1624 // read a command from the serial port
1625 while (Serial.available() <= 0);
1626 return(Serial.read());
1627 }
print_wrsctrl
static void print_wrsctrl(void)
Definition: DC2350AA.ino:1285
LTC6812_diagn
void LTC6812_diagn()
Starts the Mux Decoder diagnostic self test Running this command will start the Mux Decoder Diagnosti...
Definition: LTC6812.cpp:256
LTC6812_wrcfg
void LTC6812_wrcfg(uint8_t total_ic, cell_asic *ic)
Write the LTC6812 configuration register.
Definition: LTC6812.cpp:88
cell_asic::sctrl
ic_register sctrl
Definition: LTC681x.h:180
SEL_REG_B
const uint8_t SEL_REG_B
Register Selection.
Definition: DC2350AA.ino:140
LTC681x.h
General BMS Library.
read_hex
char read_hex(void)
Definition: DC2350AA.ino:1607
LTC6812_adstat
void LTC6812_adstat(uint8_t MD, uint8_t CHST)
Start a Status ADC Conversion.
Definition: LTC6812.cpp:145
MEASURE_AUX
const uint8_t MEASURE_AUX
This is to ENABLED or DISABLED reading the auxiliary registers in a continuous loop.
Definition: DC2350AA.ino:152
wakeup_sleep
void wakeup_sleep()
Definition: LTC68041.cpp:969
LTC6812_run_adc_redundancy_st
int16_t LTC6812_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: LTC6812.cpp:357
BMS_IC
cell_asic BMS_IC[TOTAL_IC]
Global Battery Variable.
Definition: DC2350AA.ino:165
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
LTC6812_set_discharge
void LTC6812_set_discharge(int Cell, uint8_t total_ic, cell_asic *ic)
Helper function to set discharge bit in CFG register.
Definition: LTC6812.cpp:407
SEL_REG_A
const uint8_t SEL_REG_A
Register Selection.
Definition: DC2350AA.ino:139
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
LTC6812_run_adc_overlap
uint16_t LTC6812_run_adc_overlap(uint8_t total_ic, cell_asic *ic)
Helper Function that runs the ADC Overlap test.
Definition: LTC6812.cpp:323
LTC6812.h
LTC6812: Multicell Battery Monitors.
LTC6812_reset_crc_count
void LTC6812_reset_crc_count(uint8_t total_ic, cell_asic *ic)
Helper Function that resets the PEC error counters.
Definition: LTC6812.cpp:630
READ_CONFIG
const uint8_t READ_CONFIG
This is to ENABLED or DISABLED reading the configuration registers in a continuous loop...
Definition: DC2350AA.ino:150
PRINT_PEC
const uint8_t PRINT_PEC
This is to ENABLED or DISABLED printing the PEC Error Count in a continuous loop. ...
Definition: DC2350AA.ino:154
LTC6812_init_cfgb
void LTC6812_init_cfgb(uint8_t total_ic, cell_asic *ic)
Helper Function to initialize the CFGR B data structures.
Definition: LTC6812.cpp:688
LTC6812_run_gpio_openwire
void LTC6812_run_gpio_openwire(uint8_t total_ic, cell_asic *ic)
Runs open wire for GPIOs.
Definition: LTC6812.cpp:399
check_mute_bit
static void check_mute_bit(void)
Definition: DC2350AA.ino:1520
cell_asic::sctrlb
ic_register sctrlb
Definition: LTC681x.h:181
WRITE_CONFIG
const uint8_t WRITE_CONFIG
This is to ENABLED or DISABLED writing into to configuration registers in a continuous loop...
Definition: DC2350AA.ino:149
AUX
#define AUX
Definition: LTC6810.h:63
SEL_ALL_REG
const uint8_t SEL_ALL_REG
Register Selection.
Definition: DC2350AA.ino:138
serial_print_hex
static void serial_print_hex(uint8_t data)
Definition: DC2350AA.ino:1568
print_rxconfig
static void print_rxconfig(void)
Definition: DC2350AA.ino:878
ADC_OPT
const uint8_t ADC_OPT
ADC Mode option bit.
Definition: DC2350AA.ino:132
TOTAL_IC
const uint8_t TOTAL_IC
Number of ICs in the daisy chain.
Definition: DC2350AA.ino:129
ADC_CONVERSION_MODE
const uint8_t ADC_CONVERSION_MODE
ADC Mode.
Definition: DC2350AA.ino:133
ENABLED
#define ENABLED
Definition: DC2350AA.ino:83
hex_digits
char hex_digits[16]
Definition: DC2350AA.ino:1582
Linduino.h
Header File for Linduino Libraries and Demo Code.
cell_asic
Cell variable structure.
Definition: LTC681x.h:170
LTC6812_unmute
void LTC6812_unmute()
Clears the LTC6812 Mute Discharge.
Definition: LTC6812.cpp:614
check_mux_fail
static void check_mux_fail(void)
Definition: DC2350AA.ino:1110
LTC6812_rdstat
int8_t LTC6812_rdstat(uint8_t reg, uint8_t total_ic, cell_asic *ic)
Reads and parses the LTC6812 stat registers.
Definition: LTC6812.cpp:202
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
SCTL
#define SCTL
Definition: DC2350AA.ino:88
print_sumofcells
static void print_sumofcells(void)
Definition: DC2350AA.ino:1093
CELL
#define CELL
Definition: LTC6810.h:62
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
DATALOG_DISABLED
#define DATALOG_DISABLED
Definition: DC2350AA.ino:86
ADCOPT
bool ADCOPT
ADC Mode option bit.
Definition: DC2350AA.ino:171
OV_THRESHOLD
const uint16_t OV_THRESHOLD
Over voltage threshold ADC Code.
Definition: DC2350AA.ino:145
cell_asic::com
ic_register com
Definition: LTC681x.h:177
DISABLED
#define DISABLED
Definition: DC2350AA.ino:84
UV_THRESHOLD
const uint16_t UV_THRESHOLD
Under voltage threshold ADC Code.
Definition: DC2350AA.ino:146
LTC6812_rdsctrl
int8_t LTC6812_rdsctrl(uint8_t total_ic, uint8_t sctrl_reg, cell_asic *ic)
Reads sctrl registers of a LTC6812 daisy chain.
Definition: LTC6812.cpp:473
LTC6812_adcvsc
void LTC6812_adcvsc(uint8_t MD, uint8_t DCP)
Starts cell voltage and SOC conversion.
Definition: LTC6812.cpp:153
LTC6812_stsctrl
void LTC6812_stsctrl()
Start Sctrl data communication This command will start the sctrl pulse communication over the spins...
Definition: LTC6812.cpp:484
hex_to_byte_buffer
char hex_to_byte_buffer[5]
Definition: DC2350AA.ino:1590
data
union LT_union_int32_4bytes data
Definition: DC2094A.ino:138
measurement_loop
static void measurement_loop(uint8_t datalog_en)
Definition: DC2350AA.ino:721
get_char
char get_char(void)
Definition: DC2350AA.ino:1622
LTC6812_init_reg_limits
void LTC6812_init_reg_limits(uint8_t total_ic, cell_asic *ic)
Initialize the Register limits.
Definition: LTC6812.cpp:68
UV
static uint16_t UV
Under voltage Comparison Voltage.
Definition: DC2350AA.ino:174
DTMEN
bool DTMEN
Enable Discharge Timer Monitor.
Definition: DC2350AA.ino:181
STAT
#define STAT
Definition: LTC6810.h:64
loop
static void loop()
Definition: DC2350AA.ino:209
print_conv_time
static void print_conv_time(uint32_t conv_time)
Definition: DC2350AA.ino:1534
print_rxpwm
static void print_rxpwm(void)
Definition: DC2350AA.ino:1261
STAT_CH_TO_CONVERT
const uint8_t STAT_CH_TO_CONVERT
Channel Selection for ADC conversion.
Definition: DC2350AA.ino:137
LTC6812_run_openwire_multi
void LTC6812_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: LTC6812.cpp:393
OV
static uint16_t OV
Over voltage Comparison Voltage.
Definition: DC2350AA.ino:175
LTC6812_clrsctrl
void LTC6812_clrsctrl()
Clears the LTC6812 Sctrl registers.
Definition: LTC6812.cpp:494
run_command
static void run_command(uint32_t cmd)
Definition: DC2350AA.ino:231
GPIOBITS_A
bool GPIOBITS_A[5]
GPIO Pin Control // Gpio 1,2,3,4,5.
Definition: DC2350AA.ino:172
MEASUREMENT_LOOP_TIME
const uint16_t MEASUREMENT_LOOP_TIME
Loop Time in milliseconds(ms)
Definition: DC2350AA.ino:142
LTC6812_pollAdc
uint32_t LTC6812_pollAdc()
This function will block operation until the ADC has finished it&#39;s conversion.
Definition: LTC6812.cpp:219
LTC6812_set_cfgrb
void LTC6812_set_cfgrb(uint8_t nIC, cell_asic *ic, bool fdrf, bool dtmen, bool ps[2], bool gpiobits[4], bool dccbits[4])
Helper function to set appropriate bits in CFGR register based on bit function.
Definition: LTC6812.cpp:700
print_rxconfigb
static void print_rxconfigb(void)
Definition: DC2350AA.ino:903
LTC6812_clear_discharge
void LTC6812_clear_discharge(uint8_t total_ic, cell_asic *ic)
Clears all of the DCC bits in the configuration registers.
Definition: LTC6812.cpp:435
ADC_OPT_DISABLED
#define ADC_OPT_DISABLED
Definition: LTC681x.h:67
LTC6812_run_cell_adc_st
int16_t LTC6812_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: LTC6812.cpp:310
cell_asic::pwm
ic_register pwm
Definition: LTC681x.h:178
print_cells
static void print_cells(uint8_t datalog_en)
Definition: DC2350AA.ino:927
FDRF
bool FDRF
Force Digital Redundancy Failure Bit.
Definition: DC2350AA.ino:180
wakeup_idle
void wakeup_idle()
Definition: LTC68041.cpp:957
print_overlap_results
static void print_overlap_results(int8_t error)
Definition: DC2350AA.ino:1150
serial_print_text
static void serial_print_text(char data[])
Definition: DC2350AA.ino:1559
REG_ALL
#define REG_ALL
Definition: LTC681x.h:94
LTC6812_wrpwm
void LTC6812_wrpwm(uint8_t total_ic, uint8_t pwmReg, cell_asic *ic)
Write the LTC6812 PWM register.
Definition: LTC6812.cpp:444
print_wrcomm
static void print_wrcomm(void)
Definition: DC2350AA.ino:1467
REG_2
#define REG_2
Definition: LTC681x.h:96
check_error
static void check_error(int error)
Definition: DC2350AA.ino:1547
input
#define input(pin)
Return the state of pin "pin".
Definition: Linduino.h:79
print_wrpwm
static void print_wrpwm(void)
Definition: DC2350AA.ino:1234
LTC6812_run_openwire_single
void LTC6812_run_openwire_single(uint8_t total_ic, cell_asic *ic)
Runs the data sheet algorithm for open wire for single cell detection.
Definition: LTC6812.cpp:387
register_cfg::cell_channels
uint8_t cell_channels
Number of Cell channels.
Definition: LTC681x.h:161
print_stat
static void print_stat(void)
Definition: DC2350AA.ino:1017
LTC6812_init_cfg
void LTC6812_init_cfg(uint8_t total_ic, cell_asic *ic)
Helper Function to initialize the CFGR data structures.
Definition: LTC6812.cpp:636
CELL_CH_TO_CONVERT
const uint8_t CELL_CH_TO_CONVERT
Channel Selection for ADC conversion.
Definition: DC2350AA.ino:135
print_pec_error_count
static void print_pec_error_count(void)
Definition: DC2350AA.ino:1204
error
static int error
Definition: LT1054_voltage_mode_buck.ino:64
LTC6812_clrcell
void LTC6812_clrcell()
Clears the LTC6812 cell voltage registers.
Definition: LTC6812.cpp:229
LTC6812_adcvax
void LTC6812_adcvax(uint8_t MD, uint8_t DCP)
Starts cell voltage and GPIO 1&2 conversion.
Definition: LTC6812.cpp:161
MEASURE_CELL
const uint8_t MEASURE_CELL
This is to ENABLED or DISABLED measuring the cell voltages in a continuous loop.
Definition: DC2350AA.ino:151
LTC6812_adax
void LTC6812_adax(uint8_t MD, uint8_t CHG)
Start a GPIO and Vref2 Conversion.
Definition: LTC6812.cpp:137
LTC6812_rdcfgb
int8_t LTC6812_rdcfgb(uint8_t total_ic, cell_asic *ic)
Reads configuration registers of a LTC6812 daisy chain.
Definition: LTC6812.cpp:118
LTC6812_wrsctrl
void LTC6812_wrsctrl(uint8_t total_ic, uint8_t sctrl_reg, cell_asic *ic)
Write the LTC6812 Sctrl register.
Definition: LTC6812.cpp:464
pec15_calc
uint16_t pec15_calc(uint8_t len, uint8_t *data)
Definition: LTC68041.cpp:985
LTC6812_stcomm
void LTC6812_stcomm(uint8_t len)
Issues a stcomm command and clocks data out of the COMM register.
Definition: LTC6812.cpp:598
PSBits
bool PSBits[2]
Digital Redundancy Path Selection//ps-0,1.
Definition: DC2350AA.ino:182
GPIOBITS_B
bool GPIOBITS_B[4]
GPIO Pin Control // Gpio 6,7,8,9.
Definition: DC2350AA.ino:173
LT_SPI.h
LT_SPI: Routines to communicate with ATmega328P&#39;s hardware SPI port.
LTC6812_set_cfgr
void LTC6812_set_cfgr(uint8_t nIC, cell_asic *ic, bool refon, bool adcopt, bool gpio[5], bool dcc[12], bool dcto[4], uint16_t uv, uint16_t ov)
Helper function to set appropriate bits in CFGR register based on bit function.
Definition: LTC6812.cpp:641
print_open_wires
static void print_open_wires(void)
Definition: DC2350AA.ino:1179
DATALOG_ENABLED
#define DATALOG_ENABLED
Definition: DC2350AA.ino:85
print_menu
static void print_menu(void)
Definition: DC2350AA.ino:801
MD_7KHZ_3KHZ
#define MD_7KHZ_3KHZ
Definition: LTC681x.h:63
AUX_CH_TO_CONVERT
const uint8_t AUX_CH_TO_CONVERT
Channel Selection for ADC conversion.
Definition: DC2350AA.ino:136
LTC6812_mute
void LTC6812_mute()
Mutes the LTC6812 discharge transistors.
Definition: LTC6812.cpp:604
print_wrconfigb
static void print_wrconfigb(void)
Definition: DC2350AA.ino:851
LTC6812_rdcfg
int8_t LTC6812_rdcfg(uint8_t total_ic, cell_asic *ic)
Reads configuration registers of a LTC6812 daisy chain.
Definition: LTC6812.cpp:108
LTC6812_rdpsb
int8_t LTC6812_rdpsb(uint8_t total_ic, cell_asic *ic)
Reading pwm/s control register b.
Definition: LTC6812.cpp:526
print_selftest_errors
static void print_selftest_errors(uint8_t adc_reg, int8_t error)
Definition: DC2350AA.ino:1128
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
DCCBITS_B
bool DCCBITS_B[7]
Discharge cell switch //Dcc 0,13,14,15.
Definition: DC2350AA.ino:177
read_int
int32_t read_int()
Definition: UserInterface.cpp:93
LTC6812_rdpwm
int8_t LTC6812_rdpwm(uint8_t total_ic, uint8_t pwmReg, cell_asic *ic)
Reads pwm registers of a LTC6811 daisy chain.
Definition: LTC6812.cpp:453
MEASURE_STAT
const uint8_t MEASURE_STAT
This is to ENABLED or DISABLED reading the status registers in a continuous loop. ...
Definition: DC2350AA.ino:153
print_digital_redundancy_errors
static void print_digital_redundancy_errors(uint8_t adc_reg, int8_t error)
Definition: DC2350AA.ino:1160
select_s_pin
static int8_t select_s_pin(void)
Definition: DC2350AA.ino:1220
LTC6812_wrcfgb
void LTC6812_wrcfgb(uint8_t total_ic, cell_asic *ic)
Write the LTC6812 configuration register B.
Definition: LTC6812.cpp:100
LTC6812_clraux
void LTC6812_clraux()
Clears the LTC6812 Auxiliary registers.
Definition: LTC6812.cpp:239
print_rxsctrl
static void print_rxsctrl(void)
Definition: DC2350AA.ino:1314
DCP_DISABLED
#define DCP_DISABLED
Definition: LTC68041.h:183
print_wrconfig
static void print_wrconfig(void)
Definition: DC2350AA.ino:824
setup
static void setup()
Definition: DC2350AA.ino:188
print_aux1
static void print_aux1(void)
DCTOBITS
bool DCTOBITS[4]
Discharge time value //Dcto 0,1,2,3 // Programed for 4 min.
Definition: DC2350AA.ino:178
LTC6812_clrstat
void LTC6812_clrstat()
Clears the LTC6812 Stat registers.
Definition: LTC6812.cpp:250
i
static int i
Definition: DC2430A.ino:184
LTC6812_wrcomm
void LTC6812_wrcomm(uint8_t total_ic, cell_asic *ic)
Write the LTC6812 COMM register.
Definition: LTC6812.cpp:580
print_rxpsb
static void print_rxpsb(uint8_t type)
Definition: DC2350AA.ino:1406
REFON
bool REFON
Reference Powered Up Bit.
Definition: DC2350AA.ino:170
LTC6812_rdcomm
int8_t LTC6812_rdcomm(uint8_t total_ic, cell_asic *ic)
Reads comm registers of a LTC6812 daisy chain.
Definition: LTC6812.cpp:588
print_aux
static void print_aux(uint8_t datalog_en)
Definition: DC2350AA.ino:963
LTC6812_rdaux
int8_t LTC6812_rdaux(uint8_t reg, uint8_t total_ic, cell_asic *ic)
Reads and parses the LTC6812 auxiliary registers.
Definition: LTC6812.cpp:186
LTC6812_adcv
void LTC6812_adcv(uint8_t MD, uint8_t DCP, uint8_t CH)
Starts cell voltage conversion.
Definition: LTC6812.cpp:128
LTC6812_wrpsb
void LTC6812_wrpsb(uint8_t total_ic, cell_asic *ic)
Write the 6812 PWM/Sctrl Register B.
Definition: LTC6812.cpp:500
byte_to_hex_buffer
char byte_to_hex_buffer[3]
Definition: DC2350AA.ino:1598
ADC_DCP
const uint8_t ADC_DCP
Discharge Permitted.
Definition: DC2350AA.ino:134
read_char
int8_t read_char()
Definition: UserInterface.cpp:116
PWM
#define PWM
Definition: DC2350AA.ino:87
cell_asic::pwmb
ic_register pwmb
Definition: LTC681x.h:179
print_wrpsb
static void print_wrpsb(uint8_t type)
Definition: DC2350AA.ino:1341
DCCBITS_A
bool DCCBITS_A[12]
Discharge cell switch //Dcc 1,2,3,4,5,6,7,8,9,10,11,12.
Definition: DC2350AA.ino:176
LTC6812_rdcv
uint8_t LTC6812_rdcv(uint8_t reg, uint8_t total_ic, cell_asic *ic)
Reads and parses the LTC6812 cell voltage registers.
Definition: LTC6812.cpp:172
print_rxcomm
static void print_rxcomm(void)
Definition: DC2350AA.ino:1495