Linduino  1.3.0
Linear Technology Arduino-Compatible Demonstration Board
DC2334A.ino
Go to the documentation of this file.
1 /*!
2 @verbatim
3 
4 Linear Technology DC2334A Demonstration Board.
5 LTC2947: LTC2947 a high-precision power and energy monitor
6 with an internal sense resistor supporting up to 30A.
7 
8 The LTC2947 is a high-precision power and energy
9 monitor with an internal sense resistor supporting up
10 to 30A. Three internal No Latency delta sigma ADCs ensure
11 accurate measurement of voltage and current, while high-
12 bandwidth analog multiplication of voltage and current
13 provides accurate power measurement in a wide range of
14 applications. Internal or external clocking options enable
15 precise charge and energy measurements.
16 An internal 300 micro ohms, temperature-compensated sense
17 resistor minimizes efficiency loss and external compo-
18 nents, simplifying energy measurement applications while
19 enabling high accuracy current measurement over the full
20 temperature range. For more details see following URLs:
21 
22 http://www.linear.com/product/LTC2947
23 http://www.linear.com/product/LTC2947#demoboards
24 
25 NOTES
26 Setup:
27 Set the terminal baud rate to 115200 and select the newline terminator.
28 
29 USER INPUT DATA FORMAT:
30 decimal : 1024
31 hex : 0x400
32 octal : 02000 (leading 0 "zero")
33 binary : B10000000000
34 float : 1024.0
35 
36 See the DC2334 demo manual and LTC2947 datasheet for more details on
37 operation.
38 
39 @endverbatim
40 
41 
42 
43 Copyright 2018(c) Analog Devices, Inc.
44 
45 All rights reserved.
46 
47 Redistribution and use in source and binary forms, with or without
48 modification, are permitted provided that the following conditions are met:
49  - Redistributions of source code must retain the above copyright
50  notice, this list of conditions and the following disclaimer.
51  - Redistributions in binary form must reproduce the above copyright
52  notice, this list of conditions and the following disclaimer in
53  the documentation and/or other materials provided with the
54  distribution.
55  - Neither the name of Analog Devices, Inc. nor the names of its
56  contributors may be used to endorse or promote products derived
57  from this software without specific prior written permission.
58  - The use of this software may or may not infringe the patent rights
59  of one or more patent holders. This license does not release you
60  from the requirement that you obtain separate licenses from these
61  patent holders to use this software.
62  - Use of the software either in source or binary form, must be run
63  on or directly connected to an Analog Devices Inc. component.
64 
65 THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
66 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
67 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
68 IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
69 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
70 LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
71 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
72 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
73 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
74 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75 */
76 
77 /*! @file
78 @ingroup LTC2947
79 */
80 
81 #include <Arduino.h>
82 #include <stdint.h>
83 #include "Linduino.h"
84 #include "LT_SPI.h"
85 #include "LT_I2C.h"
86 #include "UserInterface.h"
87 #include "QuikEval_EEPROM.h"
88 #include "LTC2947.h"
89 #include <SPI.h>
90 #include <LiquidCrystal.h>
91 
92 //! Global variables
93 static uint8_t demo_board_connected; //!< Set to 1 if the board is connected
94 
95 //! Initialize Linduino
96 void setup()
97 {
98  char demo_name[] = "DC2334"; //! Demo Board Name stored in QuikEval EEPROM
99  spi_enable(SPI_CLOCK_DIV16); //! Configure the spi port for 1MHz SCK
100  quikeval_SPI_connect(); //! Connect SPI to main data port (in case the demo board is
101  //! configured to SPI mode this avoids pin conflicts when
102  //! reading the EEPROM with discover_demo_board)
103  quikeval_I2C_init(); //! Configure the EEPROM I2C port for 100kHz
104  Serial.begin(115200); //! Initialize the serial port to the PC
105  print_title(); //! print title
106  demo_board_connected = discover_demo_board(demo_name); //! read demo board's EEPROM
108  {
109  Serial.print(F("Found correct demo board"));
110  }
111  else
112  {
113  Serial.println(F("Will attempt to proceed"));
115  }
116  setup_ser_mode(); //! setup LTC2947's serial interface mode
117  go_idle_cfg_tbctl(); //! go to idle and configure TBCTL
118  print_main_menu(); //! show main menu
119 }
120 
121 //! Repeats Linduino loop
122 void loop()
123 {
124  if (Serial.available()) //! Do nothing if serial is not available
125  {
126  int32_t command = read_int(); //! get user input
127  Serial.println(command); //! echo selection
128  Serial.println();
129  switch (command)
130  {
131  case 1:
133  break;
134  case 2:
136  break;
137  case 3:
139  break;
140  case 4:
142  break;
143  case 5:
144  mm5_accu_init();
145  break;
146  case 6:
147  mm6_min_max();
148  break;
149  case 7:
150  mm7_gpio_ctrl();
151  break;
152  case 8:
153  mm8_ara();
154  break;
155 #ifdef LTC2947_DEBUG
156  case 99:
157  LTC2947_DoubleToBytes_Test();
158  break;
159 #endif
160  default:
161  Serial.println(F("Unknown command!"));
162  break;
163  }
164  print_main_menu();
165  }
166 }
167 
168 //! Print the title block
170 {
171  Serial.println();
172  Serial.println(F("*****************************************************************"));
173  Serial.println(F("* DC2334A Demonstration Program *"));
174  Serial.println(F("* *"));
175  Serial.println(F("* This program demonstrates the basic features of the LTC2947 *"));
176  Serial.println(F("* a high-precision power and energy monitor with an internal *"));
177  Serial.println(F("* sense resistor supporting up to 30A. *"));
178  Serial.println(F("* Set the baud rate to 115200 and select the newline terminator.*"));
179  Serial.println(F("*****************************************************************"));
180 }
181 
182 //! Print the main menu
184 {
185  Serial.println(F("\n\nMain Menu"));
186  Serial.println(F(" 1. Operation control menu"));
187  Serial.println(F(" 2. Read Status and Alert Registers"));
188  Serial.println(F(" 3. Read measurements (I,P,V,TEMP,VCC)"));
189  Serial.println(F(" 4. Read accumulated measurements (C,E,TB)"));
190  Serial.println(F(" 5. Init accumulated measurements (C,E,TB)"));
191  Serial.println(F(" 6. Read min/max values of I,V,P,TEMP"));
192  Serial.println(F(" 7. GPIO control"));
194  Serial.println(F(" 8. Send ARA"));
195 
196 #ifdef LTC2947_DEBUG
197  Serial.println(F(" 99. LTC2947_DoubleToBytes_Test"));
198 #endif
199  Serial.print(F("Enter: "));
200 }
201 
202 //! LTC2947's operation control menu
204 {
205  Serial.println(F("\n\nOperation control"));
206  Serial.println(F(" 1. Continuous measurement"));
207  Serial.println(F(" 2. Single measurement"));
208  Serial.println(F(" 3. Clear measurement results"));
209  Serial.println(F(" 4. Stop measurement"));
210  Serial.println(F(" 5. Shutdown"));
211  Serial.println(F(" 6. Wakeup"));
212  Serial.println(F(" 7. Read current operation mode"));
213  Serial.println(F(" 8. RESET"));
214  Serial.println(F(" Any other number to cancel"));
215  Serial.print(F("Enter: "));
216 
217  while (!Serial.available()); //! wait for user input
218  int32_t opt = read_int(); //! Read user input command
219  Serial.println(opt); //! echo user input
220  switch (opt)
221  {
222  case 1: //! Continuous measurement
224  break;
225  case 2: //! Single measurement
227  break;
228  case 3: //! Clear measurement results
229  {
230  byte data[1];
231  LTC2947_RD_BYTE(LTC2947_REG_OPCTL, data); //! store current operation mode
233  LTC2947_BM_OPCTL_CLR | //! set clear bit
234  (data[0] & LTC2947_BM_OPCTL_CONT) //! restore last operation mode (idle or cont. meas.)
235  );
236  }
237  break;
238  case 4: //! Stop measurement
240  break;
241  case 5: //! Shutdown
243  break;
244  case 6: //! Wakeup
245  {
246  int16_t wakeupTime = LTC2947_wake_up();
247  if (wakeupTime < 0)
248  Serial.println(F("Failed to wakeup LTC2947 due to timeout"));
249  else
250  {
251  Serial.print(F("LTC2947 woke up after "));
252  Serial.print(wakeupTime);
253  Serial.println(F(" milliseconds"));
254  }
255  }
256  break;
257  case 7: //! Read current operation mode
258  {
259  byte data[1];
261  if (bitMaskSetChk(data[0], LTC2947_BM_OPCTL_CONT))
262  Serial.println(F("Continuous measurement enabled"));
263  else if (bitMaskSetChk(data[0], LTC2947_BM_OPCTL_SHDN))
264  Serial.println(F("LTC2947 was in shutdown mode and should\nhave been woken up by this read operation"));
265  else
266  Serial.println(F("Idle mode"));
267  }
268  break;
269  case 8: //! make a reset of LTC2947
271  delay(120); //! give device some time to restart
272  go_idle_cfg_tbctl(); //! re-configure TBCTL
273  break;
274  default:
275  Serial.println(F("Unsupported command, canceled!"));
276  break;
277  }
278 }
279 
280 //! Read and print all status / alert registers
282 {
283  Serial.println(F("\nSTATUS / ALERT registers"));
284  uint8_t values[8];
286  for (uint8_t i = 0; i < 8; i++)
287  parse_status_alert_regs(values, i);
288 }
289 
290 //! Read measurement results
292 {
293  Serial.println(F("\nMeasurements"));
294  float current, power, voltage, temp, vcc;
295 
296  LTC2947_SetPageSelect(false); //! make sure we are on page 0
297  LTC2947_Read_I_P_V_TEMP_VCC(&current, &power, &voltage, &temp, &vcc);
298 
299  Serial.print(F("Current(A): "));
300  Serial.println(current, 3);
301 
302  Serial.print(F("Power(W) : "));
303  Serial.println(power, 2);
304 
305  Serial.print(F("Voltage(V): "));
306  Serial.println(voltage, 3);
307 
308  Serial.print(F("Temp.(C) : "));
309  Serial.println(temp, 1);
310 
311  Serial.print(F("Supply(V) : "));
312  Serial.println(vcc, 2);
313 
314  Serial.println();
315 }
316 
317 //! Read accumulated measurement results
319 {
320  Serial.println(F("\nAccumulated measurements"));
321  double C, E, TB;
322  boolean accuSet1 = true; //! start with accu set 1
323  LTC2947_SetPageSelect(false); //! make sure we are on page 0
324  do
325  {
326  LTC2947_Read_C_E_TB(accuSet1, &C, &E, &TB); //! read values from device
327  Serial.print(F("\nAccu set "));
328  Serial.println(accuSet1 ? 1 : 2);
329 
330  Serial.print(F("Charge(As): "));
331  Serial.println(C, 4); // smallest increment is roughly 3 mA * 100 ms = 0.0003 As
332 
333  Serial.print(F("Energy(Ws): "));
334  Serial.println(E, 3); // smallest increment is roughly 50 mW * 100 ms = 0.005 Ws
335 
336  Serial.print(F("Time(s) : "));
337  Serial.println(TB, 1); // smallest increment is roughly 100 ms = 0.1 s
338 
339  if (!accuSet1)
340  break; //! DONE!
341  accuSet1 = false;
342  }
343  while (true);
344 }
345 
346 //! Initialize accumulators with user defined values
348 {
349  boolean accuSet1;
350  byte bytes[16]; //! 16 bytes to store charge, energy and time
351  uint8_t sel;
352  boolean lsbs;
353  double cetb;
354  uint8_t accu_base_addr;
355 
356  //! Which ACCUs? (C1,E1,TB1 or C2,E2,TB2)
357  Serial.println(F("\nInit Accumulator set 1 or 2?"));
358  Serial.print(F("Enter: "));
359  while (!Serial.available());
360  sel = read_int();
361  accuSet1 = (sel == 1);
362  if (accuSet1)
363  Serial.println(F("1 (C1,E1,TB1)"));
364  else if (sel == 2)
365  Serial.println(F("2 (C2,E2,TB2)"));
366  else
367  Serial.println(F("Unknown selection, will use C2,E2,TB2"));
368 
369  //! assign base register address of the accu set
370  accu_base_addr = accuSet1 ? LTC2947_VAL_C1 : LTC2947_VAL_C2;
371 
372  //! Set accus in LSBs or in real values?
373  Serial.println(F("\nInput LSBs or real values in As/Ws/s?"));
374  Serial.println(F(" 1. LSBs"));
375  Serial.println(F(" 2. Real Values in As/Ws/s"));
376  Serial.print(F("Enter: "));
377  while (!Serial.available());
378  sel = read_int();
379  lsbs = (sel == 1);
380  if (lsbs)
381  Serial.println(F("1 (LSBs)"));
382  else if (sel == 2)
383  Serial.println(F("2 (As/Ws/s)"));
384  else
385  Serial.println(F("Unknown selection, will use 1 (LSBs)"));
386 
387  //! Input new charge value
388  Serial.println();
389  Serial.print(accuSet1 ? F("C1: ") : F("C2: "));
390  while (!Serial.available());
391  if (lsbs)
392  //! convert integer input to floating point value
393  //! Note: actually this is not necessary as we have to
394  //! write integer values to the device anyway. So
395  //! we could convert this int value directly to
396  //! a bytes array and write it to the device instead of first going to float
397  //! and then going back to an integer representation
398  //! in form of a byte array. Still the focus of the code below
399  //! is to show the usage of the function LTC2947_DoubleToBytes
400  cetb = read_int() * LTC2947_LSB_C1;
401  else
402  cetb = read_float();
403  Serial.print(cetb, 8);
404  Serial.println(F(" As"));
405  LTC2947_DoubleToBytes(cetb, LTC2947_LSB_C1, bytes, 6); //! convert to bytes
406 
407  //! Input new energy value
408  Serial.println();
409  Serial.print(accuSet1 ? F("E1: ") : F("E2: "));
410  while (!Serial.available());
411  if (lsbs)
412  cetb = read_int() * LTC2947_LSB_E1;
413  else
414  cetb = read_float();
415  Serial.print(cetb, 8);
416  Serial.println(F(" Ws"));
417  LTC2947_DoubleToBytes(cetb, LTC2947_LSB_E1, bytes + 6, 6); //! convert to bytes
418 
419  //! Input new time value
420  Serial.println();
421  Serial.print(accuSet1 ? F("TB1: ") : F("TB2: "));
422  while (!Serial.available());
423  if (lsbs)
424  cetb = read_int() * LTC2947_LSB_TB1;
425  else
426  cetb = read_float();
427  Serial.print(cetb, 8);
428  Serial.println(F(" s"));
429  LTC2947_DoubleToBytes(cetb, LTC2947_LSB_TB1, bytes + 6 + 6, 4); //! convert to bytes
430 
431  Serial.print(F("\nC,E,TB will be written with following values starting at address 0x"));
432  LTC2947_SerialPrint8hex(accu_base_addr);
433  Serial.println();
434 
435  //! report the whole byte array
436  for (int8_t i = 0; i < 16; i++)
437  {
438  Serial.print(i);
439  Serial.print(F(":0x"));
440  LTC2947_SerialPrint8hex(bytes[i]);
441  if (i == 0)
442  Serial.print(F(" (MSB)"));
443  else if (i == 15)
444  Serial.print(F(" (LSB)"));
445  Serial.println();
446  }
447 
448  LTC2947_SetPageSelect(false); //! make sure we are on page 0
449  LTC2947_WR_BYTES(accu_base_addr, 16, bytes); //! write new values to the device
450 
451  //! readback values from the device
452  Serial.println(F("\nRead back of both accu sets from device:"));
454 }
455 
456 //! Read tracking (min/max) measurement values
458 {
459  float min, max;
460  byte bytes[8];
461  Serial.println(F("\nMIN/MAX measurements"));
462 
463  //! read current/power max/min from device
465 
466  //! current max/min
467  //! LSB is given in mA, *1e-3 gives A. Note also the different LSB size of
468  //! LTC2947_LSB_IMAX (or LTC2947_LSB_IMIN which is the same) compared to LTC2947_LSB_I!
469  Serial.print(F("Current(A) "));
470  max = LTC2947_2BytesToInt16(bytes + 0) * LTC2947_LSB_IMAX * 1e-3;
471  min = LTC2947_2BytesToInt16(bytes + 2) * LTC2947_LSB_IMIN * 1e-3;
472  print_min_max(min, max, 3, bytes + 2, bytes + 0);
473 
474  Serial.print(F("Power(W) "));
475  max = LTC2947_2BytesToInt16(bytes + 4) * LTC2947_LSB_PMAX * 1e-3;
476  min = LTC2947_2BytesToInt16(bytes + 6) * LTC2947_LSB_PMIN * 1e-3;
477  print_min_max(min, max, 3, bytes + 6, bytes + 4);
478 
479  //! read voltage/temperature max/min from device
481 
482  Serial.print(F("Voltage(V) "));
483  max = LTC2947_2BytesToInt16(bytes + 0) * LTC2947_LSB_VMAX * 1e-3;
484  min = LTC2947_2BytesToInt16(bytes + 2) * LTC2947_LSB_VMIN * 1e-3;
485  print_min_max(min, max, 3, bytes + 2, bytes + 0);
486 
487  Serial.print(F("Temp.(C) "));
490  print_min_max(min, max, 2, bytes + 6, bytes + 4);
491 }
492 
493 //! LTC2947's GPIO control menu
495 {
496  Serial.println(F("\n\nGPIO control"));
497  Serial.println(F(" 1. Disable output driver"));
498  Serial.println(F(" 2. Enable output driver"));
499  Serial.println(F(" 3. Set GPO"));
500  Serial.println(F(" 4. Clr GPO"));
501  Serial.println(F(" 5. Read GPIO pin state"));
502  Serial.print(F("Enter: "));
503 
504  while (!Serial.available()); //! wait for user input
505  int32_t opt = read_int(); //! Read user input command
506  Serial.println(opt); //! echo user input
507  switch (opt)
508  {
509  case 1:
510  case 2:
511  Serial.print(F("GPIO output driver "));
512  LTC2947_GPIO_PinMode((opt == 1)
513  ? INPUT
514  : OUTPUT);
515  Serial.println((opt == 1)
516  ? F("disabled")
517  : F("enabled")
518  );
519  break;
520  case 3:
521  case 4:
522  Serial.print(F("GPIO pin state set "));
523  LTC2947_GPIO_SetPinState((opt == 3)
524  ? HIGH
525  : LOW);
526  Serial.println((opt == 3)
527  ? F("high")
528  : F("low")
529  );
530  break;
531  case 5:
532  Serial.print(F("GPIO pin "));
533  Serial.println(LTC2947_GPIO_Read()
534  ? F("high")
535  : F("low")
536  );
537  break;
538  default:
539  Serial.println(F("Unsupported command, canceled!"));
540  break;
541  }
542 }
543 
544 //! SMBus Alert Response Protocol
545 void mm8_ara()
546 {
547  uint8_t slvAddr;
548  uint8_t result;
549  Serial.print(F("\nSend ARA, slave response:0x"));
550  result = LTC2947_Ara(&slvAddr);
551  LTC2947_SerialPrint8hex(slvAddr);
552  switch (result)
553  {
554  case LTC2947_ARA_ERROR:
555  Serial.println(F(" (ERROR: I2C communication failed)"));
556  break;
558  Serial.println(F(" (LTC2947 response)"));
559  break;
561  Serial.println(F(" (other slave response)"));
562  break;
564  Serial.println(F(" (no slave response)"));
565  break;
567  if (slvAddr == LTC2947_I2C_Slave_Addr)
568  Serial.println(F(" (ERROR: LTC2947 response without WR bit)"));
569  else
570  Serial.println(F(" (ERROR: other slave response without WR bit)"));
571  break;
572  }
573 }
574 
575 //! prints two (min/max) values with label including the 16 bit raw values
576 void print_min_max(float min, float max, uint8_t digits, byte *minBytes, byte *maxBytes)
577 {
578  Serial.print(F("MIN: "));
579  if (min >= 0)
580  Serial.print('+');
581  Serial.print(min, digits); //! print float value
582  Serial.print(F(" (0x"));
583  //! print integer value
585  Serial.print(F(") / MAX: "));
586  if (max >= 0)
587  Serial.print('+');
588  Serial.print(max, digits); //! print float value
589  Serial.print(F(" (0x"));
590  //! print integer value
592  Serial.println(')');
593 }
594 
595 //! put LTC2947 into idle mode and configure TBCTL
597 {
598  byte data[1];
599  byte tbctl;
600  LTC2947_RD_BYTE(LTC2947_REG_OPCTL, data); //! check if we are in idle mode
601  if (data[0] != 0) //! not in idle mode
602  {
603  Serial.println(F("Will set LTC2947 to IDLE mode now!"));
604  LTC2947_WR_BYTE(LTC2947_REG_OPCTL, 0);//! go to idle mode
605  delay(200); //! after 2 system tickes (2x100ms) LTC2947 must be in idle mode
607  }
608  if (data[0] == 0)
609  {
610  Serial.println(F("LTC2947 in IDLE mode now!"));
611  }
612  else
613  {
614  Serial.println(F("Unable to set LTC2947 to IDLE mode!"));
615  }
616 
617  LTC2947_SetPageSelect(false); //! make sure we are on page 0
618 
619  tbctl = //! generate TBCTL configuration value
622 
623  LTC2947_WR_BYTE(LTC2947_REG_TBCTL, tbctl); //! write PRE and DIV setting
624 
625  LTC2947_RD_BYTE(LTC2947_REG_TBCTL, data); //! read back configuration
626 
627  if (tbctl == data[0]) //! check if everything was written correctly
628  Serial.println(F("Successfully configured LTC2947's TBCTL"));
629  else
630  Serial.println(F("Failed to configured LTC2947's TBCTL"));
631 }
632 
633 //! parse status and alert registers. register_num (0..7) selects one of the 8 status/alert registers
634 //! statusRegs is a 8-byte array that holds the content of the status/alert registers read from the device
635 void parse_status_alert_regs(uint8_t statusRegs[8], uint8_t register_num)
636 {
637  switch (register_num)
638  {
639  case 0:
640  Serial.println(F("STATUS:"));
641  Serial.print(F(" UPDATE: "));
642  Serial.println(bitMaskSetChk(statusRegs[0], LTC2947_BM_STATUS_UPDATE/* */) ? 1 : 0);
643  Serial.print(F(" ADCERR: "));
644  Serial.println(bitMaskSetChk(statusRegs[0], LTC2947_BM_STATUS_ADCERR/* */) ? 1 : 0);
645  Serial.print(F(" TBERR: "));
646  Serial.println(bitMaskSetChk(statusRegs[0], LTC2947_BM_STATUS_TBERR/* */) ? 1 : 0);
647  Serial.print(F(" PORA: "));
648  Serial.println(bitMaskSetChk(statusRegs[0], LTC2947_BM_STATUS_PORA/* */) ? 1 : 0);
649  Serial.print(F(" UVLOA: "));
650  Serial.println(bitMaskSetChk(statusRegs[0], LTC2947_BM_STATUS_UVLOA/* */) ? 1 : 0);
651  Serial.print(F(" UVLOD: "));
652  Serial.println(bitMaskSetChk(statusRegs[0], LTC2947_BM_STATUS_UVLOD/* */) ? 1 : 0);
653  Serial.print(F(" UVLOSTBY:"));
654  Serial.println(bitMaskSetChk(statusRegs[0], LTC2947_BM_STATUS_UVLOSTBY/**/) ? 1 : 0);
655  break;
656  case 1:
657  Serial.println(F("STATVT:"));
658  Serial.print(F(" FANH: "));
659  Serial.println(bitMaskSetChk(statusRegs[1], LTC2947_BM_STATVT_FANH/* */) ? 1 : 0);
660  Serial.print(F(" FANL: "));
661  Serial.println(bitMaskSetChk(statusRegs[1], LTC2947_BM_STATVT_FANL/* */) ? 1 : 0);
662  Serial.print(F(" TEMPH: "));
663  Serial.println(bitMaskSetChk(statusRegs[1], LTC2947_BM_STATVT_TEMPH/* */) ? 1 : 0);
664  Serial.print(F(" TEMPL: "));
665  Serial.println(bitMaskSetChk(statusRegs[1], LTC2947_BM_STATVT_TEMPL/* */) ? 1 : 0);
666  Serial.print(F(" VH: "));
667  Serial.println(bitMaskSetChk(statusRegs[1], LTC2947_BM_STATVT_VH/* */) ? 1 : 0);
668  Serial.print(F(" VL: "));
669  Serial.println(bitMaskSetChk(statusRegs[1], LTC2947_BM_STATVT_VL/* */) ? 1 : 0);
670  break;
671  case 2:
672  Serial.println(F("STATIP:"));
673  Serial.print(F(" IH: "));
674  Serial.println(bitMaskSetChk(statusRegs[2], LTC2947_BM_STATIP_IH) ? 1 : 0);
675  Serial.print(F(" IL: "));
676  Serial.println(bitMaskSetChk(statusRegs[2], LTC2947_BM_STATIP_IL) ? 1 : 0);
677  Serial.print(F(" PH: "));
678  Serial.println(bitMaskSetChk(statusRegs[2], LTC2947_BM_STATIP_PH) ? 1 : 0);
679  Serial.print(F(" PL: "));
680  Serial.println(bitMaskSetChk(statusRegs[2], LTC2947_BM_STATIP_PL) ? 1 : 0);
681  break;
682  case 3:
683  Serial.println(F("STATC:"));
684  Serial.print(F(" C1H "));
685  Serial.println(bitMaskSetChk(statusRegs[3], LTC2947_BM_STATC_C1H) ? 1 : 0);
686  Serial.print(F(" C1L "));
687  Serial.println(bitMaskSetChk(statusRegs[3], LTC2947_BM_STATC_C1L) ? 1 : 0);
688  Serial.print(F(" C2H "));
689  Serial.println(bitMaskSetChk(statusRegs[3], LTC2947_BM_STATC_C2H) ? 1 : 0);
690  Serial.print(F(" C2L "));
691  Serial.println(bitMaskSetChk(statusRegs[3], LTC2947_BM_STATC_C2L) ? 1 : 0);
692  break;
693  case 4:
694  Serial.println(F("STATE:"));
695  Serial.print(F(" E1H "));
696  Serial.println(bitMaskSetChk(statusRegs[4], LTC2947_BM_STATE_E1H) ? 1 : 0);
697  Serial.print(F(" E1L "));
698  Serial.println(bitMaskSetChk(statusRegs[4], LTC2947_BM_STATE_E1L) ? 1 : 0);
699  Serial.print(F(" E2H "));
700  Serial.println(bitMaskSetChk(statusRegs[4], LTC2947_BM_STATE_E2H) ? 1 : 0);
701  Serial.print(F(" E2L "));
702  Serial.println(bitMaskSetChk(statusRegs[4], LTC2947_BM_STATE_E2L) ? 1 : 0);
703  break;
704  case 5:
705  Serial.println(F("STATCEOF:"));
706  Serial.print(F(" C1OF "));
707  Serial.println(bitMaskSetChk(statusRegs[5], LTC2947_BM_STATCEOF_C1OF) ? 1 : 0);
708  Serial.print(F(" C2OF "));
709  Serial.println(bitMaskSetChk(statusRegs[5], LTC2947_BM_STATCEOF_C2OF) ? 1 : 0);
710  Serial.print(F(" E1OF "));
711  Serial.println(bitMaskSetChk(statusRegs[5], LTC2947_BM_STATCEOF_E1OF) ? 1 : 0);
712  Serial.print(F(" E2OF "));
713  Serial.println(bitMaskSetChk(statusRegs[5], LTC2947_BM_STATCEOF_E2OF) ? 1 : 0);
714  break;
715  case 6:
716  Serial.println(F("STATTB:"));
717  Serial.print(F(" TB1OF "));
718  Serial.println(bitMaskSetChk(statusRegs[6], LTC2947_BM_STATTB_TB1OF) ? 1 : 0);
719  Serial.print(F(" TB2OF "));
720  Serial.println(bitMaskSetChk(statusRegs[6], LTC2947_BM_STATTB_TB2OF) ? 1 : 0);
721  Serial.print(F(" TB1TH "));
722  Serial.println(bitMaskSetChk(statusRegs[6], LTC2947_BM_STATTB_TB1TH) ? 1 : 0);
723  Serial.print(F(" TB2TH "));
724  Serial.println(bitMaskSetChk(statusRegs[6], LTC2947_BM_STATTB_TB2TH) ? 1 : 0);
725  break;
726  case 7:
727  Serial.println(F("STATVDVCC:"));
728  Serial.print(F(" VDVCCH "));
729  Serial.println(bitMaskSetChk(statusRegs[7], LTC2947_BM_STATVDVCC_VDVCCH) ? 1 : 0);
730  Serial.print(F(" VDVCCL "));
731  Serial.println(bitMaskSetChk(statusRegs[7], LTC2947_BM_STATVDVCC_VDVCCL) ? 1 : 0);
732  break;
733  default:
734  Serial.print(register_num);
735  Serial.println(F(" is not available!"));
736  break;
737  }
738 }
739 
740 //! Setup LTC2947's serial interface mode
742 {
743  do
744  {
745  Serial.println(F("\n\nSelect serial mode for LTC2947"));
746  Serial.println(F(" 1. I2C (DEFAULT)"));
747  Serial.println(F(" 2. SPI"));
748  Serial.print(F("Enter: "));
749  while (Serial.available())
750  ;
751  int32_t i = read_int();
752  Serial.println(i); //! echo selection
753  if (i == 0)
754  {
755  Serial.println(F("Will use DEFAULT (I2C)"));
756  i = 1;
757  }
758  if (i == 1)
759  {
760  do
761  {
762  Serial.println(F("\n\nEnter 7-bit I2C slave address for LTC2947 (DEFAULT:0x5C)"));
763  while (Serial.available())
764  ;
765  uint8_t slv = read_int();
766  if (slv == 0)
767  {
768  Serial.println(F("Will use DEFAULT (0x5C)"));
769  slv = 0x5C;
770  }
771  Serial.print(F("Slave address: 0x"));
772  Serial.println(slv, HEX);
773  switch (slv)
774  {
775  case LTC2947_I2C_ADDR_LL:
776  case LTC2947_I2C_ADDR_LH:
777  case LTC2947_I2C_ADDR_LR:
778  case LTC2947_I2C_ADDR_RL:
779  case LTC2947_I2C_ADDR_RH:
780  case LTC2947_I2C_ADDR_RR:
781  LTC2947_InitI2C(slv); //! set LTC2947 library to I2C mode
782  quikeval_I2C_init(); //! Configure I2C port for 100kHz
783  quikeval_I2C_connect(); //! Connect I2C to main data port
784  return;
785  default:
786  Serial.println(F("Unsupported slave address, please try again!"));
787  break;
788  }
789 
790  }
791  while (true);
792  }
793  else if (i == 2)
794  {
795  LTC2947_InitSPI(); //! set LTC2947 library to SPI mode
796  spi_enable(SPI_CLOCK_DIV16); //! Configure the spi port for 1MHz SCK (16MHz / 16)
797  quikeval_SPI_connect(); //! Connect SPI to main data port
798  return;
799  }
800  else
801  {
802  Serial.println(F("Please enter 1 or 2!"));
803  }
804  }
805  while (true);
806 }
static void mm7_gpio_ctrl()
LTC2947&#39;s GPIO control menu.
Definition: DC2334A.ino:494
#define LTC2947_BM_TBCTL_PRE_0
Definition: LTC2947.h:1245
#define LTC2947_LSB_VMAX
Definition: LTC2947.h:936
byte statusRegs[8]
array to store all status / alert registers
#define LTC2947_I2C_ADDR_LL
Definition: LTC2947.h:102
#define LTC2947_LSB_IMIN
Definition: LTC2947.h:930
static void print_min_max(float min, float max, uint8_t digits, byte *minBytes, byte *maxBytes)
prints two (min/max) values with label including the 16 bit raw values
Definition: DC2334A.ino:576
#define LTC2947_ARA_ERROR
general I2C communication error
Definition: LTC2947.h:1508
#define LTC2947_BM_STATC_C1L
Definition: LTC2947.h:1094
#define LTC2947_OFFS_TEMPMAX
Definition: LTC2947.h:942
#define LTC2947_BM_STATUS_ADCERR
Definition: LTC2947.h:1062
#define LTC2947_BM_STATTB_TB1TH
Definition: LTC2947.h:1122
#define LTC2947_LSB_TB1
Definition: LTC2947.h:920
#define LTC2947_PRE
Definition: LTC2947.h:900
#define LTC2947_BM_STATIP_PL
Definition: LTC2947.h:1088
#define LTC2947_BM_TBCTL_DIV_0
Definition: LTC2947.h:1251
void LTC2947_Read_I_P_V_TEMP_VCC(float *I, float *P, float *V, float *TEMP, float *VCC)
Reads current (I), power (P), voltage (V), temperature (TEMP) and supply voltage (VCC) from the devic...
Definition: LTC2947.cpp:603
#define LTC2947_BM_STATC_C2L
Definition: LTC2947.h:1098
#define LTC2947_BM_STATIP_IL
Definition: LTC2947.h:1084
#define LTC2947_BM_STATTB_TB2TH
Definition: LTC2947.h:1124
static int8_t LTC2947_RD_BYTES(uint8_t REG_ADDR, uint8_t LENGTH, uint8_t *BYTES)
read multiple bytes via I2C/SPI
Definition: LTC2947.h:1588
uint8_t LTC2947_Ara(uint8_t *svlAddr)
Sends the Alert Response address to the I2C bus and reads the response If two or more devices on the ...
Definition: LTC2947.cpp:533
void LTC2947_InitSPI()
Initializes the LTC2947 library for SPI mode operation.
Definition: LTC2947.cpp:91
static void print_title()
Print the title block.
Definition: DC2334A.ino:169
#define LTC2947_BM_STATVT_VH
Definition: LTC2947.h:1068
#define LTC2947_REG_STATUS
Definition: LTC2947.h:171
void LTC2947_Read_C_E_TB(boolean accuSet1, double *C, double *E, double *TB)
Reads charge (C), energy (E) and time (TB) from the device.
Definition: LTC2947.cpp:649
#define LTC2947_BM_STATVDVCC_VDVCCH
Definition: LTC2947.h:1132
#define LTC2947_BM_STATC_C2H
Definition: LTC2947.h:1096
#define LTC2947_BM_STATC_C1H
Definition: LTC2947.h:1092
#define LTC2947_BM_STATIP_IH
Definition: LTC2947.h:1082
Header File for Linduino Libraries and Demo Code.
#define BM2BITPOS(bm)
Definition: LTC2947.h:93
#define LTC2947_ARA_OTHER_RESPONSE
got ARA response from some other I2C slave
Definition: LTC2947.h:1512
#define LTC2947_BM_STATE_E2H
Definition: LTC2947.h:1106
#define LTC2947_LSB_IMAX
Definition: LTC2947.h:928
static void loop()
Repeats Linduino loop.
Definition: DC2334A.ino:122
static void mm3_measurements()
Read measurement results.
Definition: DC2334A.ino:291
void spi_enable(uint8_t spi_clock_divider)
Setup the processor for hardware SPI communication.
Definition: LT_SPI.cpp:160
#define LTC2947_BM_STATUS_TBERR
Definition: LTC2947.h:1064
#define LTC2947_BM_STATVT_FANH
Definition: LTC2947.h:1076
static uint8_t demo_board_connected
Global variables.
Definition: DC2334A.ino:93
#define LTC2947_BM_STATVT_TEMPH
Definition: LTC2947.h:1072
void LTC2947_SetPageSelect(boolean page)
write LTC2947&#39;s page control register to selected one of two memory pages
Definition: LTC2947.cpp:598
#define LTC2947_BM_STATE_E1L
Definition: LTC2947.h:1104
#define LTC2947_VAL_C2
Definition: LTC2947.h:753
#define LTC2947_ARA_NO_RESPONSE
got NO ARA response
Definition: LTC2947.h:1514
#define LTC2947_BM_STATUS_UVLOA
Definition: LTC2947.h:1052
#define LTC2947_LSB_VMIN
Definition: LTC2947.h:938
#define min(a, b)
static void mm1_operation_control()
LTC2947&#39;s operation control menu.
Definition: DC2334A.ino:203
void LTC2947_SerialPrint8hex(uint8_t val)
Prints a 8-bit value in 2-character hexadecimal format with left padded zeros.
Definition: LTC2947.cpp:152
#define LTC2947_VAL_IMAX
Definition: LTC2947.h:762
#define LTC2947_I2C_ADDR_RR
Definition: LTC2947.h:107
union LT_union_int32_4bytes data
Definition: DC2094A.ino:138
static void setup_ser_mode()
Setup LTC2947&#39;s serial interface mode.
Definition: DC2334A.ino:741
#define LTC2947_LSB_PMIN
Definition: LTC2947.h:934
#define LTC2947_LSB_C1
Definition: LTC2947.h:916
#define LTC2947_I2C_ADDR_RL
Definition: LTC2947.h:105
#define LTC2947_BM_STATCEOF_E1OF
Definition: LTC2947.h:1116
#define LTC2947_BM_STATUS_PORA
Definition: LTC2947.h:1054
#define LTC2947_BM_OPCTL_SHDN
Definition: LTC2947.h:1264
#define LTC2947_BM_STATUS_UVLOD
Definition: LTC2947.h:1058
#define LTC2947_LSB_TEMPMAX
Definition: LTC2947.h:940
#define LTC2947_BM_STATTB_TB1OF
Definition: LTC2947.h:1126
#define LTC2947_BM_STATUS_UPDATE
Definition: LTC2947.h:1060
static void mm2_read_status_alert_registers()
Read and print all status / alert registers.
Definition: DC2334A.ino:281
boolean LTC2947_SPI_Mode_Enabled
controlled by LTC2947_InitI2C / LTC2947_InitSPI to switch between I2C / SPI mode
Definition: LTC2947.cpp:82
static void mm6_min_max()
Read tracking (min/max) measurement values.
Definition: DC2334A.ino:457
#define LTC2947_BM_OPCTL_SSHOT
Definition: LTC2947.h:1268
#define LTC2947_BM_STATCEOF_E2OF
Definition: LTC2947.h:1118
#define LTC2947_BM_OPCTL_RST
Definition: LTC2947.h:1273
int16_t LTC2947_2BytesToInt16(byte *bytes)
converts an array of 2 bytes to 16-bit signed integer
Definition: LTC2947.cpp:301
QuikEval EEPROM Library.
#define LTC2947_REG_TBCTL
Definition: LTC2947.h:240
boolean LTC2947_GPIO_Read()
reads the current GPIO pin state Make sure LTC2947&#39;s page 0 is selected before calling this function...
Definition: LTC2947.cpp:526
#define LTC2947_BM_STATCEOF_C1OF
Definition: LTC2947.h:1112
#define LTC2947_BM_OPCTL_CLR
Definition: LTC2947.h:1266
#define bitMaskSetChk(value, bitMask)
Definition: LTC2947.h:75
int8_t discover_demo_board(char *demo_name)
Read the ID string from the EEPROM and determine if the correct board is connected.
#define LTC2947_BM_STATE_E1H
Definition: LTC2947.h:1102
static void print_main_menu()
Print the main menu.
Definition: DC2334A.ino:183
void LTC2947_InitI2C(uint8_t slvAddr)
Initializes the LTC2947 library for I2C mode operation and configures the slave address see defines L...
Definition: LTC2947.cpp:85
static void setup()
Initialize Linduino.
Definition: DC2334A.ino:96
#define LTC2947_OFFS_TEMPMIN
Definition: LTC2947.h:946
LT_SPI: Routines to communicate with ATmega328P&#39;s hardware SPI port.
uint8_t LTC2947_I2C_Slave_Addr
set by LTC2947_InitI2C to set slave address for I2C operation
Definition: LTC2947.cpp:83
static void go_idle_cfg_tbctl()
put LTC2947 into idle mode and configure TBCTL
Definition: DC2334A.ino:596
#define LTC2947_BM_STATVT_VL
Definition: LTC2947.h:1070
#define LTC2947_VAL_C1
Definition: LTC2947.h:744
void LTC2947_GPIO_SetPinState(uint8_t val)
Sets the level of the output driver on the GPIO pin This has only an effect if the output driver is e...
Definition: LTC2947.cpp:518
LT_I2C: Routines to communicate with ATmega328P&#39;s hardware I2C port.
#define LTC2947_BM_STATCEOF_C2OF
Definition: LTC2947.h:1114
#define LTC2947_BM_STATE_E2L
Definition: LTC2947.h:1108
char demo_name[]
Demo Board Name stored in QuikEval EEPROM.
Definition: DC1880A.ino:97
void quikeval_SPI_connect()
Connect SPI pins to QuikEval connector through the Linduino MUX. This will disconnect I2C...
Definition: LT_SPI.cpp:138
#define LTC2947_REG_OPCTL
Definition: LTC2947.h:243
int32_t read_int()
static void mm4_accu_measurements()
Read accumulated measurement results.
Definition: DC2334A.ino:318
int16_t LTC2947_wake_up()
Wake up LTC2947 from shutdown mode and measure the wakeup time.
Definition: LTC2947.cpp:567
void LTC2947_SerialPrint16hex(uint16_t val)
Prints a 16-bit value in 4-character hexadecimal format with left padded zeros.
Definition: LTC2947.cpp:157
#define LTC2947_VAL_VMAX
Definition: LTC2947.h:774
static void parse_status_alert_regs(uint8_t statusRegs[8], uint8_t register_num)
parse status and alert registers.
Definition: DC2334A.ino:635
float read_float()
#define LTC2947_ARA_LTC2947_RESPONSE
got ARA response from LTC2947
Definition: LTC2947.h:1510
static void mm8_ara()
SMBus Alert Response Protocol.
Definition: DC2334A.ino:545
void LTC2947_GPIO_PinMode(uint8_t mode)
Enables/disables the output driver on the GPIO pin Make sure LTC2947&#39;s page 0 is selected before call...
Definition: LTC2947.cpp:510
#define LTC2947_LSB_TEMPMIN
Definition: LTC2947.h:944
#define LTC2947_LSB_E1
Definition: LTC2947.h:918
#define LTC2947_I2C_ADDR_LH
Definition: LTC2947.h:103
#define LTC2947_BM_STATVT_TEMPL
Definition: LTC2947.h:1074
#define LTC2947_I2C_ADDR_LR
Definition: LTC2947.h:104
void LTC2947_DoubleToBytes(double value, double lsb, uint8_t *bytes, uint8_t length)
Converts a floating point number that was scaled with a given LSB to an integer representation that w...
Definition: LTC2947.cpp:175
void quikeval_I2C_init(void)
Initializes Linduino I2C port.
Definition: LT_I2C.cpp:394
LTC2947: LTC2947 a high-precision power and energy monitor with an internal sense resistor supporting...
static int8_t LTC2947_WR_BYTES(uint8_t REG_ADDR, uint8_t LENGTH, uint8_t *BYTES)
write byte array via I2C/SPI interface
Definition: LTC2947.h:1601
const int16_t E
static int8_t LTC2947_WR_BYTE(uint8_t REG_ADDR, uint8_t VALUE)
write single byte via I2C
Definition: LTC2947.h:1626
#define LTC2947_BM_STATVDVCC_VDVCCL
Definition: LTC2947.h:1134
void quikeval_I2C_connect(void)
Switch MUX to connect I2C pins to QuikEval connector.
Definition: LT_I2C.cpp:401
static int i
Definition: DC2430A.ino:184
#define LTC2947_DIV
Definition: LTC2947.h:907
static float voltage
Definition: DC2289AA.ino:71
static uint16_t current
the current measurement from the LTC3335&#39;s counter test mode.
Definition: DC2343A.ino:114
static void mm5_accu_init()
Initialize accumulators with user defined values.
Definition: DC2334A.ino:347
#define LTC2947_BM_STATTB_TB2OF
Definition: LTC2947.h:1128
#define LTC2947_BM_OPCTL_CONT
Definition: LTC2947.h:1271
#define LTC2947_BM_STATIP_PH
Definition: LTC2947.h:1086
#define LTC2947_BM_STATVT_FANL
Definition: LTC2947.h:1078
#define LTC2947_BM_STATUS_UVLOSTBY
Definition: LTC2947.h:1056
#define LTC2947_ARA_RESPONSE_WO_WR
got ARA response from any slave but wihtout the expected WR bit
Definition: LTC2947.h:1516
#define LTC2947_I2C_ADDR_RH
Definition: LTC2947.h:106
static int8_t LTC2947_RD_BYTE(uint8_t REG_ADDR, uint8_t *RESULT)
read single byte via I2C/SPI
Definition: LTC2947.h:1614
static uint8_t values[4]
Definition: DC2218A.ino:117
#define LTC2947_LSB_PMAX
Definition: LTC2947.h:932