Linduino  1.3.0
Linear Technology Arduino-Compatible Demonstration Board
DC1942.ino
Go to the documentation of this file.
1 /*!
2 DC1942B
3 LTC6804-2: Battery stack monitor
4 
5 @verbatim
6 NOTES
7  Setup:
8  Set the terminal baud rate to 115200 and select the newline terminator.
9  Ensure all jumpers on the demo board are installed in their default positions from the factory.
10  Refer to Demo Manual D1894B.
11 
12 
13  Menu Entry 1: Write Configuration
14  Writes the configuration register of the LTC6804. This command can be used to turn on the reference.
15 
16  Menu Entry 2: Read Configuration
17  Reads the configuration register of the LTC6804, the read configuration can differ from the written configuration.
18  The GPIO pins will reflect the state of the pin
19 
20  Menu Entry 3: Start Cell voltage conversion
21  Starts a LTC6804 cell channel adc conversion.
22 
23  Menu Entry 4: Read cell voltages
24  Reads the LTC6804 cell voltage registers and prints the results to the serial port.
25 
26  Menu Entry 5: Start Auxiliary voltage conversion
27  Starts a LTC6804 GPIO channel adc conversion.
28 
29  Menu Entry 6: Read Auxiliary voltages
30  Reads the LTC6804 axiliary registers and prints the GPIO voltages to the serial port.
31 
32  Menu Entry 7: Start cell voltage measurement loop
33  The command will continuously measure the LTC6804 cell voltages and print the results to the serial port.
34  The loop can be exited by sending the MCU a 'm' character over the serial link.
35 
36 USER INPUT DATA FORMAT:
37  decimal : 1024
38  hex : 0x400
39  octal : 02000 (leading 0)
40  binary : B10000000000
41  float : 1024.0
42 
43 @endverbatim
44 
45 http://www.linear.com/product/LTC6804-1
46 
47 http://www.linear.com/product/LTC6804-1#demoboards
48 
49 
50 Copyright 2018(c) Analog Devices, Inc.
51 
52 All rights reserved.
53 
54 Redistribution and use in source and binary forms, with or without
55 modification, are permitted provided that the following conditions are met:
56  - Redistributions of source code must retain the above copyright
57  notice, this list of conditions and the following disclaimer.
58  - Redistributions in binary form must reproduce the above copyright
59  notice, this list of conditions and the following disclaimer in
60  the documentation and/or other materials provided with the
61  distribution.
62  - Neither the name of Analog Devices, Inc. nor the names of its
63  contributors may be used to endorse or promote products derived
64  from this software without specific prior written permission.
65  - The use of this software may or may not infringe the patent rights
66  of one or more patent holders. This license does not release you
67  from the requirement that you obtain separate licenses from these
68  patent holders to use this software.
69  - Use of the software either in source or binary form, must be run
70  on or directly connected to an Analog Devices Inc. component.
71 
72 THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
73 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
74 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
75 IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
76 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
77 LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
78 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
79 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
80 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
81 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
82 
83 Copyright 2013 Linear Technology Corp. (LTC)
84  */
85 
86 
87 /*! @file
88  @ingroup LTC68042
89 */
90 
91 #include <Arduino.h>
92 #include <stdint.h>
93 #include "Linduino.h"
94 #include "LT_SPI.h"
95 #include "UserInterface.h"
96 #include "LTC68042.h"
97 #include <SPI.h>
98 
99 const uint8_t TOTAL_IC = 1;//!<number of ICs in the isoSPI network LTC6804-2 ICs must be addressed in ascending order starting at 0.
100 
101 /******************************************************
102  *** Global Battery Variables received from 6804 commands
103  These variables store the results from the LTC6804
104  register reads and the array lengths must be based
105  on the number of ICs on the stack
106  ******************************************************/
107 uint16_t cell_codes[TOTAL_IC][12];
108 /*!<
109  The cell codes will be stored in the cell_codes[][12] array in the following format:
110 
111  | cell_codes[0][0]| cell_codes[0][1] | cell_codes[0][2]| ..... | cell_codes[0][11]| cell_codes[1][0] | cell_codes[1][1]| ..... |
112  |------------------|------------------|------------------|--------------|-------------------|-------------------|-----------------|----------|
113  |IC1 Cell 1 |IC1 Cell 2 |IC1 Cell 3 | ..... | IC1 Cell 12 |IC2 Cell 1 |IC2 Cell 2 | ..... |
114 ****/
115 
116 uint16_t aux_codes[TOTAL_IC][6];
117 /*!<
118  The GPIO codes will be stored in the aux_codes[][6] array in the following format:
119 
120  | 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]| ..... |
121  |-----------------|-----------------|-----------------|-----------------|-----------------|-----------------|-----------------|---------------|-----------|
122  |IC1 GPIO1 |IC1 GPIO2 |IC1 GPIO3 |IC1 GPIO4 |IC1 GPIO5 |IC1 Vref2 |IC2 GPIO1 |IC2 GPIO2 | ..... |
123 */
124 
125 uint8_t tx_cfg[TOTAL_IC][6];
126 /*!<
127  The tx_cfg[][6] stores the LTC6804 configuration data that is going to be written
128  to the LTC6804 ICs on the daisy chain. The LTC6804 configuration data that will be
129  written should be stored in blocks of 6 bytes. The array should have the following format:
130 
131  | tx_cfg[0][0]| tx_cfg[0][1] | tx_cfg[0][2]| tx_cfg[0][3]| tx_cfg[0][4]| tx_cfg[0][5]| tx_cfg[1][0] | tx_cfg[1][1]| tx_cfg[1][2]| ..... |
132  |--------------|--------------|--------------|--------------|--------------|--------------|--------------|--------------|--------------|-----------|
133  |IC1 CFGR0 |IC1 CFGR1 |IC1 CFGR2 |IC1 CFGR3 |IC1 CFGR4 |IC1 CFGR5 |IC2 CFGR0 |IC2 CFGR1 | IC2 CFGR2 | ..... |
134 
135 */
136 
137 uint8_t rx_cfg[TOTAL_IC][8];
138 /*!<
139  the rx_cfg[][8] array stores the data that is read back from a LTC6804-1 daisy chain.
140  The configuration data for each IC is stored in blocks of 8 bytes. Below is an table illustrating the array organization:
141 
142 |rx_config[0][0]|rx_config[0][1]|rx_config[0][2]|rx_config[0][3]|rx_config[0][4]|rx_config[0][5]|rx_config[0][6] |rx_config[0][7] |rx_config[1][0]|rx_config[1][1]| ..... |
143 |---------------|---------------|---------------|---------------|---------------|---------------|-----------------|----------------|---------------|---------------|-----------|
144 |IC1 CFGR0 |IC1 CFGR1 |IC1 CFGR2 |IC1 CFGR3 |IC1 CFGR4 |IC1 CFGR5 |IC1 PEC High |IC1 PEC Low |IC2 CFGR0 |IC2 CFGR1 | ..... |
145 */
146 
147 /*!**********************************************************************
148  \brief Inititializes hardware and variables
149  ***********************************************************************/
150 void setup()
151 {
152  Serial.begin(115200);
153  LTC6804_initialize(); //Initialize LTC6804 hardware
154  init_cfg(); //initialize the 6804 configuration array to be written
155  print_menu();
156 }
157 
158 /*!*********************************************************************
159  \brief main loop
160 
161 ***********************************************************************/
162 void loop()
163 {
164 
165  if (Serial.available()) // Check for user input
166  {
167  uint32_t user_command;
168  user_command = read_int(); // Read the user command
169  Serial.println(user_command);
170  run_command(user_command);
171  }
172 }
173 
174 
175 /*!*****************************************
176  \brief executes the user inputted command
177 
178  Menu Entry 1: Write Configuration \n
179  Writes the configuration register of the LTC6804. This command can be used to turn on the reference
180  and increase the speed of the ADC conversions.
181 
182  Menu Entry 2: Read Configuration \n
183  Reads the configuration register of the LTC6804, the read configuration can differ from the written configuration.
184  The GPIO pins will reflect the state of the pin
185 
186  Menu Entry 3: Start Cell voltage conversion \n
187  Starts a LTC6804 cell channel adc conversion.
188 
189  Menu Entry 4: Read cell voltages
190  Reads the LTC6804 cell voltage registers and prints the results to the serial port.
191 
192  Menu Entry 5: Start Auxiliary voltage conversion
193  Starts a LTC6804 GPIO channel adc conversion.
194 
195  Menu Entry 6: Read Auxiliary voltages
196  Reads the LTC6804 axiliary registers and prints the GPIO voltages to the serial port.
197 
198  Menu Entry 7: Start cell voltage measurement loop
199  The command will continuously measure the LTC6804 cell voltages and print the results to the serial port.
200  The loop can be exited by sending the MCU a 'm' character over the serial link.
201 
202 *******************************************/
203 void run_command(uint16_t cmd)
204 {
205  int8_t error = 0;
206 
207  char input = 0;
208  switch (cmd)
209  {
210 
211  case 1:
212  wakeup_sleep();
214  print_config();
215  break;
216 
217  case 2:
218  wakeup_sleep();
219  error = LTC6804_rdcfg(TOTAL_IC,rx_cfg);
220  if (error == -1)
221  {
222  Serial.println("A PEC error was detected in the received data");
223  }
224  print_rxconfig();
225  break;
226 
227  case 3:
228  wakeup_sleep();
229  LTC6804_adcv();
230  delay(3);
231  Serial.println("cell conversion completed");
232  Serial.println();
233  break;
234 
235  case 4:
236  wakeup_sleep();
237  error = LTC6804_rdcv(0, TOTAL_IC,cell_codes); // Set to read back all cell voltage registers
238  if (error == -1)
239  {
240  Serial.println("A PEC error was detected in the received data");
241  }
242  print_cells();
243  break;
244 
245  case 5:
246  wakeup_sleep();
247  LTC6804_adax();
248  delay(3);
249  Serial.println("aux conversion completed");
250  Serial.println();
251  break;
252 
253  case 6:
254  wakeup_sleep();
255  error = LTC6804_rdaux(0,TOTAL_IC,aux_codes); // Set to read back all aux registers
256  if (error == -1)
257  {
258  Serial.println("A PEC error was detected in the received data");
259  }
260  print_aux();
261  break;
262 
263  case 7:
264  Serial.println("transmit 'm' to quit");
265  wakeup_sleep();
267  while (input != 'm')
268  {
269  if (Serial.available() > 0)
270  {
271  input = read_char();
272  }
273  wakeup_idle();
274  LTC6804_adcv();
275  delay(10);
276  wakeup_idle();
277  error = LTC6804_rdcv(0, TOTAL_IC,cell_codes);
278  if (error == -1)
279  {
280  Serial.println("A PEC error was detected in the received data");
281  }
282  print_cells();
283  delay(500);
284  }
285  print_menu();
286  break;
287 
288  default:
289  Serial.println("Incorrect Option");
290  break;
291  }
292 }
293 
294 /*!***********************************
295  \brief Initializes the configuration array
296  **************************************/
297 void init_cfg()
298 {
299  for (int i = 0; i<TOTAL_IC; i++)
300  {
301  tx_cfg[i][0] = 0xFE;
302  tx_cfg[i][1] = 0x00 ;
303  tx_cfg[i][2] = 0x00 ;
304  tx_cfg[i][3] = 0x00 ;
305  tx_cfg[i][4] = 0x00 ;
306  tx_cfg[i][5] = 0x00 ;
307  }
308 }
309 
310 /*!*********************************
311  \brief Prints the main menu
312 ***********************************/
314 {
315  Serial.println("Please enter LTC6804 Command");
316  Serial.println("Write Configuration: 1");
317  Serial.println("Read Configuration: 2");
318  Serial.println("Start Cell Voltage Conversion: 3");
319  Serial.println("Read Cell Voltages: 4");
320  Serial.println("Start Aux Voltage Conversion: 5");
321  Serial.println("Read Aux Voltages: 6");
322  Serial.println("loop cell voltages: 7");
323  Serial.println("Please enter command: ");
324  Serial.println();
325 }
326 
327 
328 
329 /*!************************************************************
330  \brief Prints Cell Voltage Codes to the serial port
331  *************************************************************/
333 {
334 
335 
336  for (int current_ic = 0 ; current_ic < TOTAL_IC; current_ic++)
337  {
338  Serial.print(" IC ");
339  Serial.print(current_ic+1,DEC);
340  for (int i=0; i<12; i++)
341  {
342  Serial.print(" C");
343  Serial.print(i+1,DEC);
344  Serial.print(":");
345  Serial.print(cell_codes[current_ic][i]*0.0001,4);
346  Serial.print(",");
347  }
348  Serial.println();
349  }
350  Serial.println();
351 }
352 
353 /*!****************************************************************************
354  \brief Prints GPIO Voltage Codes and Vref2 Voltage Code onto the serial port
355  *****************************************************************************/
356 void print_aux()
357 {
358 
359  for (int current_ic =0 ; current_ic < TOTAL_IC; current_ic++)
360  {
361  Serial.print(" IC ");
362  Serial.print(current_ic+1,DEC);
363  for (int i=0; i < 5; i++)
364  {
365  Serial.print(" GPIO-");
366  Serial.print(i+1,DEC);
367  Serial.print(":");
368  Serial.print(aux_codes[current_ic][i]*0.0001,4);
369  Serial.print(",");
370  }
371  Serial.print(" Vref2");
372  Serial.print(":");
373  Serial.print(aux_codes[current_ic][5]*0.0001,4);
374  Serial.println();
375  }
376  Serial.println();
377 }
378 /*!******************************************************************************
379  \brief Prints the Configuration data that is going to be written to the LTC6804
380  to the serial port.
381  ********************************************************************************/
383 {
384  int cfg_pec;
385 
386  Serial.println("Written Configuration: ");
387  for (int current_ic = 0; current_ic<TOTAL_IC; current_ic++)
388  {
389  Serial.print(" IC ");
390  Serial.print(current_ic+1,DEC);
391  Serial.print(": ");
392  Serial.print("0x");
393  serial_print_hex(tx_cfg[current_ic][0]);
394  Serial.print(", 0x");
395  serial_print_hex(tx_cfg[current_ic][1]);
396  Serial.print(", 0x");
397  serial_print_hex(tx_cfg[current_ic][2]);
398  Serial.print(", 0x");
399  serial_print_hex(tx_cfg[current_ic][3]);
400  Serial.print(", 0x");
401  serial_print_hex(tx_cfg[current_ic][4]);
402  Serial.print(", 0x");
403  serial_print_hex(tx_cfg[current_ic][5]);
404  Serial.print(", Calculated PEC: 0x");
405  cfg_pec = pec15_calc(6,&tx_cfg[current_ic][0]);
406  serial_print_hex((uint8_t)(cfg_pec>>8));
407  Serial.print(", 0x");
408  serial_print_hex((uint8_t)(cfg_pec));
409  Serial.println();
410  }
411  Serial.println();
412 }
413 
414 /*!*****************************************************************
415  \brief Prints the Configuration data that was read back from the
416  LTC6804 to the serial port.
417  *******************************************************************/
419 {
420  Serial.println("Received Configuration ");
421  for (int current_ic=0; current_ic<TOTAL_IC; current_ic++)
422  {
423  Serial.print(" IC ");
424  Serial.print(current_ic+1,DEC);
425  Serial.print(": 0x");
426  serial_print_hex(rx_cfg[current_ic][0]);
427  Serial.print(", 0x");
428  serial_print_hex(rx_cfg[current_ic][1]);
429  Serial.print(", 0x");
430  serial_print_hex(rx_cfg[current_ic][2]);
431  Serial.print(", 0x");
432  serial_print_hex(rx_cfg[current_ic][3]);
433  Serial.print(", 0x");
434  serial_print_hex(rx_cfg[current_ic][4]);
435  Serial.print(", 0x");
436  serial_print_hex(rx_cfg[current_ic][5]);
437  Serial.print(", Received PEC: 0x");
438  serial_print_hex(rx_cfg[current_ic][6]);
439  Serial.print(", 0x");
440  serial_print_hex(rx_cfg[current_ic][7]);
441  Serial.println();
442  }
443  Serial.println();
444 }
445 
446 void serial_print_hex(uint8_t data)
447 {
448  if (data< 16)
449  {
450  Serial.print("0");
451  Serial.print((byte)data,HEX);
452  }
453  else
454  Serial.print((byte)data,HEX);
455 }
int8_t LTC6804_rdcfg(uint8_t total_ic, uint8_t r_config[][8])
Definition: LTC68041.cpp:891
static void run_command(uint16_t cmd)
Definition: DC1942.ino:203
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
void LTC6804_adcv()
Definition: LTC68041.cpp:154
void wakeup_sleep()
Definition: LTC68041.cpp:969
unsigned char user_command
static void print_cells()
Definition: DC1942.ino:332
static uint8_t rx_cfg[TOTAL_IC][8]
the rx_cfg[][8] array stores the data that is read back from a LTC6804-1 daisy chain.
Definition: DC1942.ino:137
Header File for Linduino Libraries and Demo Code.
static void print_rxconfig()
Definition: DC1942.ino:418
static void init_cfg()
Definition: DC1942.ino:297
void LTC6804_initialize()
This function will initialize all 6804 variables and the SPI port.
Definition: LTC68041.cpp:92
static void serial_print_hex(uint8_t data)
Definition: DC1942.ino:446
union LT_union_int32_4bytes data
Definition: DC2094A.ino:138
void wakeup_idle()
Definition: LTC68041.cpp:957
#define input(pin)
Return the state of pin "pin".
Definition: Linduino.h:79
LTC6804-2 Multicell Battery Monitor.
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: DC1942.ino:116
static int error
static uint8_t tx_cfg[TOTAL_IC][6]
The tx_cfg[][6] stores the LTC6804 configuration data that is going to be written to the LTC6804 ICs ...
Definition: DC1942.ino:125
uint16_t pec15_calc(uint8_t len, uint8_t *data)
Definition: LTC68041.cpp:985
const uint8_t TOTAL_IC
number of ICs in the isoSPI network LTC6804-2 ICs must be addressed in ascending order starting at 0...
Definition: DC1942.ino:99
static void loop()
Definition: DC1942.ino:162
LT_SPI: Routines to communicate with ATmega328P&#39;s hardware SPI port.
static void print_config()
Definition: DC1942.ino:382
static void print_aux()
Definition: DC1942.ino:356
int32_t read_int()
void LTC6804_adax()
Definition: LTC68041.cpp:206
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: DC1942.ino:107
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
static int i
Definition: DC2430A.ino:184
void LTC6804_wrcfg(uint8_t total_ic, uint8_t config[][6])
Write the LTC6804 configuration register.
Definition: LTC68041.cpp:805
int8_t read_char()
static void setup()
Definition: DC1942.ino:150
static void print_menu()
Definition: DC1942.ino:313