| Linduino 1.3.0 Linear Technology Arduino-Compatible Demonstration Board

LTC68041.cpp
Go to the documentation of this file.
1 /*!
2 LTC6804-1 Multicell Battery Monitor
3
4 @verbatim
5 The LTC6804 is a 3rd generation multicell battery stack
6 monitor that measures up to 12 series connected battery
7 cells with a total measurement error of less than 1.2mV. The
8 cell measurement range of 0V to 5V makes the LTC6804
9 suitable for most battery chemistries. All 12 cell voltages
10 can be captured in 290uS, and lower data acquisition rates
11 can be selected for high noise reduction.
12
13 Using the LTC6804-1, multiple devices are connected in
14 a daisy-chain with one host processor connection for all
15 devices.
16 @endverbatim
17
18 http://www.linear.com/product/LTC6804-1
19
20 http://www.linear.com/product/LTC6804-1#demoboards
21
22
23 Copyright 2018(c) Analog Devices, Inc.
24
25 All rights reserved.
26
27 Redistribution and use in source and binary forms, with or without
28 modification, are permitted provided that the following conditions are met:
29 - Redistributions of source code must retain the above copyright
30 notice, this list of conditions and the following disclaimer.
31 - Redistributions in binary form must reproduce the above copyright
32 notice, this list of conditions and the following disclaimer in
33 the documentation and/or other materials provided with the
34 distribution.
35 - Neither the name of Analog Devices, Inc. nor the names of its
36 contributors may be used to endorse or promote products derived
37 from this software without specific prior written permission.
38 - The use of this software may or may not infringe the patent rights
39 of one or more patent holders. This license does not release you
40 from the requirement that you obtain separate licenses from these
41 patent holders to use this software.
42 - Use of the software either in source or binary form, must be run
43 on or directly connected to an Analog Devices Inc. component.
44
45 THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
46 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
47 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
48 IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
49 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
50 LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
51 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
52 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
53 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
54 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
55
56 Copyright 2013 Linear Technology Corp. (LTC)
57 ***********************************************************/
58
59 //! @ingroup BMS
60 //! @{
61 //! @defgroup LTC68041 LTC6804-1: Multicell Battery Monitor
62 //! @}
63
64 /*! @file
65 @ingroup LTC68041
66 Library for LTC6804-1 Multicell Battery Monitor
67 */
68
69 #include <stdint.h>
70 #include <Arduino.h>
71 #include "Linduino.h"
72 #include "LT_SPI.h"
73 #include "LTC68041.h"
74 #include <SPI.h>
75
76
77
78 /*!
79 6804 conversion command variables.
80 */
81 uint8_t ADCV[2]; //!< Cell Voltage conversion command.
82 uint8_t ADAX[2]; //!< GPIO conversion command.
83
84
85 /*!
86 \brief This function will initialize all 6804 variables and the SPI port.
87
88 This function will initialize the Linduino to communicate with the LTC6804 with a 1MHz SPI clock.
89 The Function also intializes the ADCV and ADAX commands to convert all cell and GPIO voltages in
90 the Normal ADC mode.
91 */
92 void LTC6804_initialize()
93 {
94 quikeval_SPI_connect();
95 spi_enable(SPI_CLOCK_DIV16); // This will set the Linduino to have a 1MHz Clock
96 set_adc(MD_NORMAL,DCP_DISABLED,CELL_CH_ALL,AUX_CH_ALL);
97 }
98
99 /*!*******************************************************************************************************************
100 \brief Maps global ADC control variables to the appropriate control bytes for each of the different ADC commands
101
102 @param[in] uint8_t MD The adc conversion mode
103 @param[in] uint8_t DCP Controls if Discharge is permitted during cell conversions
104 @param[in] uint8_t CH Determines which cells are measured during an ADC conversion command
105 @param[in] uint8_t CHG Determines which GPIO channels are measured during Auxiliary conversion command
106
107 Command Code:
108 -------------
109
110 |command | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
111 |-----------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|
112 |ADCV: | 0 | 0 | 0 | 0 | 0 | 0 | 1 | MD[1] | MD[2] | 1 | 1 | DCP | 0 | CH[2] | CH[1] | CH[0] |
113 |ADAX: | 0 | 0 | 0 | 0 | 0 | 1 | 0 | MD[1] | MD[2] | 1 | 1 | DCP | 0 | CHG[2]| CHG[1]| CHG[0]|
114 ******************************************************************************************************************/
115 void set_adc(uint8_t MD, //ADC Mode
116 uint8_t DCP, //Discharge Permit
117 uint8_t CH, //Cell Channels to be measured
118 uint8_t CHG //GPIO Channels to be measured
119 )
120 {
121 uint8_t md_bits;
122
123 md_bits = (MD & 0x02) >> 1;
124 ADCV[0] = md_bits + 0x02;
125 md_bits = (MD & 0x01) << 7;
126 ADCV[1] = md_bits + 0x60 + (DCP<<4) + CH;
127
128 md_bits = (MD & 0x02) >> 1;
129 ADAX[0] = md_bits + 0x04;
130 md_bits = (MD & 0x01) << 7;
131 ADAX[1] = md_bits + 0x60 + CHG ;
132
133 }
134
135
136 /*!*********************************************************************************************
137 \brief Starts cell voltage conversion
138
139 Starts ADC conversions of the LTC6804 Cpin inputs.
140 The type of ADC conversion executed can be changed by setting the associated global variables:
141 |Variable|Function |
142 |--------|----------------------------------------------|
143 | MD | Determines the filter corner of the ADC |
144 | CH | Determines which cell channels are converted |
145 | DCP | Determines if Discharge is Permitted |
146
147 Command Code:
148 -------------
149
150 |CMD[0:1] | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
151 |-----------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|
152 |ADCV: | 0 | 0 | 0 | 0 | 0 | 0 | 1 | MD[1] | MD[2] | 1 | 1 | DCP | 0 | CH[2] | CH[1] | CH[0] |
153 ***********************************************************************************************/
154 void LTC6804_adcv()
155 {
156
157 uint8_t cmd[4];
158 uint16_t cmd_pec;
159
160 //1
161 cmd[0] = ADCV[0];
162 cmd[1] = ADCV[1];
163
164 //2
165 cmd_pec = pec15_calc(2, ADCV);
166 cmd[2] = (uint8_t)(cmd_pec >> 8);
167 cmd[3] = (uint8_t)(cmd_pec);
168
169 //3
170 wakeup_idle (); //This will guarantee that the LTC6804 isoSPI port is awake. This command can be removed.
171
172 //4
173 output_low(LTC6804_CS);
174 spi_write_array(4,cmd);
175 output_high(LTC6804_CS);
176
177 }
178 /*
179 LTC6804_adcv Function sequence:
180
181 1. Load adcv command into cmd array
182 2. Calculate adcv cmd PEC and load pec into cmd array
183 3. wakeup isoSPI port, this step can be removed if isoSPI status is previously guaranteed
184 4. send broadcast adcv command to LTC6804 daisy chain
185 */
186
187
188 /*!******************************************************************************************************
189 \brief Start an GPIO Conversion
190
191 Starts an ADC conversions of the LTC6804 GPIO inputs.
192 The type of ADC conversion executed can be changed by setting the associated global variables:
193 |Variable|Function |
194 |--------|----------------------------------------------|
195 | MD | Determines the filter corner of the ADC |
196 | CHG | Determines which GPIO channels are converted |
197
198
199 Command Code:
200 -------------
201
202 |CMD[0:1] | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
203 |-----------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|
204 |ADAX: | 0 | 0 | 0 | 0 | 0 | 1 | 0 | MD[1] | MD[2] | 1 | 1 | DCP | 0 | CHG[2]| CHG[1]| CHG[0]|
205 *********************************************************************************************************/
206 void LTC6804_adax()
207 {
208 uint8_t cmd[4];
209 uint16_t cmd_pec;
210
211 cmd[0] = ADAX[0];
212 cmd[1] = ADAX[1];
213 cmd_pec = pec15_calc(2, ADAX);
214 cmd[2] = (uint8_t)(cmd_pec >> 8);
215 cmd[3] = (uint8_t)(cmd_pec);
216
217 wakeup_idle (); //This will guarantee that the LTC6804 isoSPI port is awake. This command can be removed.
218 output_low(LTC6804_CS);
219 spi_write_array(4,cmd);
220 output_high(LTC6804_CS);
221
222 }
223 /*
224 LTC6804_adax Function sequence:
225
226 1. Load adax command into cmd array
227 2. Calculate adax cmd PEC and load pec into cmd array
228 3. wakeup isoSPI port, this step can be removed if isoSPI status is previously guaranteed
229 4. send broadcast adax command to LTC6804 daisy chain
230 */
231
232
233 /***********************************************//**
234 \brief Reads and parses the LTC6804 cell voltage registers.
235
236 The function is used to read the cell codes of the LTC6804.
237 This function will send the requested read commands parse the data
238 and store the cell voltages in cell_codes variable.
239
240 @param[in] uint8_t reg; This controls which cell voltage register is read back.
241
242 0: Read back all Cell registers
243
244 1: Read back cell group A
245
246 2: Read back cell group B
247
248 3: Read back cell group C
249
250 4: Read back cell group D
251
252 @param[in] uint8_t total_ic; This is the number of ICs in the daisy chain(-1 only)
253
254 @param[out] uint16_t cell_codes[]; An array of the parsed cell codes from lowest to highest. The cell codes will
255 be stored in the cell_codes[] array in the following format:
256 | cell_codes[0][0]| cell_codes[0][1] | cell_codes[0][2]| ..... | cell_codes[0][11]| cell_codes[1][0] | cell_codes[1][1]| ..... |
257 |------------------|------------------|------------------|--------------|-------------------|-------------------|-----------------|----------|
258 |IC1 Cell 1 |IC1 Cell 2 |IC1 Cell 3 | ..... | IC1 Cell 12 |IC2 Cell 1 |IC2 Cell 2 | ..... |
259
260 @return int8_t, PEC Status.
261
262 0: No PEC error detected
263
264 -1: PEC error detected, retry read
265
266
267 *************************************************/
268 uint8_t LTC6804_rdcv(uint8_t reg, // Controls which cell voltage register is read back.
269 uint8_t total_ic, // the number of ICs in the system
270 uint16_t cell_codes[][12] // Array of the parsed cell codes
271 )
272 {
273
274 const uint8_t NUM_RX_BYT = 8;
275 const uint8_t BYT_IN_REG = 6;
276 const uint8_t CELL_IN_REG = 3;
277
278 uint8_t *cell_data;
279 uint8_t pec_error = 0;
280 uint16_t parsed_cell;
281 uint16_t received_pec;
282 uint16_t data_pec;
283 uint8_t data_counter=0; //data counter
284 cell_data = (uint8_t *) malloc((NUM_RX_BYT*total_ic)*sizeof(uint8_t));
285 //1.a
286 if (reg == 0)
287 {
288 //a.i
289 for (uint8_t cell_reg = 1; cell_reg<5; cell_reg++) //executes once for each of the LTC6804 cell voltage registers
290 {
291 data_counter = 0;
292 LTC6804_rdcv_reg(cell_reg, total_ic,cell_data ); //Reads a single Cell voltage register
293
294 for (uint8_t current_ic = 0 ; current_ic < total_ic; current_ic++) // executes for every LTC6804 in the daisy chain
295 {
296 // current_ic is used as the IC counter
297
298 //a.ii
299 for (uint8_t current_cell = 0; current_cell<CELL_IN_REG; current_cell++) // This loop parses the read back data into cell voltages, it
300 {
301 // loops once for each of the 3 cell voltage codes in the register
302
303 parsed_cell = cell_data[data_counter] + (cell_data[data_counter + 1] << 8);//Each cell code is received as two bytes and is combined to
304 // create the parsed cell voltage code
305
306 cell_codes[current_ic][current_cell + ((cell_reg - 1) * CELL_IN_REG)] = parsed_cell;
307 data_counter = data_counter + 2; //Because cell voltage codes are two bytes the data counter
308 //must increment by two for each parsed cell code
309 }
310 //a.iii
311 received_pec = (cell_data[data_counter] << 8) + cell_data[data_counter+1]; //The received PEC for the current_ic is transmitted as the 7th and 8th
312 //after the 6 cell voltage data bytes
313 data_pec = pec15_calc(BYT_IN_REG, &cell_data[current_ic * NUM_RX_BYT]);
314 if (received_pec != data_pec)
315 {
316 pec_error = -1; //The pec_error variable is simply set negative if any PEC errors
317 //are detected in the serial data
318 }
319 data_counter=data_counter+2; //Because the transmitted PEC code is 2 bytes long the data_counter
320 //must be incremented by 2 bytes to point to the next ICs cell voltage data
321 }
322 }
323 }
324 //1.b
325 else
326 {
327 //b.i
328 LTC6804_rdcv_reg(reg, total_ic,cell_data);
329 for (uint8_t current_ic = 0 ; current_ic < total_ic; current_ic++) // executes for every LTC6804 in the daisy chain
330 {
331 // current_ic is used as the IC counter
332 //b.ii
333 for (uint8_t current_cell = 0; current_cell < CELL_IN_REG; current_cell++) // This loop parses the read back data into cell voltages, it
334 {
335 // loops once for each of the 3 cell voltage codes in the register
336
337 parsed_cell = cell_data[data_counter] + (cell_data[data_counter+1]<<8); //Each cell code is received as two bytes and is combined to
338 // create the parsed cell voltage code
339
340 cell_codes[current_ic][current_cell + ((reg - 1) * CELL_IN_REG)] = 0x0000FFFF & parsed_cell;
341 data_counter= data_counter + 2; //Because cell voltage codes are two bytes the data counter
342 //must increment by two for each parsed cell code
343 }
344 //b.iii
345 received_pec = (cell_data[data_counter] << 8 )+ cell_data[data_counter + 1]; //The received PEC for the current_ic is transmitted as the 7th and 8th
346 //after the 6 cell voltage data bytes
347 data_pec = pec15_calc(BYT_IN_REG, &cell_data[current_ic * NUM_RX_BYT]);
348 if (received_pec != data_pec)
349 {
350 pec_error = -1; //The pec_error variable is simply set negative if any PEC errors
351 //are detected in the serial data
352 }
353 data_counter= data_counter + 2; //Because the transmitted PEC code is 2 bytes long the data_counter
354 //must be incremented by 2 bytes to point to the next ICs cell voltage data
355 }
356 }
357
358 //2
359 free(cell_data);
360 return(pec_error);
361 }
362 /*
363 LTC6804_rdcv Sequence
364
365 1. Switch Statement:
366 a. Reg = 0
367 i. Read cell voltage registers A-D for every IC in the daisy chain
368 ii. Parse raw cell voltage data in cell_codes array
369 iii. Check the PEC of the data read back vs the calculated PEC for each read register command
370 b. Reg != 0
371 i.Read single cell voltage register for all ICs in daisy chain
372 ii. Parse raw cell voltage data in cell_codes array
373 iii. Check the PEC of the data read back vs the calculated PEC for each read register command
374 2. Return pec_error flag
375 */
376
377
378 /***********************************************//**
379 \brief Read the raw data from the LTC6804 cell voltage register
380
381 The function reads a single cell voltage register and stores the read data
382 in the *data point as a byte array. This function is rarely used outside of
383 the LTC6804_rdcv() command.
384
385 @param[in] uint8_t reg; This controls which cell voltage register is read back.
386
387 1: Read back cell group A
388
389 2: Read back cell group B
390
391 3: Read back cell group C
392
393 4: Read back cell group D
394
395 @param[in] uint8_t total_ic; This is the number of ICs in the daisy chain(-1 only)
396
397 @param[out] uint8_t *data; An array of the unparsed cell codes
398
399 Command Code:
400 -------------
401
402 |CMD[0:1] | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
403 |-----------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|
404 |RDCVA: | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
405 |RDCVB: | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 |
406 |RDCVC: | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
407 |RDCVD: | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 |
408
409 *************************************************/
410 void LTC6804_rdcv_reg(uint8_t reg, //Determines which cell voltage register is read back
411 uint8_t total_ic, //the number of ICs in the
412 uint8_t *data //An array of the unparsed cell codes
413 )
414 {
415 const uint8_t REG_LEN = 8; //number of bytes in each ICs register + 2 bytes for the PEC
416 uint8_t cmd[4];
417 uint16_t cmd_pec;
418
419 //1
420 if (reg == 1) //1: RDCVA
421 {
422 cmd[1] = 0x04;
423 cmd[0] = 0x00;
424 }
425 else if (reg == 2) //2: RDCVB
426 {
427 cmd[1] = 0x06;
428 cmd[0] = 0x00;
429 }
430 else if (reg == 3) //3: RDCVC
431 {
432 cmd[1] = 0x08;
433 cmd[0] = 0x00;
434 }
435 else if (reg == 4) //4: RDCVD
436 {
437 cmd[1] = 0x0A;
438 cmd[0] = 0x00;
439 }
440
441 //2
442 cmd_pec = pec15_calc(2, cmd);
443 cmd[2] = (uint8_t)(cmd_pec >> 8);
444 cmd[3] = (uint8_t)(cmd_pec);
445
446 //3
447 wakeup_idle (); //This will guarantee that the LTC6804 isoSPI port is awake. This command can be removed.
448
449 //4
450 output_low(LTC6804_CS);
451 spi_write_read(cmd,4,data,(REG_LEN*total_ic));
452 output_high(LTC6804_CS);
453
454 }
455 /*
456 LTC6804_rdcv_reg Function Process:
457 1. Determine Command and initialize command array
458 2. Calculate Command PEC
459 3. Wake up isoSPI, this step is optional
460 4. Send Global Command to LTC6804 daisy chain
461 */
462
463
464 /***********************************************************************************//**
465 \brief Reads and parses the LTC6804 auxiliary registers.
466
467 The function is used
468 to read the parsed GPIO codes of the LTC6804. This function will send the requested
469 read commands parse the data and store the gpio voltages in aux_codes variable
470
471 @param[in] uint8_t reg; This controls which GPIO voltage register is read back.
472
473 0: Read back all auxiliary registers
474
475 1: Read back auxiliary group A
476
477 2: Read back auxiliary group B
478
479
480 @param[in] uint8_t total_ic; This is the number of ICs in the daisy chain(-1 only)
481
482
483 @param[out] uint16_t aux_codes[][6]; A two dimensional array of the gpio voltage codes. The GPIO codes will
484 be stored in the aux_codes[][6] array in the following format:
485 | aux_codes[0][0]| aux_codes[0][1] | aux_codes[0][2]| aux_codes[0][3]| aux_codes[0][4]| aux_codes[0][5]| aux_codes[1][0] |aux_codes[1][1]| ..... |
486 |-----------------|-----------------|-----------------|-----------------|-----------------|-----------------|-----------------|---------------|-----------|
487 |IC1 GPIO1 |IC1 GPIO2 |IC1 GPIO3 |IC1 GPIO4 |IC1 GPIO5 |IC1 Vref2 |IC2 GPIO1 |IC2 GPIO2 | ..... |
488
489 @return int8_t, PEC Status
490
491 0: No PEC error detected
492
493 -1: PEC error detected, retry read
494 *************************************************/
495 int8_t LTC6804_rdaux(uint8_t reg, //Determines which GPIO voltage register is read back.
496 uint8_t total_ic,//the number of ICs in the system
497 uint16_t aux_codes[][6]//A two dimensional array of the gpio voltage codes.
498 )
499 {
500
501
502 const uint8_t NUM_RX_BYT = 8;
503 const uint8_t BYT_IN_REG = 6;
504 const uint8_t GPIO_IN_REG = 3;
505
506 uint8_t *data;
507 uint8_t data_counter = 0;
508 int8_t pec_error = 0;
509 uint16_t parsed_aux;
510 uint16_t received_pec;
511 uint16_t data_pec;
512 data = (uint8_t *) malloc((NUM_RX_BYT*total_ic)*sizeof(uint8_t));
513 //1.a
514 if (reg == 0)
515 {
516 //a.i
517 for (uint8_t gpio_reg = 1; gpio_reg<3; gpio_reg++) //executes once for each of the LTC6804 aux voltage registers
518 {
519 data_counter = 0;
520 LTC6804_rdaux_reg(gpio_reg, total_ic,data); //Reads the raw auxiliary register data into the data[] array
521
522 for (uint8_t current_ic = 0 ; current_ic < total_ic; current_ic++) // executes for every LTC6804 in the daisy chain
523 {
524 // current_ic is used as the IC counter
525
526 //a.ii
527 for (uint8_t current_gpio = 0; current_gpio< GPIO_IN_REG; current_gpio++) // This loop parses the read back data into GPIO voltages, it
528 {
529 // loops once for each of the 3 gpio voltage codes in the register
530
531 parsed_aux = data[data_counter] + (data[data_counter+1]<<8); //Each gpio codes is received as two bytes and is combined to
532 // create the parsed gpio voltage code
533
534 aux_codes[current_ic][current_gpio +((gpio_reg-1)*GPIO_IN_REG)] = parsed_aux;
535 data_counter=data_counter+2; //Because gpio voltage codes are two bytes the data counter
536 //must increment by two for each parsed gpio voltage code
537
538 }
539 //a.iii
540 received_pec = (data[data_counter]<<8)+ data[data_counter+1]; //The received PEC for the current_ic is transmitted as the 7th and 8th
541 //after the 6 gpio voltage data bytes
542 data_pec = pec15_calc(BYT_IN_REG, &data[current_ic*NUM_RX_BYT]);
543 if (received_pec != data_pec)
544 {
545 pec_error = -1; //The pec_error variable is simply set negative if any PEC errors
546 //are detected in the received serial data
547 }
548
549 data_counter=data_counter+2; //Because the transmitted PEC code is 2 bytes long the data_counter
550 //must be incremented by 2 bytes to point to the next ICs gpio voltage data
551 }
552
553
554 }
555
556 }
557 else
558 {
559 //b.i
560 LTC6804_rdaux_reg(reg, total_ic, data);
561 for (int current_ic = 0 ; current_ic < total_ic; current_ic++) // executes for every LTC6804 in the daisy chain
562 {
563 // current_ic is used as an IC counter
564
565 //b.ii
566 for (int current_gpio = 0; current_gpio<GPIO_IN_REG; current_gpio++) // This loop parses the read back data. Loops
567 {
568 // once for each aux voltage in the register
569
570 parsed_aux = (data[data_counter] + (data[data_counter+1]<<8)); //Each gpio codes is received as two bytes and is combined to
571 // create the parsed gpio voltage code
572 aux_codes[current_ic][current_gpio +((reg-1)*GPIO_IN_REG)] = parsed_aux;
573 data_counter=data_counter+2; //Because gpio voltage codes are two bytes the data counter
574 //must increment by two for each parsed gpio voltage code
575 }
576 //b.iii
577 received_pec = (data[data_counter]<<8) + data[data_counter+1]; //The received PEC for the current_ic is transmitted as the 7th and 8th
578 //after the 6 gpio voltage data bytes
579 data_pec = pec15_calc(BYT_IN_REG, &data[current_ic*NUM_RX_BYT]);
580 if (received_pec != data_pec)
581 {
582 pec_error = -1; //The pec_error variable is simply set negative if any PEC errors
583 //are detected in the received serial data
584 }
585
586 data_counter=data_counter+2; //Because the transmitted PEC code is 2 bytes long the data_counter
587 //must be incremented by 2 bytes to point to the next ICs gpio voltage data
588 }
589 }
590 free(data);
591 return (pec_error);
592 }
593 /*
594 LTC6804_rdaux Sequence
595
596 1. Switch Statement:
597 a. Reg = 0
598 i. Read GPIO voltage registers A-D for every IC in the daisy chain
599 ii. Parse raw GPIO voltage data in cell_codes array
600 iii. Check the PEC of the data read back vs the calculated PEC for each read register command
601 b. Reg != 0
602 i.Read single GPIO voltage register for all ICs in daisy chain
603 ii. Parse raw GPIO voltage data in cell_codes array
604 iii. Check the PEC of the data read back vs the calculated PEC for each read register command
605 2. Return pec_error flag
606 */
607
608
609 /***********************************************//**
610 \brief Read the raw data from the LTC6804 auxiliary register
611
612 The function reads a single GPIO voltage register and stores thre read data
613 in the *data point as a byte array. This function is rarely used outside of
614 the LTC6804_rdaux() command.
615
616 @param[in] uint8_t reg; This controls which GPIO voltage register is read back.
617
618 1: Read back auxiliary group A
619
620 2: Read back auxiliary group B
621
622
623 @param[in] uint8_t total_ic; This is the number of ICs in the daisy chain
624
625 @param[out] uint8_t *data; An array of the unparsed aux codes
626
627
628
629 Command Code:
630 -------------
631
632 |CMD[0:1] | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
633 |---------------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|
634 |RDAUXA: | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 |
635 |RDAUXB: | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 0 |
636
637 *************************************************/
638 void LTC6804_rdaux_reg(uint8_t reg, //Determines which GPIO voltage register is read back
639 uint8_t total_ic, //The number of ICs in the system
640 uint8_t *data //Array of the unparsed auxiliary codes
641 )
642 {
643 const uint8_t REG_LEN = 8; // number of bytes in the register + 2 bytes for the PEC
644 uint8_t cmd[4];
645 uint16_t cmd_pec;
646
647 //1
648 if (reg == 1) //Read back auxiliary group A
649 {
650 cmd[1] = 0x0C;
651 cmd[0] = 0x00;
652 }
653 else if (reg == 2) //Read back auxiliary group B
654 {
655 cmd[1] = 0x0e;
656 cmd[0] = 0x00;
657 }
658 else //Read back auxiliary group A
659 {
660 cmd[1] = 0x0C;
661 cmd[0] = 0x00;
662 }
663 //2
664 cmd_pec = pec15_calc(2, cmd);
665 cmd[2] = (uint8_t)(cmd_pec >> 8);
666 cmd[3] = (uint8_t)(cmd_pec);
667
668 //3
669 wakeup_idle (); //This will guarantee that the LTC6804 isoSPI port is awake, this command can be removed.
670 //4
671 output_low(LTC6804_CS);
672 spi_write_read(cmd,4,data,(REG_LEN*total_ic));
673 output_high(LTC6804_CS);
674
675 }
676 /*
677 LTC6804_rdaux_reg Function Process:
678 1. Determine Command and initialize command array
679 2. Calculate Command PEC
680 3. Wake up isoSPI, this step is optional
681 4. Send Global Command to LTC6804 daisy chain
682 */
683
684 /********************************************************//**
685 \brief Clears the LTC6804 cell voltage registers
686
687 The command clears the cell voltage registers and intiallizes
688 all values to 1. The register will read back hexadecimal 0xFF
689 after the command is sent.
690
691
692 Command Code:
693 -------------
694
695 |CMD[0:1] | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
696 |---------------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|
697 |CLRCELL: | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 |
698 ************************************************************/
699 void LTC6804_clrcell()
700 {
701 uint8_t cmd[4];
702 uint16_t cmd_pec;
703
704 //1
705 cmd[0] = 0x07;
706 cmd[1] = 0x11;
707
708 //2
709 cmd_pec = pec15_calc(2, cmd);
710 cmd[2] = (uint8_t)(cmd_pec >> 8);
711 cmd[3] = (uint8_t)(cmd_pec );
712
713 //3
714 wakeup_idle (); //This will guarantee that the LTC6804 isoSPI port is awake. This command can be removed.
715
716 //4
717 output_low(LTC6804_CS);
718 spi_write_read(cmd,4,0,0);
719 output_high(LTC6804_CS);
720 }
721 /*
722 LTC6804_clrcell Function sequence:
723
724 1. Load clrcell command into cmd array
725 2. Calculate clrcell cmd PEC and load pec into cmd array
726 3. wakeup isoSPI port, this step can be removed if isoSPI status is previously guaranteed
727 4. send broadcast clrcell command to LTC6804 daisy chain
728 */
729
730
731 /***********************************************************//**
732 \brief Clears the LTC6804 Auxiliary registers
733
734 The command clears the Auxiliary registers and intiallizes
735 all values to 1. The register will read back hexadecimal 0xFF
736 after the command is sent.
737
738
739 Command Code:
740 -------------
741
742 |CMD[0:1] | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
743 |---------------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|
744 |CLRAUX: | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 2 | 0 |
745 ***************************************************************/
746 void LTC6804_clraux()
747 {
748 uint8_t cmd[4];
749 uint16_t cmd_pec;
750
751 //1
752 cmd[0] = 0x07;
753 cmd[1] = 0x12;
754
755 //2
756 cmd_pec = pec15_calc(2, cmd);
757 cmd[2] = (uint8_t)(cmd_pec >> 8);
758 cmd[3] = (uint8_t)(cmd_pec);
759
760 //3
761 wakeup_idle (); //This will guarantee that the LTC6804 isoSPI port is awake.This command can be removed.
762 //4
763 output_low(LTC6804_CS);
764 spi_write_read(cmd,4,0,0);
765 output_high(LTC6804_CS);
766 }
767 /*
768 LTC6804_clraux Function sequence:
769
770 1. Load clraux command into cmd array
771 2. Calculate clraux cmd PEC and load pec into cmd array
772 3. wakeup isoSPI port, this step can be removed if isoSPI status is previously guaranteed
773 4. send broadcast clraux command to LTC6804 daisy chain
774 */
775
776
777 /*****************************************************//**
778 \brief Write the LTC6804 configuration register
779
780 This command will write the configuration registers of the LTC6804-1s
781 connected in a daisy chain stack. The configuration is written in descending
782 order so the last device's configuration is written first.
783
784 @param[in] uint8_t total_ic; The number of ICs being written to.
785
786 @param[in] uint8_t config[][6] is a two dimensional array of the configuration data that will be written, the array should contain the 6 bytes for each
787 IC in the daisy chain. The lowest IC in the daisy chain should be the first 6 byte block in the array. The array should
788 have the following format:
789 | config[0][0]| config[0][1] | config[0][2]| config[0][3]| config[0][4]| config[0][5]| config[1][0] | config[1][1]| config[1][2]| ..... |
790 |--------------|--------------|--------------|--------------|--------------|--------------|--------------|--------------|--------------|-----------|
791 |IC1 CFGR0 |IC1 CFGR1 |IC1 CFGR2 |IC1 CFGR3 |IC1 CFGR4 |IC1 CFGR5 |IC2 CFGR0 |IC2 CFGR1 | IC2 CFGR2 | ..... |
792
793 The function will calculate the needed PEC codes for the write data
794 and then transmit data to the ICs on a daisy chain.
795
796
797 Command Code:
798 -------------
799 | | CMD[0] | CMD[1] |
800 |---------------|---------------------------------------------------------------|---------------------------------------------------------------|
801 |CMD[0:1] | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
802 |---------------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|
803 |WRCFG: | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
804 ********************************************************/
805 void LTC6804_wrcfg(uint8_t total_ic, //The number of ICs being written to
806 uint8_t config[][6] //A two dimensional array of the configuration data that will be written
807 )
808 {
809 const uint8_t BYTES_IN_REG = 6;
810 const uint8_t CMD_LEN = 4+(8*total_ic);
811 uint8_t *cmd;
812 uint16_t cfg_pec;
813 uint8_t cmd_index; //command counter
814
815 cmd = (uint8_t *)malloc(CMD_LEN*sizeof(uint8_t));
816
817 //1
818 cmd[0] = 0x00;
819 cmd[1] = 0x01;
820 cmd[2] = 0x3d;
821 cmd[3] = 0x6e;
822
823 //2
824 cmd_index = 4;
825 for (uint8_t current_ic = total_ic; current_ic > 0; current_ic--) // executes for each LTC6804 in daisy chain, this loops starts with
826 {
827 // the last IC on the stack. The first configuration written is
828 // received by the last IC in the daisy chain
829
830 for (uint8_t current_byte = 0; current_byte < BYTES_IN_REG; current_byte++) // executes for each of the 6 bytes in the CFGR register
831 {
832 // current_byte is the byte counter
833
834 cmd[cmd_index] = config[current_ic-1][current_byte]; //adding the config data to the array to be sent
835 cmd_index = cmd_index + 1;
836 }
837 //3
838 cfg_pec = (uint16_t)pec15_calc(BYTES_IN_REG, &config[current_ic-1][0]); // calculating the PEC for each ICs configuration register data
839 cmd[cmd_index] = (uint8_t)(cfg_pec >> 8);
840 cmd[cmd_index + 1] = (uint8_t)cfg_pec;
841 cmd_index = cmd_index + 2;
842 }
843
844 //4
845 wakeup_idle (); //This will guarantee that the LTC6804 isoSPI port is awake.This command can be removed.
846 //5
847 output_low(LTC6804_CS);
848 spi_write_array(CMD_LEN, cmd);
849 output_high(LTC6804_CS);
850 free(cmd);
851 }
852 /*
853 WRCFG Sequence:
854
855 1. Load cmd array with the write configuration command and PEC
856 2. Load the cmd with LTC6804 configuration data
857 3. Calculate the pec for the LTC6804 configuration data being transmitted
858 4. wakeup isoSPI port, this step can be removed if isoSPI status is previously guaranteed
859 5. Write configuration data to the LTC6804 daisy chain
860
861 */
862
863 /*!******************************************************
864 \brief Reads configuration registers of a LTC6804 daisy chain
865
866 @param[in] uint8_t total_ic: number of ICs in the daisy chain
867
868 @param[out] uint8_t r_config[][8] is a two dimensional array that the function stores the read configuration data. The configuration data for each IC
869 is stored in blocks of 8 bytes with the configuration data of the lowest IC on the stack in the first 8 bytes
870 block of the array, the second IC in the second 8 byte etc. Below is an table illustrating the array organization:
871
872 |r_config[0][0]|r_config[0][1]|r_config[0][2]|r_config[0][3]|r_config[0][4]|r_config[0][5]|r_config[0][6] |r_config[0][7] |r_config[1][0]|r_config[1][1]| ..... |
873 |--------------|--------------|--------------|--------------|--------------|--------------|----------------|---------------|--------------|--------------|-----------|
874 |IC1 CFGR0 |IC1 CFGR1 |IC1 CFGR2 |IC1 CFGR3 |IC1 CFGR4 |IC1 CFGR5 |IC1 PEC High |IC1 PEC Low |IC2 CFGR0 |IC2 CFGR1 | ..... |
875
876
877 @return int8_t, PEC Status.
878
879 0: Data read back has matching PEC
880
881 -1: Data read back has incorrect PEC
882
883
884 Command Code:
885 -------------
886
887 |CMD[0:1] | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
888 |---------------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|
889 |RDCFG: | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 |
890 ********************************************************/
891 int8_t LTC6804_rdcfg(uint8_t total_ic, //Number of ICs in the system
892 uint8_t r_config[][8] //A two dimensional array that the function stores the read configuration data.
893 )
894 {
895 const uint8_t BYTES_IN_REG = 8;
896
897 uint8_t cmd[4];
898 uint8_t *rx_data;
899 int8_t pec_error = 0;
900 uint16_t data_pec;
901 uint16_t received_pec;
902
903 rx_data = (uint8_t *) malloc((8*total_ic)*sizeof(uint8_t));
904
905 //1
906 cmd[0] = 0x00;
907 cmd[1] = 0x02;
908 cmd[2] = 0x2b;
909 cmd[3] = 0x0A;
910
911 //2
912 wakeup_idle (); //This will guarantee that the LTC6804 isoSPI port is awake. This command can be removed.
913 //3
914 output_low(LTC6804_CS);
915 spi_write_read(cmd, 4, rx_data, (BYTES_IN_REG*total_ic)); //Read the configuration data of all ICs on the daisy chain into
916 output_high(LTC6804_CS); //rx_data[] array
917
918 for (uint8_t current_ic = 0; current_ic < total_ic; current_ic++) //executes for each LTC6804 in the daisy chain and packs the data
919 {
920 //into the r_config array as well as check the received Config data
921 //for any bit errors
922 //4.a
923 for (uint8_t current_byte = 0; current_byte < BYTES_IN_REG; current_byte++)
924 {
925 r_config[current_ic][current_byte] = rx_data[current_byte + (current_ic*BYTES_IN_REG)];
926 }
927 //4.b
928 received_pec = (r_config[current_ic][6]<<8) + r_config[current_ic][7];
929 data_pec = pec15_calc(6, &r_config[current_ic][0]);
930 if (received_pec != data_pec)
931 {
932 pec_error = -1;
933 }
934 }
935
936 free(rx_data);
937 //5
938 return(pec_error);
939 }
940 /*
941 RDCFG Sequence:
942
943 1. Load cmd array with the write configuration command and PEC
944 2. wakeup isoSPI port, this step can be removed if isoSPI status is previously guaranteed
945 3. Send command and read back configuration data
946 4. For each LTC6804 in the daisy chain
947 a. load configuration data into r_config array
948 b. calculate PEC of received data and compare against calculated PEC
949 5. Return PEC Error
950
951 */
952
953 /*!****************************************************
954 \brief Wake isoSPI up from idle state
955 Generic wakeup commannd to wake isoSPI up out of idle
956 *****************************************************/
957 void wakeup_idle()
958 {
959 output_low(LTC6804_CS);
960 delayMicroseconds(2); //Guarantees the isoSPI will be in ready mode
961 output_high(LTC6804_CS);
962 }
963
964 /*!****************************************************
965 \brief Wake the LTC6804 from the sleep state
966
967 Generic wakeup commannd to wake the LTC6804 from sleep
968 *****************************************************/
969 void wakeup_sleep()
970 {
971 output_low(LTC6804_CS);
972 delay(1); // Guarantees the LTC6804 will be in standby
973 output_high(LTC6804_CS);
974 }
975 /*!**********************************************************
976 \brief calaculates and returns the CRC15
977
978 @param[in] uint8_t len: the length of the data array being passed to the function
979
980 @param[in] uint8_t data[] : the array of data that the PEC will be generated from
981
982
983 @returns The calculated pec15 as an unsigned int
984 ***********************************************************/
985 uint16_t pec15_calc(uint8_t len, //Number of bytes that will be used to calculate a PEC
986 uint8_t *data //Array of data that will be used to calculate a PEC
987 )
988 {
989 uint16_t remainder,addr;
990
991 remainder = 16;//initialize the PEC
992 for (uint8_t i = 0; i<len; i++) // loops for each byte in data array
993 {
994 addr = ((remainder>>7)^data[i])&0xff;//calculate PEC table address
995 remainder = (remainder<<8)^crc15Table[addr];
996 }
997 return(remainder*2);//The CRC15 has a 0 in the LSB so the remainder must be multiplied by 2
998 }
999
1000
1001 /*!
1002 \brief Writes an array of bytes out of the SPI port
1003
1004 @param[in] uint8_t len length of the data array being written on the SPI port
1005 @param[in] uint8_t data[] the data array to be written on the SPI port
1006
1007 */
1008 void spi_write_array(uint8_t len, // Option: Number of bytes to be written on the SPI port
1009 uint8_t data[] //Array of bytes to be written on the SPI port
1010 )
1011 {
1012 for (uint8_t i = 0; i < len; i++)
1013 {
1014 spi_write((int8_t)data[i]);
1015 }
1016 }
1017
1018 /*!
1019 \brief Writes and read a set number of bytes using the SPI port.
1020
1021 @param[in] uint8_t tx_data[] array of data to be written on the SPI port
1022 @param[in] uint8_t tx_len length of the tx_data array
1023 @param[out] uint8_t rx_data array that read data will be written too.
1024 @param[in] uint8_t rx_len number of bytes to be read from the SPI port.
1025
1026 */
1027
1028 void spi_write_read(uint8_t tx_Data[],//array of data to be written on SPI port
1029 uint8_t tx_len, //length of the tx data arry
1030 uint8_t *rx_data,//Input: array that will store the data read by the SPI port
1031 uint8_t rx_len //Option: number of bytes to be read from the SPI port
1032 )
1033 {
1034 for (uint8_t i = 0; i < tx_len; i++)
1035 {
1036 spi_write(tx_Data[i]);
1037
1038 }
1039
1040 for (uint8_t i = 0; i < rx_len; i++)
1041 {
1042 rx_data[i] = (uint8_t)spi_read(0xFF);
1043 }
1044
1045 }
1046
1047
1048
LTC6804_rdcfg
int8_t LTC6804_rdcfg(uint8_t total_ic, uint8_t r_config[][8])
Definition: LTC68041.cpp:891
ADCV
uint8_t ADCV[2]
6804 conversion command variables.
Definition: LTC68041.cpp:81
LTC6804_rdaux
int8_t LTC6804_rdaux(uint8_t reg, uint8_t total_ic, uint16_t aux_codes[][6])
Reads and parses the LTC6804 auxiliary registers.
Definition: LTC68041.cpp:495
LTC6804_adcv
void LTC6804_adcv()
Definition: LTC68041.cpp:154
wakeup_sleep
void wakeup_sleep()
Definition: LTC68041.cpp:969
CELL_CH_ALL
#define CELL_CH_ALL
CH Dec Channels to convert 0000 All Cells 0011 Cell 1 and Cell 7 0102 Cell 2 and Cell 8 0113 Cell 3 ...
Definition: LTC68041.h:142
ADAX
uint8_t ADAX[2]
GPIO conversion command.
Definition: LTC68041.cpp:82
LTC6804_clrcell
void LTC6804_clrcell()
Clears the LTC6804 cell voltage registers.
Definition: LTC68041.cpp:699
output_high
#define output_high(pin)
Set "pin" high.
Definition: Linduino.h:75
spi_write_read
void spi_write_read(uint8_t tx_Data[], uint8_t tx_len, uint8_t *rx_data, uint8_t rx_len)
Writes and read a set number of bytes using the SPI port.
Definition: LTC68041.cpp:1028
Linduino.h
Header File for Linduino Libraries and Demo Code.
spi_write
void spi_write(int8_t data)
Write a data byte using the SPI hardware.
Definition: LT_SPI.cpp:176
AUX_CH_ALL
#define AUX_CH_ALL
CHG Dec Channels to convert 000 0 All GPIOS and 2nd Ref 001 1 GPIO 1 010 2 GPIO 2 011 3 GPIO 3 100 4...
Definition: LTC68041.h:164
LTC6804_CS
#define LTC6804_CS
Definition: LTC68041.h:55
spi_enable
void spi_enable(uint8_t spi_clock_divider)
Setup the processor for hardware SPI communication.
Definition: LT_SPI.cpp:160
LTC6804_clraux
void LTC6804_clraux()
Clears the LTC6804 Auxiliary registers.
Definition: LTC68041.cpp:746
LTC6804_initialize
void LTC6804_initialize()
This function will initialize all 6804 variables and the SPI port.
Definition: LTC68041.cpp:92
LTC6804_rdcv_reg
void LTC6804_rdcv_reg(uint8_t reg, uint8_t total_ic, uint8_t *data)
Read the raw data from the LTC6804 cell voltage register.
Definition: LTC68041.cpp:410
data
union LT_union_int32_4bytes data
Definition: DC2094A.ino:138
crc15Table
static const unsigned int crc15Table[256]
Definition: LTC68041.h:90
wakeup_idle
void wakeup_idle()
Definition: LTC68041.cpp:957
output_low
#define output_low(pin)
Set "pin" low.
Definition: Linduino.h:72
MD_NORMAL
#define MD_NORMAL
Definition: LTC68041.h:126
pec15_calc
uint16_t pec15_calc(uint8_t len, uint8_t *data)
Definition: LTC68041.cpp:985
LT_SPI.h
LT_SPI: Routines to communicate with ATmega328P&#39;s hardware SPI port.
LTC6804_rdaux_reg
void LTC6804_rdaux_reg(uint8_t reg, uint8_t total_ic, uint8_t *data)
Read the raw data from the LTC6804 auxiliary register.
Definition: LTC68041.cpp:638
set_adc
void set_adc(uint8_t MD, uint8_t DCP, uint8_t CH, uint8_t CHG)
Definition: LTC68041.cpp:115
NUM_RX_BYT
#define NUM_RX_BYT
Definition: LTC681x.h:108
quikeval_SPI_connect
void quikeval_SPI_connect()
Connect SPI pins to QuikEval connector through the Linduino MUX. This will disconnect I2C...
Definition: LT_SPI.cpp:138
spi_read
int8_t spi_read(int8_t data)
The data byte to be written.
Definition: LT_SPI.cpp:189
aux_codes
static uint16_t aux_codes[TOTAL_IC][6]
The GPIO codes will be stored in the aux_codes[][6] array in the following format: ...
Definition: DC1894.ino:117
LTC6804_adax
void LTC6804_adax()
Definition: LTC68041.cpp:206
DCP_DISABLED
#define DCP_DISABLED
Definition: LTC68041.h:183
LTC68041.h
LTC6804-1 Multicell Battery Monitor.
LTC6804_rdcv
uint8_t LTC6804_rdcv(uint8_t reg, uint8_t total_ic, uint16_t cell_codes[][12])
Reads and parses the LTC6804 cell voltage registers.
Definition: LTC68041.cpp:268
i
static int i
Definition: DC2430A.ino:184
LTC6804_wrcfg
void LTC6804_wrcfg(uint8_t total_ic, uint8_t config[][6])
Write the LTC6804 configuration register.
Definition: LTC68041.cpp:805
spi_write_array
void spi_write_array(uint8_t len, uint8_t data[])
Writes an array of bytes out of the SPI port.
Definition: LTC68041.cpp:1008
cell_codes
static uint16_t cell_codes[TOTAL_IC][12]
The cell codes will be stored in the cell_codes[][12] array in the following format: ...
Definition: DC1651A.ino:108