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);
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  {
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
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 
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
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
269  conv_time = LTC6812_pollAdc();
270  print_conv_time(conv_time);
271  break;
272 
273  case 4: // Read Cell Voltage Registers
275  error = LTC6812_rdcv(SEL_ALL_REG, TOTAL_IC,BMS_IC); // Set to read back all cell voltage registers
276  check_error(error);
278  break;
279 
280  case 5: // Start GPIO ADC Measurement
283  conv_time= LTC6812_pollAdc();
284  print_conv_time(conv_time);
285  break;
286 
287  case 6: // Read AUX Voltage Registers
289  error = LTC6812_rdaux(SEL_ALL_REG,TOTAL_IC,BMS_IC); // Set to read back all aux registers
290  check_error(error);
292  break;
293 
294  case 7: // Start Status ADC Measurement
297  conv_time=LTC6812_pollAdc();
298  print_conv_time(conv_time);
299  break;
300 
301  case 8: // Read Status registers
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
311  conv_time = LTC6812_pollAdc();
312  print_conv_time(conv_time);
314  error = LTC6812_rdcv(SEL_ALL_REG, TOTAL_IC,BMS_IC); // Set to read back all cell voltage registers
315  check_error(error);
318  error = LTC6812_rdaux(SEL_REG_A, TOTAL_IC,BMS_IC); // Set to read back aux register A
319  check_error(error);
321  break;
322 
323  case 10 : // Start Combined Cell Voltage and Sum of cells
326  conv_time = LTC6812_pollAdc();
327  print_conv_time(conv_time);
329  error = LTC6812_rdcv(SEL_ALL_REG, TOTAL_IC,BMS_IC); // Set to read back all cell voltage registers
330  check_error(error);
333  error = LTC6812_rdstat(SEL_REG_A,TOTAL_IC,BMS_IC); // Set to read back stat register A
334  check_error(error);
336  break;
337 
338  case 11: // Loop Measurements of configuration register or cell voltages or auxiliary register or status register without data-log output
340  LTC6812_wrcfg(TOTAL_IC,BMS_IC);
341  LTC6812_wrcfgb(TOTAL_IC,BMS_IC);
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
348  LTC6812_wrcfg(TOTAL_IC,BMS_IC);
349  LTC6812_wrcfgb(TOTAL_IC,BMS_IC);
351  print_menu();
352  break;
353 
354  case 13: // Clear all ADC measurement registers
356  LTC6812_clrcell();
357  LTC6812_clraux();
358  LTC6812_clrstat();
360  LTC6812_rdcv(SEL_ALL_REG, TOTAL_IC,BMS_IC); // read back all cell voltage registers
362  LTC6812_rdaux(SEL_ALL_REG,TOTAL_IC,BMS_IC); // read back all auxiliary registers
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
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;
381  print_selftest_errors(CELL, error);
382 
383  error = 0;
386  print_selftest_errors(AUX, error);
387 
388  error = 0;
391  print_selftest_errors(STAT, error);
392  break;
393 
394  case 16: // Run ADC Overlap self test
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
404 
408  break;
409 
410  case 18: // Run open wire self test for single cell detection
413  print_open_wires();
414  break;
415 
416  case 19: // Run open wire self test for multiple cell and two consecutive cells detection
419  break;
420 
421  case 20: // Open wire Diagnostic for Auxiliary Measurements
425  break;
426 
427  case 21: //print pec counter
429  break;
430 
431  case 22: // Reset pec counter
434  break;
435 
436  case 23: // Enable a discharge transistor
437  s_pin_read = select_s_pin();
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();
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
456  LTC6812_wrcfg(TOTAL_IC,BMS_IC);
457  LTC6812_wrcfgb(TOTAL_IC,BMS_IC);
458  print_wrconfig();
459  print_wrconfigb();
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  *******************************************************/
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);
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  {
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  {
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  {
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  {
759  LTC6812_pollAdc();
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  {
770  LTC6812_pollAdc();
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  {
781  LTC6812_pollAdc();
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  {
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  *****************************************************************************/
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 *************************************************************/
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  *****************************************************************************/
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  *****************************************************************************/
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  *****************************************************************************/
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 *************************************************************/
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  *************************************************************/
1591 {
1592  '0', 'x', '0', '0', '\0'
1593 };
1594 
1595 /*!************************************************************
1596  \brief Buffer for ASCII hex to byte conversion
1597  *************************************************************/
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;
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 }
static void print_wrsctrl(void)
Definition: DC2350AA.ino:1285
void LTC6812_diagn()
Starts the Mux Decoder diagnostic self test Running this command will start the Mux Decoder Diagnosti...
Definition: LTC6812.cpp:256
void LTC6812_wrcfg(uint8_t total_ic, cell_asic *ic)
Write the LTC6812 configuration register.
Definition: LTC6812.cpp:88
ic_register sctrl
Definition: LTC681x.h:180
const uint8_t SEL_REG_B
Register Selection.
Definition: DC2350AA.ino:140
General BMS Library.
char read_hex(void)
Definition: DC2350AA.ino:1607
void LTC6812_adstat(uint8_t MD, uint8_t CHST)
Start a Status ADC Conversion.
Definition: LTC6812.cpp:145
const uint8_t MEASURE_AUX
This is to ENABLED or DISABLED reading the auxiliary registers in a continuous loop.
Definition: DC2350AA.ino:152
void wakeup_sleep()
Definition: LTC68041.cpp:969
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
cell_asic BMS_IC[TOTAL_IC]
Global Battery Variable.
Definition: DC2350AA.ino:165
unsigned char user_command
uint8_t tx_data[6]
Stores data to be transmitted.
Definition: LTC681x.h:143
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
const uint8_t SEL_REG_A
Register Selection.
Definition: DC2350AA.ino:139
#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
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: Multicell Battery Monitors.
void LTC6812_reset_crc_count(uint8_t total_ic, cell_asic *ic)
Helper Function that resets the PEC error counters.
Definition: LTC6812.cpp:630
const uint8_t READ_CONFIG
This is to ENABLED or DISABLED reading the configuration registers in a continuous loop...
Definition: DC2350AA.ino:150
const uint8_t PRINT_PEC
This is to ENABLED or DISABLED printing the PEC Error Count in a continuous loop. ...
Definition: DC2350AA.ino:154
void LTC6812_init_cfgb(uint8_t total_ic, cell_asic *ic)
Helper Function to initialize the CFGR B data structures.
Definition: LTC6812.cpp:688
void LTC6812_run_gpio_openwire(uint8_t total_ic, cell_asic *ic)
Runs open wire for GPIOs.
Definition: LTC6812.cpp:399
static void check_mute_bit(void)
Definition: DC2350AA.ino:1520
ic_register sctrlb
Definition: LTC681x.h:181
const uint8_t WRITE_CONFIG
This is to ENABLED or DISABLED writing into to configuration registers in a continuous loop...
Definition: DC2350AA.ino:149
#define AUX
Definition: LTC6810.h:63
const uint8_t SEL_ALL_REG
Register Selection.
Definition: DC2350AA.ino:138
static void serial_print_hex(uint8_t data)
Definition: DC2350AA.ino:1568
static void print_rxconfig(void)
Definition: DC2350AA.ino:878
const uint8_t ADC_OPT
ADC Mode option bit.
Definition: DC2350AA.ino:132
const uint8_t TOTAL_IC
Number of ICs in the daisy chain.
Definition: DC2350AA.ino:129
const uint8_t ADC_CONVERSION_MODE
ADC Mode.
Definition: DC2350AA.ino:133
#define ENABLED
Definition: DC2350AA.ino:83
char hex_digits[16]
Definition: DC2350AA.ino:1582
Header File for Linduino Libraries and Demo Code.
Cell variable structure.
Definition: LTC681x.h:170
void LTC6812_unmute()
Clears the LTC6812 Mute Discharge.
Definition: LTC6812.cpp:614
static void check_mux_fail(void)
Definition: DC2350AA.ino:1110
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
#define STAT_CH_ALL
Definition: LTC681x.h:88
#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
#define SCTL
Definition: DC2350AA.ino:88
static void print_sumofcells(void)
Definition: DC2350AA.ino:1093
#define CELL
Definition: LTC6810.h:62
register_cfg ic_reg
Definition: LTC681x.h:185
void spi_enable(uint8_t spi_clock_divider)
Setup the processor for hardware SPI communication.
Definition: LT_SPI.cpp:160
#define DATALOG_DISABLED
Definition: DC2350AA.ino:86
bool ADCOPT
ADC Mode option bit.
Definition: DC2350AA.ino:171
const uint16_t OV_THRESHOLD
Over voltage threshold ADC Code.
Definition: DC2350AA.ino:145
ic_register com
Definition: LTC681x.h:177
#define DISABLED
Definition: DC2350AA.ino:84
const uint16_t UV_THRESHOLD
Under voltage threshold ADC Code.
Definition: DC2350AA.ino:146
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
void LTC6812_adcvsc(uint8_t MD, uint8_t DCP)
Starts cell voltage and SOC conversion.
Definition: LTC6812.cpp:153
void LTC6812_stsctrl()
Start Sctrl data communication This command will start the sctrl pulse communication over the spins...
Definition: LTC6812.cpp:484
char hex_to_byte_buffer[5]
Definition: DC2350AA.ino:1590
union LT_union_int32_4bytes data
Definition: DC2094A.ino:138
static void measurement_loop(uint8_t datalog_en)
Definition: DC2350AA.ino:721
char get_char(void)
Definition: DC2350AA.ino:1622
void LTC6812_init_reg_limits(uint8_t total_ic, cell_asic *ic)
Initialize the Register limits.
Definition: LTC6812.cpp:68
static uint16_t UV
Under voltage Comparison Voltage.
Definition: DC2350AA.ino:174
bool DTMEN
Enable Discharge Timer Monitor.
Definition: DC2350AA.ino:181
#define STAT
Definition: LTC6810.h:64
static void loop()
Definition: DC2350AA.ino:209
static void print_conv_time(uint32_t conv_time)
Definition: DC2350AA.ino:1534
static void print_rxpwm(void)
Definition: DC2350AA.ino:1261
const uint8_t STAT_CH_TO_CONVERT
Channel Selection for ADC conversion.
Definition: DC2350AA.ino:137
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
static uint16_t OV
Over voltage Comparison Voltage.
Definition: DC2350AA.ino:175
void LTC6812_clrsctrl()
Clears the LTC6812 Sctrl registers.
Definition: LTC6812.cpp:494
static void run_command(uint32_t cmd)
Definition: DC2350AA.ino:231
bool GPIOBITS_A[5]
GPIO Pin Control // Gpio 1,2,3,4,5.
Definition: DC2350AA.ino:172
const uint16_t MEASUREMENT_LOOP_TIME
Loop Time in milliseconds(ms)
Definition: DC2350AA.ino:142
uint32_t LTC6812_pollAdc()
This function will block operation until the ADC has finished it&#39;s conversion.
Definition: LTC6812.cpp:219
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
static void print_rxconfigb(void)
Definition: DC2350AA.ino:903
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
#define ADC_OPT_DISABLED
Definition: LTC681x.h:67
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
ic_register pwm
Definition: LTC681x.h:178
static void print_cells(uint8_t datalog_en)
Definition: DC2350AA.ino:927
bool FDRF
Force Digital Redundancy Failure Bit.
Definition: DC2350AA.ino:180
void wakeup_idle()
Definition: LTC68041.cpp:957
static void print_overlap_results(int8_t error)
Definition: DC2350AA.ino:1150
static void serial_print_text(char data[])
Definition: DC2350AA.ino:1559
#define REG_ALL
Definition: LTC681x.h:94
void LTC6812_wrpwm(uint8_t total_ic, uint8_t pwmReg, cell_asic *ic)
Write the LTC6812 PWM register.
Definition: LTC6812.cpp:444
static void print_wrcomm(void)
Definition: DC2350AA.ino:1467
#define REG_2
Definition: LTC681x.h:96
static void check_error(int error)
Definition: DC2350AA.ino:1547
#define input(pin)
Return the state of pin "pin".
Definition: Linduino.h:79
static void print_wrpwm(void)
Definition: DC2350AA.ino:1234
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
uint8_t cell_channels
Number of Cell channels.
Definition: LTC681x.h:161
static void print_stat(void)
Definition: DC2350AA.ino:1017
void LTC6812_init_cfg(uint8_t total_ic, cell_asic *ic)
Helper Function to initialize the CFGR data structures.
Definition: LTC6812.cpp:636
const uint8_t CELL_CH_TO_CONVERT
Channel Selection for ADC conversion.
Definition: DC2350AA.ino:135
static void print_pec_error_count(void)
Definition: DC2350AA.ino:1204
static int error
void LTC6812_clrcell()
Clears the LTC6812 cell voltage registers.
Definition: LTC6812.cpp:229
void LTC6812_adcvax(uint8_t MD, uint8_t DCP)
Starts cell voltage and GPIO 1&2 conversion.
Definition: LTC6812.cpp:161
const uint8_t MEASURE_CELL
This is to ENABLED or DISABLED measuring the cell voltages in a continuous loop.
Definition: DC2350AA.ino:151
void LTC6812_adax(uint8_t MD, uint8_t CHG)
Start a GPIO and Vref2 Conversion.
Definition: LTC6812.cpp:137
int8_t LTC6812_rdcfgb(uint8_t total_ic, cell_asic *ic)
Reads configuration registers of a LTC6812 daisy chain.
Definition: LTC6812.cpp:118
void LTC6812_wrsctrl(uint8_t total_ic, uint8_t sctrl_reg, cell_asic *ic)
Write the LTC6812 Sctrl register.
Definition: LTC6812.cpp:464
uint16_t pec15_calc(uint8_t len, uint8_t *data)
Definition: LTC68041.cpp:985
void LTC6812_stcomm(uint8_t len)
Issues a stcomm command and clocks data out of the COMM register.
Definition: LTC6812.cpp:598
bool PSBits[2]
Digital Redundancy Path Selection//ps-0,1.
Definition: DC2350AA.ino:182
bool GPIOBITS_B[4]
GPIO Pin Control // Gpio 6,7,8,9.
Definition: DC2350AA.ino:173
LT_SPI: Routines to communicate with ATmega328P&#39;s hardware SPI port.
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
static void print_open_wires(void)
Definition: DC2350AA.ino:1179
#define DATALOG_ENABLED
Definition: DC2350AA.ino:85
static void print_menu(void)
Definition: DC2350AA.ino:801
#define MD_7KHZ_3KHZ
Definition: LTC681x.h:63
const uint8_t AUX_CH_TO_CONVERT
Channel Selection for ADC conversion.
Definition: DC2350AA.ino:136
void LTC6812_mute()
Mutes the LTC6812 discharge transistors.
Definition: LTC6812.cpp:604
static void print_wrconfigb(void)
Definition: DC2350AA.ino:851
int8_t LTC6812_rdcfg(uint8_t total_ic, cell_asic *ic)
Reads configuration registers of a LTC6812 daisy chain.
Definition: LTC6812.cpp:108
int8_t LTC6812_rdpsb(uint8_t total_ic, cell_asic *ic)
Reading pwm/s control register b.
Definition: LTC6812.cpp:526
static void print_selftest_errors(uint8_t adc_reg, int8_t error)
Definition: DC2350AA.ino:1128
void quikeval_SPI_connect()
Connect SPI pins to QuikEval connector through the Linduino MUX. This will disconnect I2C...
Definition: LT_SPI.cpp:138
#define REG_1
Definition: LTC681x.h:95
bool DCCBITS_B[7]
Discharge cell switch //Dcc 0,13,14,15.
Definition: DC2350AA.ino:177
int32_t read_int()
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
const uint8_t MEASURE_STAT
This is to ENABLED or DISABLED reading the status registers in a continuous loop. ...
Definition: DC2350AA.ino:153
static void print_digital_redundancy_errors(uint8_t adc_reg, int8_t error)
Definition: DC2350AA.ino:1160
static int8_t select_s_pin(void)
Definition: DC2350AA.ino:1220
void LTC6812_wrcfgb(uint8_t total_ic, cell_asic *ic)
Write the LTC6812 configuration register B.
Definition: LTC6812.cpp:100
void LTC6812_clraux()
Clears the LTC6812 Auxiliary registers.
Definition: LTC6812.cpp:239
static void print_rxsctrl(void)
Definition: DC2350AA.ino:1314
#define DCP_DISABLED
Definition: LTC68041.h:183
static void print_wrconfig(void)
Definition: DC2350AA.ino:824
static void setup()
Definition: DC2350AA.ino:188
static void print_aux1(void)
bool DCTOBITS[4]
Discharge time value //Dcto 0,1,2,3 // Programed for 4 min.
Definition: DC2350AA.ino:178
void LTC6812_clrstat()
Clears the LTC6812 Stat registers.
Definition: LTC6812.cpp:250
static int i
Definition: DC2430A.ino:184
void LTC6812_wrcomm(uint8_t total_ic, cell_asic *ic)
Write the LTC6812 COMM register.
Definition: LTC6812.cpp:580
static void print_rxpsb(uint8_t type)
Definition: DC2350AA.ino:1406
bool REFON
Reference Powered Up Bit.
Definition: DC2350AA.ino:170
int8_t LTC6812_rdcomm(uint8_t total_ic, cell_asic *ic)
Reads comm registers of a LTC6812 daisy chain.
Definition: LTC6812.cpp:588
static void print_aux(uint8_t datalog_en)
Definition: DC2350AA.ino:963
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
void LTC6812_adcv(uint8_t MD, uint8_t DCP, uint8_t CH)
Starts cell voltage conversion.
Definition: LTC6812.cpp:128
void LTC6812_wrpsb(uint8_t total_ic, cell_asic *ic)
Write the 6812 PWM/Sctrl Register B.
Definition: LTC6812.cpp:500
char byte_to_hex_buffer[3]
Definition: DC2350AA.ino:1598
const uint8_t ADC_DCP
Discharge Permitted.
Definition: DC2350AA.ino:134
int8_t read_char()
#define PWM
Definition: DC2350AA.ino:87
ic_register pwmb
Definition: LTC681x.h:179
static void print_wrpsb(uint8_t type)
Definition: DC2350AA.ino:1341
bool DCCBITS_A[12]
Discharge cell switch //Dcc 1,2,3,4,5,6,7,8,9,10,11,12.
Definition: DC2350AA.ino:176
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
static void print_rxcomm(void)
Definition: DC2350AA.ino:1495