Linduino  1.3.0
Linear Technology Arduino-Compatible Demonstration Board
LTC6810.cpp
Go to the documentation of this file.
1 /*! LTC6810: 6-Channel Battery Stack Monitors
2 *
3 *@verbatim
4 *The LTC6810 is multi-cell battery stack monitor that measures up to 6 series
5 *connected battery cells with a total measurement error of less than 1.8mV.
6 *The cell measurement range of 0V to 5V makes the LTC6810 suitable for most
7 *battery chemistries. All 6 cell voltages can be captured in 290uS, and lower
8 *data acquisition rates can be selected for high noise reduction.
9 *Using the LTC6810-1, multiple devices are connected in a daisy-chain with one
10 *host processor connection for all devices, permitting simultaneous cell monitoring
11 *of long, high voltage battery strings.
12 *@endverbatim
13 *
14 * https://www.analog.com/en/products/ltc6810-1.html
15 *
16 ********************************************************************************
17 * Copyright 2019(c) Analog Devices, Inc.
18 *
19 * All rights reserved.
20 *
21 * Redistribution and use in source and binary forms, with or without
22 * modification, are permitted provided that the following conditions are met:
23 * - Redistributions of source code must retain the above copyright
24 * notice, this list of conditions and the following disclaimer.
25 * - Redistributions in binary form must reproduce the above copyright
26 * notice, this list of conditions and the following disclaimer in
27 * the documentation and/or other materials provided with the
28 * distribution.
29 * - Neither the name of Analog Devices, Inc. nor the names of its
30 * contributors may be used to endorse or promote products derived
31 * from this software without specific prior written permission.
32 * - The use of this software may or may not infringe the patent rights
33 * of one or more patent holders. This license does not release you
34 * from the requirement that you obtain separate licenses from these
35 * patent holders to use this software.
36 * - Use of the software either in source or binary form, must be run
37 * on or directly connected to an Analog Devices Inc. component.
38 *
39 * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
40 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
41 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
42 * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
43 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
44 * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
45 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
46 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
47 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
48 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
49 *******************************************************************************/
50 
51 //! @ingroup BMS
52 //! @{
53 //! @defgroup LTC6810-1 LTC6810-1: Multicell Battery Monitor
54 //! @}
55 
56 /*! @file
57  @ingroup LTC6810-1
58  Library for LTC6810-1 Multicell Battery Monitor
59 */
60 
61 #include "stdint.h"
62 #include "LTC681x.h"
63 #include "LTC6810.h"
64 
65 /* Helper function to initialize register limits */
66 void LTC6810_init_reg_limits(uint8_t total_ic, // Number of ICs in the system
67  cell_asic *ic // A two dimensional array that stores the data
68  )
69 {
70  for(uint8_t cic=0; cic<total_ic; cic++)
71  {
72  ic[cic].ic_reg.cell_channels=6;
73  ic[cic].ic_reg.stat_channels=4;
74  ic[cic].ic_reg.aux_channels=6;
75  ic[cic].ic_reg.num_cv_reg=2;
76  ic[cic].ic_reg.num_gpio_reg=2;
77  ic[cic].ic_reg.num_stat_reg=3;
78  }
79 }
80 
81 /*
82 This command will write into the configuration registers of the LTC6810-1s
83 connected in a daisy chain stack. The configuration is written in descending
84 order so the last device's configuration is written first.
85 */
86 void LTC6810_wrcfg(uint8_t total_ic, //The number of ICs being written to
87  cell_asic *ic //A two dimensional array of the configuration data that will be written
88  )
89 {
90  LTC681x_wrcfg(total_ic,ic);
91 }
92 
93 /* This command reads configuration registers of a LTC6810s connected in a daisy chain */
94 int8_t LTC6810_rdcfg(uint8_t total_ic, //Number of ICs in the system
95  cell_asic *ic //A two dimensional array that the function stores the read configuration data
96  )
97 {
98  int8_t pec_error = 0;
99  pec_error = LTC681x_rdcfg(total_ic,ic);
100  return(pec_error);
101 }
102 
103 /* Starts cell voltage conversion */
104 void LTC6810_adcv(uint8_t MD, //ADC Mode
105  uint8_t DCP, //Discharge Permit
106  uint8_t CH //Cell Channels to be measured
107  )
108 {
109  LTC681x_adcv(MD,DCP,CH);
110 }
111 
112 /* Start a GPIO and Vref2 Conversion */
113 void LTC6810_adax(uint8_t MD, //ADC Mode
114  uint8_t CHG //GPIO Channels to be measured
115  )
116 {
117  LTC681x_adax(MD,CHG);
118 }
119 
120 /* Start a Status ADC Conversion */
121 void LTC6810_adstat(uint8_t MD, //ADC Mode
122  uint8_t CHST //Status Channels to be measured
123  )
124 {
125  LTC681x_adstat(MD,CHST);
126 }
127 
128 /* Starts cell voltage and Sum of Cells conversion */
129 void LTC6810_adcvsc(uint8_t MD, //ADC Mode
130  uint8_t DCP //Discharge Permit
131  )
132 {
133  LTC681x_adcvsc(MD,DCP);
134 }
135 
136 /* Starts cell voltage, SV0 and GPIO1 conversion */
137 void LTC6810_adcvax(uint8_t MD, //ADC Mode
138  uint8_t DCP //Discharge Permit
139  )
140 {
141  LTC681x_adcvax(MD,DCP);
142 }
143 
144 /*
145 Reads and parses the LTC6810 cell voltage registers.
146 The function is used to read the parsed Cell Voltage of the LTC6810.
147 This function will send the requested read commands, parse the data
148 and store the gpio voltages in c_codes variable.
149 */
150 uint8_t LTC6810_rdcv(uint8_t reg, // Controls which cell voltage register is read back
151  uint8_t total_ic, // The number of ICs in the system
152  cell_asic *ic // Array of the parsed cell codes
153  )
154 {
155  int8_t pec_error = 0;
156  pec_error = LTC681x_rdcv(reg,total_ic,ic);
157  return(pec_error);
158 }
159 
160 /*
161 Reads and parses the LTC6810 Auxiliary registers.
162 The function is used to read the parsed GPIO codes of the LTC6810.
163 This function will send the requested read commands, parse the data
164 and store the gpio voltages in a_codes variable.
165 */
166 int8_t LTC6810_rdaux(uint8_t reg, //Determines which GPIO voltage register is read back
167  uint8_t total_ic,//The number of ICs in the system
168  cell_asic *ic//A two dimensional array of the gpio voltage codes
169  )
170 {
171  int8_t pec_error = 0;
172  LTC681x_rdaux(reg,total_ic,ic);
173  return (pec_error);
174 }
175 
176 /*
177 Reads and parses the LTC6810 stat registers.
178 The function is used to read the parsed stat codes of the LTC6810.
179 This function will send the requested read commands, parse the data
180 and store the stat voltages in stat_codes variable.
181 */
182 int8_t LTC6810_rdstat(uint8_t reg, //Determines which Stat register is read back
183  uint8_t total_ic,//The number of ICs in the system
184  cell_asic *ic //A two dimensional array of the stat codes
185  )
186 {
187  int8_t pec_error = 0;
188  pec_error = LTC681x_rdstat(reg,total_ic,ic);
189  return (pec_error);
190 }
191 
192 /*
193 Reads and parses the LTC6810 S voltage registers.
194 The function is used to read the parsed s voltage codes of the LTC6810.
195 This function will send the requested read commands, parse the data
196 and store the stat voltages in c_codes variable
197 */
198 uint8_t LTC6810_rds(uint8_t reg, //Controls which s voltage register is read back.
199  uint8_t total_ic, //Number of ICs in the daisy chain
200  cell_asic *ic //Array of the parsed cell codes
201  )
202 {
203  int8_t pec_error = 0;
204  uint8_t *s_data;
205  uint8_t c_ic = 0;
206  s_data = (uint8_t *) malloc((NUM_RX_BYT*total_ic)*sizeof(uint8_t));
207 
208  if (reg == 0)
209  {
210  for (uint8_t s_reg = 1; s_reg< 3; s_reg++) //executes once for each of the LTC6810 s voltage registers
211  {
212  LTC6810_rds_reg(s_reg, total_ic, s_data );
213 
214  for (int current_ic = 0; current_ic<total_ic; current_ic++)
215  {
216  if (ic->isospi_reverse == false)
217  {
218  c_ic = current_ic;
219  }
220  else
221  {
222  c_ic = total_ic - current_ic - 1;
223  }
224  pec_error = pec_error + parse_cells(current_ic, (2+ s_reg), s_data,
225  &ic[c_ic].cells.c_codes[0],
226  &ic[c_ic].cells.pec_match[0]);
227  }
228  }
229  }
230 
231  else
232  {
233  LTC6810_rds_reg(reg, total_ic, s_data);
234 
235  for (int current_ic = 0; current_ic<total_ic; current_ic++)
236  {
237  if (ic->isospi_reverse == false)
238  {
239  c_ic = current_ic;
240  }
241  else
242  {
243  c_ic = total_ic - current_ic - 1;
244  }
245  pec_error = pec_error + parse_cells(current_ic, (2+ reg), &s_data[8*c_ic],
246  &ic[c_ic].cells.c_codes[0],
247  &ic[c_ic].cells.pec_match[0]);
248  }
249  }
250  LTC6810_check_pec(total_ic,CELL,ic);
251  free(s_data);
252  return(pec_error);
253 }
254 
255 /* Selects the S voltage register to read */
256 void LTC6810_rds_reg(uint8_t reg, //Determines which S voltage register is read back
257  uint8_t total_ic, //The number of ICs in the daisy chain
258  uint8_t *data //An array of the unparsed cell codes
259  )
260 {
261  const uint8_t REG_LEN = 8; //Number of bytes in each ICs register + 2 bytes for the PEC
262  uint8_t cmd[4];
263  uint16_t cmd_pec;
264 
265  if (reg == 1) // RDSA
266  {
267  cmd[1] = 0x08;
268  cmd[0] = 0x00;
269  }
270  else if (reg == 2) // RDSB
271  {
272  cmd[1] = 0x0A;
273  cmd[0] = 0x00;
274  }
275 
276  read_68(total_ic, cmd, data);
277 }
278 
279 /* Sends the poll ADC command */
280 uint8_t LTC6810_pladc()
281 {
282  return(LTC681x_pladc());
283 }
284 
285 /* This function will block operation until the ADC has finished it's conversion*/
286 uint32_t LTC6810_pollAdc()
287 {
288  return(LTC681x_pollAdc());
289 }
290 
291 /*
292 The command clears the Cell Voltage registers and initializes
293 all values to 1. The register will read back hexadecimal 0xFF
294 after the command is sent.
295 */
297 {
298  LTC681x_clrcell();
299 }
300 
301 /*
302 The command clears the Auxiliary registers and initializes
303 all values to 1. The register will read back hexadecimal 0xFF
304 after the command is sent.
305 */
307 {
308  LTC681x_clraux();
309 }
310 
311 /*
312 The command clears the Stat registers and initializes
313 all values to 1. The register will read back hexadecimal 0xFF
314 after the command is sent.
315 */
317 {
318  LTC681x_clrstat();
319 }
320 
321 /* Starts the Mux Decoder diagnostic self test */
323 {
324  LTC681x_diagn();
325 }
326 
327 /* Starts cell voltage self test conversion */
328 void LTC6810_cvst(uint8_t MD, //ADC Mode
329  uint8_t ST //Self Test
330  )
331 {
332  LTC681x_cvst(MD,ST);
333 }
334 
335 /* Start an Auxiliary Register Self Test Conversion */
336 void LTC6810_axst(uint8_t MD, //ADC Mode
337  uint8_t ST //Self Test
338  )
339 {
340  LTC681x_axst(MD,ST);
341 }
342 
343 /* Start a Status Register Self Test Conversion */
344 void LTC6810_statst(uint8_t MD, //ADC Mode
345  uint8_t ST //Self Test
346  )
347 {
348  LTC681x_statst(MD,ST);
349 }
350 
351 /* Start an GPIO Redundancy test */
352 void LTC6810_adaxd(uint8_t MD, //ADC Mode
353  uint8_t CHG //GPIO Channels to be measured
354  )
355 {
356  LTC681x_adaxd(MD,CHG);
357 }
358 
359 /* Start a Status register redundancy test */
360 void LTC6810_adstatd(uint8_t MD, //ADC Mode
361  uint8_t CHST //Stat Channels to be measured
362  )
363 {
364  LTC681x_adstatd(MD,CHST);
365 }
366 
367 /* Runs the Digital Filter Self Test */
368 int16_t LTC6810_run_cell_adc_st(uint8_t adc_reg, //Type of register
369  uint8_t total_ic, //Number of ICs in the daisy chain
370  cell_asic *ic, //A two dimensional array that will store the data
371  uint8_t md, //ADC Mode
372  bool adcopt //ADCOPT bit in the configuration register
373  )
374 {
375  int16_t error = 0;
376  error = LTC681x_run_cell_adc_st(adc_reg,total_ic,ic, md, adcopt);
377  return(error);
378 }
379 
380 /* Runs the redundancy self test */
381 int16_t LTC6810_run_adc_redundancy_st(uint8_t adc_mode, //ADC Mode
382  uint8_t adc_reg, //Type of register
383  uint8_t total_ic, //Number of ICs in the daisy chain
384  cell_asic *ic //A two dimensional array that will store the data
385  )
386 {
387  int16_t error = 0;
388  LTC681x_run_adc_redundancy_st(adc_mode,adc_reg,total_ic,ic);
389  return(error);
390 }
391 
392 /* Start an open wire Conversion */
393 void LTC6810_adow(uint8_t MD, //ADC Conversion Mode
394  uint8_t PUP, //Pull up/Pull down current
395  uint8_t CH, //Cell Channels
396  uint8_t DCP//Discharge Permit
397  )
398 {
399  LTC681x_adow(MD,PUP, CH, DCP);
400 }
401 
402 /* Start GPIOs open wire ADC conversion */
403 void LTC6810_axow(uint8_t MD, //ADC Mode
404  uint8_t PUP //Pull up/Pull down current
405  )
406 {
407  LTC681x_axow(MD, PUP);
408 }
409 
410 /* Runs the data sheet algorithm for open wire for single cell open detection */
411 void LTC6810_run_openwire_single(uint8_t total_ic, //Number of ICs in the daisy chain
412  cell_asic *ic //A two dimensional array that will store the data
413  )
414 {
415  LTC681x_run_openwire_single(total_ic,ic);
416 }
417 
418 /* Runs the data sheet algorithm for open wire for multiple cell and two consecutive cells open detection */
419 void LTC6810_run_openwire_multi(uint8_t total_ic,//Number of ICs in the system
420  cell_asic *ic //A two dimensional array that will store the data
421  )
422 {
423  LTC681x_run_openwire_multi(total_ic,ic);
424 }
425 
426 /* Runs open wire for GPIOs */
427 void LTC6810_run_gpio_openwire(uint8_t total_ic, //Number of ICs in the daisy chain
428  cell_asic ic[] //A two dimensional array that will store the data
429  )
430 {
431  uint16_t OPENWIRE_THRESHOLD = 500;
432  const uint8_t N_CHANNELS =5;
433 
434  uint16_t aux_val[total_ic][N_CHANNELS];
435  uint16_t pDwn[total_ic][N_CHANNELS];
436  uint16_t ow_delta[total_ic][N_CHANNELS];
437 
438  int8_t error;
439  int8_t i;
440  uint32_t conv_time=0;
441 
442  wakeup_sleep(total_ic);
443  LTC6810_clraux();
444 
445  for (i = 0; i < 3; i++)
446  {
447  wakeup_idle(total_ic);
449  conv_time= LTC6810_pollAdc();
450  }
451 
452  wakeup_idle(total_ic);
453  error = LTC6810_rdaux(0, total_ic,ic);
454 
455  for (int cic=0; cic<total_ic; cic++)
456  {
457  for (int channel=0; channel<N_CHANNELS; channel++)
458  {
459  aux_val[cic][channel]=ic[cic].aux.a_codes[channel];
460  }
461  }
462  LTC6810_clraux();
463 
464  // pull ups
465  for (i = 0; i < 3; i++)
466  {
467  wakeup_idle(total_ic);
469  conv_time =LTC6810_pollAdc();
470  }
471 
472  wakeup_idle(total_ic);
473  error = LTC6810_rdaux(0, total_ic,ic);
474 
475  for (int cic=0; cic<total_ic; cic++)
476  {
477  for (int channel=0; channel<N_CHANNELS; channel++)
478  {
479  pDwn[cic][channel]=ic[cic].aux.a_codes[channel] ;
480  }
481  }
482 
483  for (int cic=0; cic<total_ic; cic++)
484  {
485  ic[cic].system_open_wire = 0xFFFF;
486 
487  for (int channel=0; channel<N_CHANNELS; channel++)
488  {
489  if (pDwn[cic][channel] > aux_val[cic][channel])
490  {
491  ow_delta[cic][channel] = (pDwn[cic][channel] - aux_val[cic][channel]);
492  }
493  else
494  {
495  ow_delta[cic][channel] = 0;
496  }
497 
498  if(channel>0)
499  {
500  if (ow_delta[cic][channel] > OPENWIRE_THRESHOLD)
501  {
502  ic[cic].system_open_wire = channel;
503  }
504  }
505  }
506  }
507 }
508 
509 /* Helper function to set discharge bit in CFG register */
510 void LTC6810_set_discharge(int Cell, //The cell to be discharged
511  uint8_t total_ic, //Number of ICs in the daisy chain
512  cell_asic *ic //A two dimensional array that will store the data
513  )
514 {
515  for (int i=0; i<total_ic; i++)
516  {
517  if (Cell<7)
518  {
519  ic[i].config.tx_data[4] = ic[i].config.tx_data[4] | (1<<(Cell-1));
520  }
521  else if (Cell ==0)
522  {
523  ic[i].config.tx_data[4] = ic[i].config.tx_data[4] | (0x80);
524  }
525  }
526 }
527 
528 /* Clears all of the DCC bits in the configuration registers */
529 void LTC6810_clear_discharge(uint8_t total_ic, //Number of ICs in the daisy chain
530  cell_asic *ic //A two dimensional array that will store the data
531  )
532 {
533  for (int i=0; i<total_ic; i++)
534  {
535  ic[i].config.tx_data[4] = ic[i].config.tx_data[4] & (0x40);
536  }
537 }
538 
539 /* Writes the pwm registers of a LTC6810 daisy chain */
540 void LTC6810_wrpwm(uint8_t total_ic, //Number of ICs in the daisy chain
541  uint8_t pwmReg, //Select register
542  cell_asic *ic //A two dimensional array that will store the data to be written
543  )
544 {
545  LTC681x_wrpwm(total_ic,pwmReg,ic);
546 }
547 
548 /* Reads pwm registers of a LTC6810 daisy chain */
549 int8_t LTC6810_rdpwm(uint8_t total_ic, //Number of ICs in the system
550  uint8_t pwmReg, // Select register
551  cell_asic *ic //A two dimensional array that the function stores the read data.
552  )
553 {
554  int8_t pec_error =0;
555  pec_error = LTC681x_rdpwm(total_ic,pwmReg,ic);
556  return(pec_error);
557 }
558 
559 
560 /* Writes the COMM registers of a LTC6810 daisy chain */
561 void LTC6810_wrcomm(uint8_t total_ic, //The number of ICs being written to
562  cell_asic *ic //A two dimensional array of the comm data that will be written
563  )
564 {
565  LTC681x_wrcomm(total_ic,ic);
566 }
567 
568 /* Reads COMM registers of a LTC6810 daisy chain */
569 int8_t LTC6810_rdcomm(uint8_t total_ic, //Number of ICs in the system
570  cell_asic *ic //A two dimensional array that the function stores the read data.
571  )
572 {
573  int8_t pec_error = 0;
574  LTC681x_rdcomm(total_ic, ic);
575  return(pec_error);
576 }
577 
578 /* Shifts data in COMM register out over LTC6810 SPI/I2C port */
579 void LTC6810_stcomm(uint8_t len) //Length of data to be transmitted
580 {
581  LTC681x_stcomm(len);
582 }
583 
584 /* Reads Serial ID registers group. */
585 uint8_t LTC6810_rdsid(uint8_t total_ic, // The number of ICs in the system
586  cell_asic *ic //A two dimensional array that the function stores the read data.
587  )
588 {
589  uint8_t cmd[4];
590  uint8_t read_buffer[256];
591  int8_t pec_error = 0;
592  uint16_t data_pec;
593  uint16_t calc_pec;
594  uint8_t c_ic = 0;
595  bool temp=ic->isospi_reverse;
596 
597  cmd[0] = 0x00;
598  cmd[1] = 0x2C;
599 
600  pec_error = read_68(total_ic, cmd, read_buffer);
601 
602  for(uint8_t current_ic =0; current_ic<total_ic; current_ic++)
603  {
604  if (temp== false)
605  {
606  c_ic = current_ic;
607  }
608  else
609  {
610  c_ic = total_ic - current_ic - 1;
611  }
612 
613  for(int byte=0; byte<8;byte++)
614  {
615  ic[c_ic].sid[byte] = read_buffer[byte+(8*current_ic)];
616  }
617  }
618  return(pec_error);
619 }
620 
621 /* Mutes the LTC6810 discharge transistors */
623 {
624  uint8_t cmd[2];
625 
626  cmd[0] = 0x00;
627  cmd[1] = 0x28;
628 
629  cmd_68(cmd);
630 }
631 
632 /* Clears the LTC6810 Mute Discharge */
634 {
635  uint8_t cmd[2];
636 
637  cmd[0] = 0x00;
638  cmd[1] = 0x29;
639  cmd_68(cmd);
640 }
641 
642 /* Helper function that increments PEC counters */
643 void LTC6810_check_pec(uint8_t total_ic, //The number of ICs in the system
644  uint8_t reg, //Type of register
645  cell_asic *ic //A two dimensional array that will store the data
646  )
647 {
648  LTC681x_check_pec(total_ic,reg,ic);
649 }
650 
651 /* Helper Function to reset PEC counters */
652 void LTC6810_reset_crc_count(uint8_t total_ic, //The number of ICs in the system
653  cell_asic *ic //A two dimensional array that will store the data
654  )
655 {
656  LTC681x_reset_crc_count(total_ic,ic);
657 }
658 
659 /* Helper function to initialize CFG variables. */
660 void LTC6810_init_cfg(uint8_t total_ic, cell_asic *ic)
661 {
662  LTC681x_init_cfg(total_ic,ic);
663 }
664 
665 /* Helper function to set CFGR variable */
666 void LTC6810_set_cfgr(uint8_t nIC, cell_asic *ic, bool refon, bool adcopt, bool gpio[4], bool dcc[6], bool dcc_0, bool mcal, bool en_dtmen, bool dis_red, bool fdrf, bool sconv, bool dcto[4], uint16_t uv, uint16_t ov)
667 {
668  LTC6810_set_cfgr_refon(nIC,ic,refon);
669  LTC6810_set_cfgr_adcopt(nIC,ic,adcopt);
670  LTC6810_set_cfgr_gpio(nIC,ic,gpio);
671  LTC6810_set_cfgr_uv(nIC, ic, uv);
672  LTC6810_set_cfgr_ov(nIC, ic, ov);
673  LTC6810_set_cfgr_dis(nIC,ic,dcc);
674  LTC6810_set_cfgr_mcal(nIC,ic,mcal);
675  LTC6810_set_cfgr_dcc_0(nIC,ic,dcc_0);
676  LTC6810_set_cfgr_en_dtmen(nIC,ic,en_dtmen);
677  LTC6810_set_cfgr_dis_red(nIC,ic,dis_red);
678  LTC6810_set_cfgr_fdrf(nIC,ic,fdrf);
679  LTC6810_set_cfgr_sconv(nIC,ic,sconv);
680  LTC6810_set_cfgr_dcto(nIC,ic,dcto);
681 }
682 
683 /* Helper function to set the REFON bit */
684 void LTC6810_set_cfgr_refon(uint8_t nIC, cell_asic *ic, bool refon)
685 {
686  LTC681x_set_cfgr_refon(nIC,ic,refon);
687 }
688 
689 /* Helper function to set the ADCOPT bit */
690 void LTC6810_set_cfgr_adcopt(uint8_t nIC, cell_asic *ic, bool adcopt)
691 {
692  LTC681x_set_cfgr_adcopt(nIC,ic,adcopt);
693 }
694 
695 /* Helper function to set GPIO bits */
696 void LTC6810_set_cfgr_gpio(uint8_t nIC, cell_asic *ic,bool gpio[4])
697 {
698  for (int i =0; i<4; i++)
699  {
700  if (gpio[i])ic[nIC].config.tx_data[0] = ic[nIC].config.tx_data[0]|(0x01<<(i+3));
701  else ic[nIC].config.tx_data[0] = ic[nIC].config.tx_data[0]&(~(0x01<<(i+3)));
702  }
703 }
704 
705 /* Helper function to control discharge */
706 void LTC6810_set_cfgr_dis(uint8_t nIC, cell_asic *ic,bool dcc[6])
707 {
708  for (int i =0; i<6; i++)
709  {
710  if (dcc[i])ic[nIC].config.tx_data[4] = ic[nIC].config.tx_data[4]|(0x01<<i);
711  else ic[nIC].config.tx_data[4] = ic[nIC].config.tx_data[4]& (~(0x01<<i));
712  }
713 }
714 
715 /* Helper Function to set UV value in CFG register */
716 void LTC6810_set_cfgr_uv(uint8_t nIC, cell_asic *ic,uint16_t uv)
717 {
718  LTC681x_set_cfgr_uv(nIC, ic, uv);
719 }
720 
721 /* Helper function to set OV value in CFG register */
722 void LTC6810_set_cfgr_ov(uint8_t nIC, cell_asic *ic,uint16_t ov)
723 {
724  LTC681x_set_cfgr_ov( nIC, ic, ov);
725 }
726 
727 /* Helper function to set the MCAL bit */
728 void LTC6810_set_cfgr_mcal(uint8_t nIC, cell_asic *ic, bool mcal)
729 {
730  if (mcal) ic[nIC].config.tx_data[4] = ic[nIC].config.tx_data[4]|0x40;
731  else ic[nIC].config.tx_data[4] = ic[nIC].config.tx_data[4]&0xBF;
732 }
733 
734 /* Helper function to set the DCC0 bit */
735 void LTC6810_set_cfgr_dcc_0(uint8_t nIC, cell_asic *ic, bool dcc_0)
736 {
737  if (dcc_0) ic[nIC].config.tx_data[4] = ic[nIC].config.tx_data[4]|0x80;
738  else ic[nIC].config.tx_data[4] = ic[nIC].config.tx_data[4]&0x7F;
739 }
740 
741 /* Helper function to set the EN_DTMEN bit */
742 void LTC6810_set_cfgr_en_dtmen(uint8_t nIC, cell_asic *ic, bool en_dtmen)
743 {
744  if (en_dtmen) ic[nIC].config.tx_data[5] = ic[nIC].config.tx_data[5]|0x01;
745  else ic[nIC].config.tx_data[5] = ic[nIC].config.tx_data[5]&0xFE;
746 }
747 
748 /* Helper function to set the DIS_RED bit */
749 void LTC6810_set_cfgr_dis_red(uint8_t nIC, cell_asic *ic, bool dis_red)
750 {
751  if (dis_red) ic[nIC].config.tx_data[5] = ic[nIC].config.tx_data[5]|0x02;
752  else ic[nIC].config.tx_data[5] = ic[nIC].config.tx_data[5]&0xFD;
753 }
754 
755 /* Helper function to set the FDRF bit */
756 void LTC6810_set_cfgr_fdrf(uint8_t nIC, cell_asic *ic, bool fdrf)
757 {
758  if (fdrf) ic[nIC].config.tx_data[5] = ic[nIC].config.tx_data[5]|0x04;
759  else ic[nIC].config.tx_data[5] = ic[nIC].config.tx_data[5]&0xFB;
760 }
761 
762 /* Helper function to set the SCONV bit */
763 void LTC6810_set_cfgr_sconv(uint8_t nIC, cell_asic *ic, bool sconv)
764 {
765  if (sconv) ic[nIC].config.tx_data[5] = ic[nIC].config.tx_data[5]|0x08;
766  else ic[nIC].config.tx_data[5] = ic[nIC].config.tx_data[5]&0xF7;
767 }
768 
769 /* Helper function to set the discharge timer bits */
770 void LTC6810_set_cfgr_dcto(uint8_t nIC, cell_asic *ic, bool dcto[4])
771 {
772  LTC681x_set_cfgr_dcto(nIC, ic, dcto);
773 }
int16_t LTC6810_run_cell_adc_st(uint8_t adc_reg, uint8_t total_ic, cell_asic *ic, uint8_t md, bool adcopt)
Helper function that runs the ADC Self Tests.
Definition: LTC6810.cpp:368
uint8_t LTC6810_rdcv(uint8_t reg, uint8_t total_ic, cell_asic *ic)
Reads and parses the LTC6810 cell voltage registers.
Definition: LTC6810.cpp:150
void LTC681x_adaxd(uint8_t MD, uint8_t CHG)
Start an GPIO Redundancy test.
Definition: LTC681x.cpp:1038
void LTC681x_adcvax(uint8_t MD, uint8_t DCP)
Starts cell voltage and GPIO 1&2 conversion.
Definition: LTC681x.cpp:415
void LTC6810_set_cfgr(uint8_t nIC, cell_asic *ic, bool refon, bool adcopt, bool gpio[4], bool dcc[6], bool dcc_0, bool mcal, bool en_dtmen, bool dis_red, bool fdrf, bool sconv, bool dcto[4], uint16_t uv, uint16_t ov)
Helper function to set appropriate bits in CFGR register based on bit function.
Definition: LTC6810.cpp:666
General BMS Library.
uint8_t LTC6810_pladc()
Sends the poll ADC command.
Definition: LTC6810.cpp:280
uint16_t a_codes[9]
Aux Voltage Codes.
Definition: LTC681x.h:126
void LTC681x_stcomm(uint8_t len)
Issues a stcomm command and clocks data out of the COMM register.
Definition: LTC681x.cpp:1978
void LTC681x_adow(uint8_t MD, uint8_t PUP, uint8_t CH, uint8_t DCP)
Start an open wire Conversion.
Definition: LTC681x.cpp:1292
void LTC6810_set_cfgr_dis_red(uint8_t nIC, cell_asic *ic, bool dis_red)
Helper function to set the DIS_RED bit.
Definition: LTC6810.cpp:749
void wakeup_sleep()
Definition: LTC68041.cpp:969
void LTC681x_diagn()
Starts the Mux Decoder diagnostic self test Running this command will start the Mux Decoder Diagnosti...
Definition: LTC681x.cpp:967
int8_t LTC681x_rdstat(uint8_t reg, uint8_t total_ic, cell_asic *ic)
Reads and parses the LTC681x stat registers.
Definition: LTC681x.cpp:560
uint8_t tx_data[6]
Stores data to be transmitted.
Definition: LTC681x.h:143
void LTC6810_set_cfgr_dis(uint8_t nIC, cell_asic *ic, bool dcc[6])
Definition: LTC6810.cpp:706
ax aux
Definition: LTC681x.h:175
void LTC681x_wrpwm(uint8_t total_ic, uint8_t pwmReg, cell_asic ic[])
Definition: LTC681x.cpp:1696
int8_t LTC6810_rdcomm(uint8_t total_ic, cell_asic *ic)
Reads comm registers of a LTC6810 in daisy chain.
Definition: LTC6810.cpp:569
void LTC681x_set_cfgr_uv(uint8_t nIC, cell_asic *ic, uint16_t uv)
Helper function to set uv field in CFGRA register.
Definition: LTC681x.cpp:2168
LTC6810: 6-Channel Battery Stack Monitors.
void LTC6810_axow(uint8_t MD, uint8_t PUP)
Start GPIOs open wire ADC conversion.
Definition: LTC6810.cpp:403
void LTC681x_axow(uint8_t MD, uint8_t PUP)
Start GPIOs open wire ADC conversion.
Definition: LTC681x.cpp:1310
void LTC681x_clrcell()
Clears the LTC681x Cell voltage registers The command clears the cell voltage registers and initializ...
Definition: LTC681x.cpp:937
void LTC681x_statst(uint8_t MD, uint8_t ST)
Start a Status Register Self Test Conversion.
Definition: LTC681x.cpp:1006
void LTC6810_set_cfgr_refon(uint8_t nIC, cell_asic *ic, bool refon)
Helper function to turn the REFON bit HIGH or LOW.
Definition: LTC6810.cpp:684
void LTC681x_adstat(uint8_t MD, uint8_t CHST)
Start a Status ADC Conversion.
Definition: LTC681x.cpp:383
Cell variable structure.
Definition: LTC681x.h:170
void LTC6810_set_cfgr_gpio(uint8_t nIC, cell_asic *ic, bool gpio[4])
Definition: LTC6810.cpp:696
#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
int8_t LTC6810_rdcfg(uint8_t total_ic, cell_asic *ic)
Reads configuration registers of a LTC6810 daisy chain.
Definition: LTC6810.cpp:94
#define CELL
Definition: LTC6810.h:62
register_cfg ic_reg
Definition: LTC681x.h:185
static uint8_t channel
LTC2305 Channel selection.
Definition: DC1444A.ino:127
void LTC681x_wrcfg(uint8_t total_ic, cell_asic ic[])
Definition: LTC681x.cpp:204
void LTC681x_set_cfgr_ov(uint8_t nIC, cell_asic *ic, uint16_t ov)
Helper function to set ov field in CFGRA register.
Definition: LTC681x.cpp:2177
uint8_t num_cv_reg
Number of Cell voltage register.
Definition: LTC681x.h:164
uint8_t num_gpio_reg
Number of Aux register.
Definition: LTC681x.h:165
void LTC6810_adaxd(uint8_t MD, uint8_t CHG)
Start an GPIO Redundancy test.
Definition: LTC6810.cpp:352
void LTC6810_clrstat()
Clears the LTC6810 Stat registers.
Definition: LTC6810.cpp:316
void LTC681x_adax(uint8_t MD, uint8_t CHG)
Start a GPIO and Vref2 Conversion.
Definition: LTC681x.cpp:367
void LTC681x_set_cfgr_refon(uint8_t nIC, cell_asic *ic, bool refon)
Helper function to turn the REFON bit HIGH or LOW.
Definition: LTC681x.cpp:2119
int8_t LTC6810_rdpwm(uint8_t total_ic, uint8_t pwmReg, cell_asic *ic)
Reads pwm registers of the LTC6810 in daisy chain.
Definition: LTC6810.cpp:549
void LTC6810_mute()
Mutes the LTC6810 discharge transistors.
Definition: LTC6810.cpp:622
void LTC6810_cvst(uint8_t MD, uint8_t ST)
Starts Cell voltage self test conversion.
Definition: LTC6810.cpp:328
uint8_t LTC681x_rdcv(uint8_t reg, uint8_t total_ic, cell_asic *ic)
Reads and parses the LTC681x cell voltage registers.
Definition: LTC681x.cpp:436
void LTC6810_set_cfgr_adcopt(uint8_t nIC, cell_asic *ic, bool adcopt)
Helper function to turn the ADCOPT bit HIGH or LOW.
Definition: LTC6810.cpp:690
void LTC681x_cvst(uint8_t MD, uint8_t ST)
Starts cell voltage self test conversion.
Definition: LTC681x.cpp:974
union LT_union_int32_4bytes data
Definition: DC2094A.ino:138
void LTC681x_adcvsc(uint8_t MD, uint8_t DCP)
Starts cell voltage and SOC conversion.
Definition: LTC681x.cpp:399
void LTC6810_adcvsc(uint8_t MD, uint8_t DCP)
Starts cell voltage and SOC conversion.
Definition: LTC6810.cpp:129
void LTC681x_wrcomm(uint8_t total_ic, cell_asic ic[])
Definition: LTC681x.cpp:1907
void LTC681x_reset_crc_count(uint8_t total_ic, cell_asic *ic)
Helper Function that resets the PEC error counters.
Definition: LTC681x.cpp:2059
void LTC6810_axst(uint8_t MD, uint8_t ST)
Start an Auxiliary Register Self Test Conversion.
Definition: LTC6810.cpp:336
void LTC6810_set_cfgr_sconv(uint8_t nIC, cell_asic *ic, bool sconv)
Helper function to set the SCONV bit.
Definition: LTC6810.cpp:763
uint8_t sid[6]
Definition: LTC681x.h:182
int8_t LTC681x_rdaux(uint8_t reg, uint8_t total_ic, cell_asic *ic)
Reads and parses the LTC681x auxiliary registers.
Definition: LTC681x.cpp:498
void LTC6810_check_pec(uint8_t total_ic, uint8_t reg, cell_asic *ic)
Helper Function that counts overall PEC errors and register/IC PEC errors.
Definition: LTC6810.cpp:643
uint8_t stat_channels
Number of Stat channels.
Definition: LTC681x.h:162
void LTC681x_adstatd(uint8_t MD, uint8_t CHST)
Start a Status register redundancy test Conversion.
Definition: LTC681x.cpp:1054
void LTC681x_clrstat()
Clears the LTC681x Stat registers The command clears the Stat registers and initializes all values to...
Definition: LTC681x.cpp:960
uint32_t LTC681x_pollAdc()
This function will block operation until the ADC has finished it&#39;s conversion.
Definition: LTC681x.cpp:899
void LTC6810_stcomm(uint8_t len)
Issues a stcomm command and clocks data out of the COMM register.
Definition: LTC6810.cpp:579
void LTC6810_adcv(uint8_t MD, uint8_t DCP, uint8_t CH)
Starts cell voltage conversion.
Definition: LTC6810.cpp:104
void LTC6810_clear_discharge(uint8_t total_ic, cell_asic *ic)
Clears all of the DCC bits in the configuration registers.
Definition: LTC6810.cpp:529
void wakeup_idle()
Definition: LTC68041.cpp:957
void LTC681x_axst(uint8_t MD, uint8_t ST)
Start an Auxiliary Register Self Test Conversion.
Definition: LTC681x.cpp:990
void LTC681x_check_pec(uint8_t total_ic, uint8_t reg, cell_asic *ic)
Helper Function that counts overall PEC errors and register/IC PEC errors.
Definition: LTC681x.cpp:1999
uint8_t LTC681x_pladc()
Sends the poll ADC command.
Definition: LTC681x.cpp:878
int8_t read_68(uint8_t total_ic, uint8_t tx_cmd[2], uint8_t *rx_data)
Issues a command onto the daisy chain and reads back 6*total_ic data in the rx_data array...
Definition: LTC681x.cpp:140
void LTC6810_rds_reg(uint8_t reg, uint8_t total_ic, uint8_t *data)
Reads the raw S voltage register data.
Definition: LTC6810.cpp:256
void LTC6810_clraux()
Clears the LTC6810 Auxiliary registers.
Definition: LTC6810.cpp:306
uint8_t cell_channels
Number of Cell channels.
Definition: LTC681x.h:161
void LTC6810_unmute()
Clears the LTC6810 Mute Discharge.
Definition: LTC6810.cpp:633
uint8_t num_stat_reg
Number of Status register.
Definition: LTC681x.h:166
void LTC6810_adow(uint8_t MD, uint8_t PUP, uint8_t CH, uint8_t DCP)
Start an open wire Conversion.
Definition: LTC6810.cpp:393
void LTC6810_set_cfgr_en_dtmen(uint8_t nIC, cell_asic *ic, bool en_dtmen)
Helper function to set the EN_DTMEN bit.
Definition: LTC6810.cpp:742
#define PULL_UP_CURRENT
Definition: LTC681x.h:105
static int error
void LTC6810_reset_crc_count(uint8_t total_ic, cell_asic *ic)
Helper Function that resets the PEC error counters.
Definition: LTC6810.cpp:652
uint8_t pec_match[6]
If a PEC error was detected during most recent read cmd.
Definition: LTC681x.h:120
int8_t LTC6810_rdstat(uint8_t reg, uint8_t total_ic, cell_asic *ic)
Reads and parses the LTC6810 stat registers.
Definition: LTC6810.cpp:182
void LTC6810_init_cfg(uint8_t total_ic, cell_asic *ic)
Helper Function to initialize the CFGR data structures.
Definition: LTC6810.cpp:660
uint8_t LTC6810_rds(uint8_t reg, uint8_t total_ic, cell_asic *ic)
Reads and parses the LTC6810 S voltage registers.
Definition: LTC6810.cpp:198
void LTC681x_set_cfgr_dcto(uint8_t nIC, cell_asic *ic, bool dcto[4])
Definition: LTC681x.cpp:2158
void LTC6810_clrcell()
Clears the LTC6810 cell voltage registers.
Definition: LTC6810.cpp:296
void cmd_68(uint8_t tx_cmd[2])
Sends a command to the BMS IC.
Definition: LTC681x.cpp:77
int8_t LTC681x_rdpwm(uint8_t total_ic, uint8_t pwmReg, cell_asic ic[])
Definition: LTC681x.cpp:1738
ic_register config
Definition: LTC681x.h:172
void LTC6810_set_cfgr_uv(uint8_t nIC, cell_asic *ic, uint16_t uv)
Helper function to set uv field in CFGRA register.
Definition: LTC6810.cpp:716
void LTC6810_wrcomm(uint8_t total_ic, cell_asic *ic)
Write the LTC6810 COMM register.
Definition: LTC6810.cpp:561
void LTC6810_set_cfgr_dcto(uint8_t nIC, cell_asic *ic, bool dcto[4])
Definition: LTC6810.cpp:770
int8_t LTC681x_rdcomm(uint8_t total_ic, cell_asic ic[])
Definition: LTC681x.cpp:1936
#define MD_7KHZ_3KHZ
Definition: LTC681x.h:63
#define NUM_RX_BYT
Definition: LTC681x.h:108
void LTC6810_run_gpio_openwire(uint8_t total_ic, cell_asic ic[])
Definition: LTC6810.cpp:427
void LTC6810_adax(uint8_t MD, uint8_t CHG)
Start a GPIO, cell 0 and Vref2 Conversion.
Definition: LTC6810.cpp:113
void LTC6810_set_cfgr_mcal(uint8_t nIC, cell_asic *ic, bool mcal)
Helper function to set the MCAL bit.
Definition: LTC6810.cpp:728
void LTC6810_adstat(uint8_t MD, uint8_t CHST)
Start a Status ADC Conversion.
Definition: LTC6810.cpp:121
void LTC6810_adcvax(uint8_t MD, uint8_t DCP)
Starts cell voltage, Cell 0 and GPIO 1 conversion.
Definition: LTC6810.cpp:137
void LTC6810_wrcfg(uint8_t total_ic, cell_asic *ic)
Write the LTC6810 configuration register.
Definition: LTC6810.cpp:86
void LTC681x_init_cfg(uint8_t total_ic, cell_asic *ic)
Helper Function to initialize the CFGR data structures.
Definition: LTC681x.cpp:2084
int8_t LTC681x_rdcfg(uint8_t total_ic, cell_asic ic[])
Definition: LTC681x.cpp:264
int8_t LTC6810_rdaux(uint8_t reg, uint8_t total_ic, cell_asic *ic)
Reads and parses the LTC6810 auxiliary registers.
Definition: LTC6810.cpp:166
void LTC6810_statst(uint8_t MD, uint8_t ST)
Start a Status Register Self Test Conversion.
Definition: LTC6810.cpp:344
void LTC681x_clraux()
Clears the LTC681x Auxiliary registers The command clears the Auxiliary registers and initializes all...
Definition: LTC681x.cpp:948
void LTC681x_adcv(uint8_t MD, uint8_t DCP, uint8_t CH)
Starts cell voltage conversion Starts ADC conversions of the LTC681x Cpin inputs. ...
Definition: LTC681x.cpp:350
void LTC6810_diagn()
Starts the Mux Decoder diagnostic self test.
Definition: LTC6810.cpp:322
void LTC6810_set_cfgr_dcc_0(uint8_t nIC, cell_asic *ic, bool dcc_0)
Helper function to set the DCC_0 bit.
Definition: LTC6810.cpp:735
uint8_t LTC6810_rdsid(uint8_t total_ic, cell_asic *ic)
Reads Serial ID registers group.
Definition: LTC6810.cpp:585
int16_t LTC681x_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: LTC681x.cpp:1188
void LTC681x_set_cfgr_adcopt(uint8_t nIC, cell_asic *ic, bool adcopt)
Helper function to turn the ADCOPT bit HIGH or LOW.
Definition: LTC681x.cpp:2126
int16_t LTC6810_run_adc_redundancy_st(uint8_t adc_mode, uint8_t adc_reg, uint8_t total_ic, cell_asic *ic)
Helper function that runs the ADC Digital Redundancy commands and checks output for errors...
Definition: LTC6810.cpp:381
void LTC6810_run_openwire_single(uint8_t total_ic, cell_asic *ic)
Helper function that runs the data sheet open wire algorithm for single cell detection.
Definition: LTC6810.cpp:411
static int i
Definition: DC2430A.ino:184
void LTC6810_set_cfgr_fdrf(uint8_t nIC, cell_asic *ic, bool fdrf)
Helper function to set the FDRF bit.
Definition: LTC6810.cpp:756
void LTC681x_run_openwire_multi(uint8_t total_ic, cell_asic ic[])
Definition: LTC681x.cpp:1416
long system_open_wire
Definition: LTC681x.h:186
cv cells
Definition: LTC681x.h:174
void LTC681x_run_openwire_single(uint8_t total_ic, cell_asic ic[])
Definition: LTC681x.cpp:1326
uint8_t aux_channels
Number of Aux channels.
Definition: LTC681x.h:163
void LTC6810_init_reg_limits(uint8_t total_ic, cell_asic *ic)
Initialize the Register limits.
Definition: LTC6810.cpp:66
int16_t LTC681x_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: LTC681x.cpp:1070
void LTC6810_adstatd(uint8_t MD, uint8_t CHST)
Start a Status register redundancy test Conversion.
Definition: LTC6810.cpp:360
int8_t parse_cells(uint8_t current_ic, uint8_t cell_reg, uint8_t cell_data[], uint16_t *cell_codes, uint8_t *ic_pec)
Helper function that parses voltage measurement registers.
Definition: LTC681x.cpp:833
bool isospi_reverse
Definition: LTC681x.h:183
void LTC6810_set_cfgr_ov(uint8_t nIC, cell_asic *ic, uint16_t ov)
Helper function to set ov field in CFGRA register.
Definition: LTC6810.cpp:722
void LTC6810_run_openwire_multi(uint8_t total_ic, cell_asic *ic)
Runs the data sheet algorithm for open wire for multiple cell and two consecutive cells detection...
Definition: LTC6810.cpp:419
void LTC6810_wrpwm(uint8_t total_ic, uint8_t pwmReg, cell_asic *ic)
Writes to the LTC6810 PWM register of LTC6810.
Definition: LTC6810.cpp:540
uint32_t LTC6810_pollAdc()
This function will block operation until the ADC has finished it&#39;s conversion.
Definition: LTC6810.cpp:286
void LTC6810_set_discharge(int Cell, uint8_t total_ic, cell_asic *ic)
Helper function to set discharge bit in CFG register.
Definition: LTC6810.cpp:510