Linduino  1.3.0
Linear Technology Arduino-Compatible Demonstration Board
LTC2947.cpp
Go to the documentation of this file.
1 /*!
2 LTC2947: LTC2947 a high-precision power and energy monitor with an internal sense resistor supporting up to 30A
3 
4 @verbatim
5 
6 The LTC2947 is a high-precision power and energy
7 monitor with an internal sense resistor supporting up
8 to 30A. Three internal No Latency delta sigma ADCs ensure
9 accurate measurement of voltage and current, while high-
10 bandwidth analog multiplication of voltage and current
11 provides accurate power measurement in a wide range of
12 applications. Internal or external clocking options enable
13 precise charge and energy measurements.
14 An internal 300 micro ohms, temperature-compensated sense
15 resistor minimizes efficiency loss and external compo-
16 nents, simplifying energy measurement applications while
17 enabling high accuracy current measurement over the full
18 temperature range. For more details see following URLs:
19 
20 @endverbatim
21 
22 http://www.linear.com/product/LTC2947
23 
24 http://www.linear.com/product/LTC2947#demoboards
25 
26 
27 Copyright 2018(c) Analog Devices, Inc.
28 
29 All rights reserved.
30 
31 Redistribution and use in source and binary forms, with or without
32 modification, are permitted provided that the following conditions are met:
33  - Redistributions of source code must retain the above copyright
34  notice, this list of conditions and the following disclaimer.
35  - Redistributions in binary form must reproduce the above copyright
36  notice, this list of conditions and the following disclaimer in
37  the documentation and/or other materials provided with the
38  distribution.
39  - Neither the name of Analog Devices, Inc. nor the names of its
40  contributors may be used to endorse or promote products derived
41  from this software without specific prior written permission.
42  - The use of this software may or may not infringe the patent rights
43  of one or more patent holders. This license does not release you
44  from the requirement that you obtain separate licenses from these
45  patent holders to use this software.
46  - Use of the software either in source or binary form, must be run
47  on or directly connected to an Analog Devices Inc. component.
48 
49 THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
50 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
51 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
52 IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
53 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
54 LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
55 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
56 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
57 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
58 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59 */
60 
61 //! @ingroup Power_Monitors
62 //! @{
63 //! @defgroup LTC2947 LTC2947 a high-precision power and energy monitor with an internal sense resistor supporting up to 30A.
64 //! @}
65 
66 /*! @file
67  @ingroup LTC2947
68  Library for LTC2947: A high-precision power and energy monitor with an internal sense resistor supporting up to 30A.
69 */
70 
71 #include <Arduino.h>
72 #include <Linduino.h>
73 #include <LT_I2C.h>
74 #include <LT_SPI.h>
75 #include "LTC2947.h"
76 #include <SPI.h>
77 
78 #ifdef LTC2947_DEBUG
79 #include "UserInterface.h"
80 #endif
81 
82 boolean LTC2947_SPI_Mode_Enabled = false;
84 
85 void LTC2947_InitI2C(uint8_t slvAddr)
86 {
88  LTC2947_I2C_Slave_Addr = slvAddr;
89 }
90 
92 {
94 }
95 
96 boolean LTC2947_Abs(uint8_t *bytes, uint8_t length)
97 {
98  if (bitMaskClrChk(*bytes, 0x80))
99  return false;// value is already positive
100 
101  // two's complement is generated by inverting all bits and add 1
102 
103  length--;
104  bytes += length; // seek to LSB
105  uint16_t cHelp = (~(*bytes)) & 0xFF; // invert LSB
106  cHelp++; // add 1
107  *bytes = cHelp; // store back to buffer
108 
109  while (length != 0)
110  {
111  // seek next byte (towards MSB)
112  length--;
113  bytes--;
114  cHelp = cHelp >> 8; // restore carry from previous sum
115  cHelp += (~(*bytes)) & 0xFF; // add inverted byte
116  *bytes = cHelp; // store back
117  }
118  return true;// value inverted
119 }
120 
121 double LTC2947_BytesToDouble(uint8_t *bytes, uint8_t length, boolean sig, double lsb)
122 {
123  if (length == 0)
124  return 0.0;
125  else if (length == 1)
126  return sig ? (int8_t)(bytes[0])*lsb : bytes[0] * lsb;
127  else if (length == 2)
128  return sig ? LTC2947_2BytesToInt16(bytes)*lsb : LTC2947_2BytesToUInt16(bytes)*lsb;
129  else if (length == 3)
130  return sig ? LTC2947_3BytesToInt32(bytes)*lsb : LTC2947_3BytesToUInt32(bytes)*lsb;
131  else if (length == 4)
132  return sig ? LTC2947_4BytesToInt32(bytes)*lsb : LTC2947_4BytesToUInt32(bytes)*lsb;
133  else
134  return sig ? LTC2947_SignedBytesToDouble(bytes, length, lsb) : LTC2947_UnsignedBytesToDouble(bytes, length, lsb);
135 }
136 
137 double LTC2947_UnsignedBytesToDouble(uint8_t *unsignedBytes, uint8_t length, double lsb)
138 {
139  // NOTE: On Arduino double is 32-bit and NOT 64-bit, thus the returned value
140  // will not reflect the full precission of e.g. C1, C2... which are 48-bit values
141  double ret = (*unsignedBytes); // MSB!
142 
143  while (length > 1)
144  {
145  unsignedBytes++; // go to next byte
146  length--;
147  ret = ret * 256.0 + (*unsignedBytes);
148  }
149  return ret*lsb;
150 }
151 
152 void LTC2947_SerialPrint8hex(uint8_t val)
153 {
154  if (val < 0x10) Serial.print("0");
155  Serial.print(val, HEX);
156 }
157 void LTC2947_SerialPrint16hex(uint16_t val)
158 {
159  for (uint16_t i = 0x1000L; i >= 0x10L; i = i >> 4)
160  if (val < i) Serial.print("0");
161  Serial.print(val, HEX);
162 }
163 void LTC2947_SerialPrint32hex(uint32_t val)
164 {
165  for (uint32_t i = 0x10000000L; i >= 0x10L; i = i >> 4)
166  if (val < i) Serial.print("0");
167  Serial.print(val, HEX);
168 }
169 void LTC2947_SerialPrint64hex(uint64_t uint64Val)
170 {
171  LTC2947_SerialPrint32hex((uint32_t)(uint64Val >> 32));
172  LTC2947_SerialPrint32hex((uint32_t)(uint64Val));
173 }
174 
175 void LTC2947_DoubleToBytes(double value, double lsb, uint8_t *bytes, uint8_t length)
176 {
177  //! on Arduino Uno / Linduino the maximum is 8 bytes
178  if (length > sizeof(int64_t)) //! sizeof(int64_t) = 8
179  return;
180 
181  //! revert the scaling with LSB and convert to integer value
182  int64_t int64Val = int64_t(value / lsb);
183 
184 #ifdef LTC2947_DEBUG
185  Serial.print(F("int64Val=0x"));
186  LTC2947_SerialPrint64hex((uint64_t)(int64Val));
187  Serial.println();
188  Serial.println(F("bytes:"));
189 #endif
190 
191  //! convert the integer value to byte array
192  for (int8_t i = length - 1; i >= 0; i--)
193  {
194  bytes[i] = int64Val & 0xFF;
195  int64Val >>= 8;
196 #ifdef LTC2947_DEBUG
197  Serial.print(i);
198  Serial.print(F(":"));
199  LTC2947_SerialPrint8hex(bytes[i]);
200  if (i == 0)
201  Serial.print(F(" (MSB)"));
202  else if (i == length - 1)
203  Serial.print(F(" (LSB)"));
204  Serial.println();
205 #endif
206  }
207 }
208 
209 #ifdef LTC2947_DEBUG
210 //! conversion function test
211 void LTC2947_DoubleToBytes_Test()
212 {
213  Serial.print(F("LSB:"));
214  while (!Serial.available());
215  double lsb = read_float();
216  Serial.println(lsb, 8);
217 
218  Serial.print(F("LSBrshift:"));
219  while (!Serial.available());
220  int32_t shift = read_int();
221  Serial.println(shift);
222  while (shift-- > 0)
223  lsb = lsb * 0.5;
224 
225  Serial.println(lsb, 16);
226 
227  Serial.print(F("VAL:"));
228  while (!Serial.available());
229  double val = read_float();
230  Serial.println(val, 8);
231 
232  Serial.print(F("VALlshift:"));
233  while (!Serial.available());
234  shift = read_int();
235  Serial.println(shift);
236  while (shift-- > 0)
237  val = val * 2.0;
238 
239  Serial.println(val, 16);
240 
241  byte bytes[8];
242  LTC2947_DoubleToBytes(val, lsb, bytes, 8);
243 }
244 #endif
245 
246 
247 double LTC2947_SignedBytesToDouble(uint8_t *signedBytes, uint8_t length, double lsb)
248 {
249  // reserve memory for unsigned bytes
250  uint8_t *unsignedBytes = (uint8_t *)malloc(length);
251  // copy signed bytes to unsigned bytes
252  memcpy(unsignedBytes, signedBytes, length);
253  // calculate absolute value of the signed bytes and store sign
254  // this function will change the unsigned bytes, for this reason
255  // we copied the original unsigned bytes to a new array
256  boolean sign = LTC2947_Abs(unsignedBytes, length);
257  // convert the unsigned bytes to a double value
258  double absDouble = LTC2947_UnsignedBytesToDouble(unsignedBytes, length, lsb);
259  // free the allocated memory of the copied array
260  free(unsignedBytes);
261  // recover the previously stored sign to return a signed value
262  return sign ? -absDouble : absDouble;
263 }
264 
265 int32_t LTC2947_4BytesToInt32(byte *bytes)
266 {
267  int32_t ret;
268 
269  ret = *bytes;
270  bytes++;
271  ret = ret << 8;
272  ret |= *bytes;
273  bytes++;
274  ret = ret << 8;
275  ret |= *bytes;
276  bytes++;
277  ret = ret << 8;
278  ret |= *bytes;
279  return ret;
280 }
281 
282 int32_t LTC2947_3BytesToInt32(byte *bytes)
283 {
284  int32_t ret;
285  // sign extension
286  if (*bytes & 0x80)
287  ret = 0xFF00;
288  else
289  ret = 0;
290 
291  ret |= *bytes;
292  bytes++;
293  ret = ret << 8;
294  ret |= *bytes;
295  bytes++;
296  ret = ret << 8;
297  ret |= *bytes;
298  return ret;
299 }
300 
301 int16_t LTC2947_2BytesToInt16(byte *bytes)
302 {
303  int16_t ret;
304  ret = *bytes;
305  bytes++;
306  ret = ret << 8;
307  ret |= *bytes;
308  return ret;
309 }
310 
311 uint32_t LTC2947_4BytesToUInt32(byte *bytes)
312 {
313  uint32_t ret;
314 
315  ret = *bytes;
316  bytes++;
317  ret = ret << 8;
318  ret |= *bytes;
319  bytes++;
320  ret = ret << 8;
321  ret |= *bytes;
322  bytes++;
323  ret = ret << 8;
324  ret |= *bytes;
325  return ret;
326 }
327 
328 uint32_t LTC2947_3BytesToUInt32(byte *bytes)
329 {
330  uint32_t ret;
331 
332  ret = *bytes;
333  bytes++;
334  ret = ret << 8;
335  ret |= *bytes;
336  bytes++;
337  ret = ret << 8;
338  ret |= *bytes;
339  return ret;
340 }
341 
342 uint16_t LTC2947_2BytesToUInt16(byte *bytes)
343 {
344  uint16_t ret;
345  ret = *bytes;
346  bytes++;
347  ret = ret << 8;
348  ret |= *bytes;
349  return ret;
350 }
351 
352 /*
353 * Note on I2C/SPI functions:
354 * i2c_write / i2c_read / spi_write / spi_read block methods from LT_I2C / LT_SPI write / read byte arrays from last to first element
355 * which is not compatible with LTC2947 library that expects the opposite order
356 */
357 
358 int8_t LTC2947_SpiWrBlock(uint8_t address, uint8_t length, uint8_t *values)
359 {
360  int8_t i;
361 
362  output_low(LTC2947_CS); //! 1) Pull CS low
363 
364  SPI.transfer(LTC2947_SPI_WRITE_CMD); // write
365  SPI.transfer(address); // reg addr
366 
367  for (i = 0; i < length; i++)
368  SPI.transfer(values[i]); //! 2) send byte array
369 
370  output_high(LTC2947_CS); //! 3) Pull CS high
371  return 0;
372 }
373 
374 int8_t LTC2947_SpiRdBlock(uint8_t address, uint8_t length, uint8_t *values)
375 {
376  int8_t i;
377 
378  output_low(LTC2947_CS); //! 1) Pull CS low
379 
380  SPI.transfer(LTC2947_SPI_READ_CMD); // read
381  SPI.transfer(address); // reg addr
382 
383  for (i = 0; i < length; i++)
384  values[i] = SPI.transfer(0x00);
385 
386  output_high(LTC2947_CS); //! 3) Pull CS high
387  return 0;
388 }
389 
390 int8_t LTC2947_SpiWrByte(uint8_t address, uint8_t value)
391 {
392  output_low(LTC2947_CS); //! 1) Pull CS low
393 
394  SPI.transfer(LTC2947_SPI_WRITE_CMD); // write
395  SPI.transfer(address); // reg addr
396  SPI.transfer(value); //! 2) send byte
397 
398  output_high(LTC2947_CS); //! 3) Pull CS high
399  return 0;
400 }
401 
402 int8_t LTC2947_SpiRdByte(uint8_t address, uint8_t *value)
403 {
404  output_low(LTC2947_CS); //! 1) Pull CS low
405 
406  SPI.transfer(LTC2947_SPI_READ_CMD); // read
407  SPI.transfer(address); // reg addr
408  value[0] = SPI.transfer(0x00); //! 2) read byte
409 
410  output_high(LTC2947_CS); //! 3) Pull CS high
411  return 0;
412 }
413 
414 int8_t LTC2947_I2CWrBlock(uint8_t slvAddr, uint8_t regAddr, uint8_t length, uint8_t *values)
415 {
416  int8_t ret = 0;
417 
418  if (i2c_start() != 0) //I2C START
419  return 1; //Stop and return 0 if START fail
420 
421  ret |= i2c_write((slvAddr << 1) | I2C_WRITE_BIT); // Write 7 bit address with W bit
422  ret |= i2c_write(regAddr); // Set register address
423 
424  while (length > 0)
425  {
426  ret |= i2c_write(*values); //Write Value
427  length--;
428  values++;
429  }
430 
431  i2c_stop(); // I2C STOP
432 
433  return ret != 0 ? 1 : 0;
434 }
435 
436 int8_t LTC2947_I2CRdBlock(uint8_t slvAddr, uint8_t regAddr, uint8_t length, uint8_t *values)
437 {
438  int8_t ret = 0;
439 
440  if (length == 0 || i2c_start() != 0) //I2C START
441  return 1; //Stop and return 0 if START fail
442 
443  ret |= i2c_write((slvAddr << 1) | I2C_WRITE_BIT); // Write 7 bit address with W bit
444  ret |= i2c_write(regAddr); // Set register address
445  ret |= i2c_repeated_start();
446  ret |= i2c_write((slvAddr << 1) | I2C_READ_BIT); // Write 7 bit address with R bit
447 
448  if (ret != 0) //If NACK return 1
449  {
450  i2c_stop(); //I2C STOP
451  return 1;
452  }
453 
454  length--;
455  while (length > 0)
456  {
457  *values = i2c_read(WITH_ACK); //Read from bus with ACK
458  values++;
459  length--;
460  }
461 
462  *values = i2c_read(WITH_NACK); //Read from bus with NACK for the last one;
463 
464  i2c_stop(); //I2C STOP
465 
466  return 0; // Success!
467 }
468 
469 int8_t LTC2947_I2CWrByte(uint8_t slvAddr, uint8_t regAddr, uint8_t value)
470 {
471  int8_t ret = 0;
472 
473  if (i2c_start() != 0) //I2C START
474  return 1; //Stop and return 0 if START fail
475 
476  ret |= i2c_write((slvAddr << 1) | I2C_WRITE_BIT); // Write 7 bit address with W bit
477  ret |= i2c_write(regAddr); // Set register address
478  ret |= i2c_write(value); //Write Value
479 
480  i2c_stop(); // I2C STOP
481 
482  return ret != 0 ? 1 : 0;
483 }
484 
485 int8_t LTC2947_I2CRdByte(uint8_t slvAddr, uint8_t regAddr, uint8_t *value)
486 {
487  int8_t ret = 0;
488 
489  if (i2c_start() != 0) //I2C START
490  return 1; //Stop and return 0 if START fail
491 
492  ret |= i2c_write((slvAddr << 1) | I2C_WRITE_BIT); // Write 7 bit address with W bit
493  ret |= i2c_write(regAddr); // Set register address
494  ret |= i2c_repeated_start();
495  ret |= i2c_write((slvAddr << 1) | I2C_READ_BIT); // Write 7 bit address with R bit
496 
497  if (ret != 0) //If NACK return 1
498  {
499  i2c_stop(); //I2C STOP
500  return 1;
501  }
502 
503  *value = i2c_read(WITH_NACK); //Read from bus with NACK for the last one;
504 
505  i2c_stop(); //I2C STOP
506 
507  return 0; // Success!
508 }
509 
510 void LTC2947_GPIO_PinMode(uint8_t mode)
511 {
512  uint8_t gpiostatcl;
514  bitMaskSetClr(gpiostatcl, LTC2947_BM_GPIOSTATCL_GPOEN, mode != INPUT);
516 }
517 
518 void LTC2947_GPIO_SetPinState(uint8_t val)
519 {
520  uint8_t gpiostatcl;
522  bitMaskSetClr(gpiostatcl, LTC2947_BM_GPIOSTATCL_GPO, val != LOW);
524 }
525 
527 {
528  uint8_t gpiostatcl;
530  return bitMaskSetChk(gpiostatcl, LTC2947_BM_GPIOSTATCL_GPI);
531 }
532 
533 uint8_t LTC2947_Ara(uint8_t *svlAddr)
534 {
535  *svlAddr = 0;
536  //! Send I2C start bit
537  if (i2c_start() != 0)
538  return LTC2947_ARA_ERROR;
539 
540  //! send the ALERT RESPONSE ADDRESS with read bit
542  {
543  //! NACK means no device response!
545  }
546 
547  //! Read device address from the responding device
548  *svlAddr = i2c_read(WITH_NACK); //! read with NACK
549  i2c_stop(); //! I2C STOP
550  //! check for the expected write bit of the response
551  boolean response_wr_bit = bitMaskClrChk(*svlAddr, 0x1);
552  //! right shift to get 7-bit slave address
553  *svlAddr = ((*svlAddr) >> 1) & 0x7F;
554  if (response_wr_bit)
555  {
556  //! got expected write bit, compare slave address
557  //! with LTC2947's address
558  return ((*svlAddr) == LTC2947_I2C_Slave_Addr)
561  }
562 
563  //! missing write bit within response!
565 }
566 
568 {
569  byte data[1];
570  unsigned long wakeupStart = millis(), wakeupTime;
571  LTC2947_WR_BYTE(LTC2947_REG_OPCTL, 0);//! any serial transaction will wakeup LTC2947
572  do
573  {
574  delay(1);
575  LTC2947_RD_BYTE(LTC2947_REG_OPCTL, data); //! wake up polling by reading OPCTL
576  wakeupTime = millis() - wakeupStart;
577  if (data[0] == 0) //! check if we are in idle mode
578  {
579  //! wake up successful, return wakeup time in milliseconds
580  return wakeupTime;
581  }
582  if (wakeupTime > 200)
583  {
584  //! failed to wake up due to timeout, return -1
585  return -1;
586  }
587  }
588  while (true);
589 }
590 
592 {
593  uint8_t currentPageCtrl;
594  LTC2947_RD_BYTE(LTC2947_REG_PGCTL, &currentPageCtrl);
595  return bitMaskSetChk(currentPageCtrl, LTC2947_BM_PGCTL_PAGE);
596 }
597 
598 void LTC2947_SetPageSelect(boolean page)
599 {
600  LTC2947_WR_BYTE(LTC2947_REG_PGCTL, page ? LTC2947_BM_PGCTL_PAGE : 0); // switch page
601 }
602 
603 void LTC2947_Read_I_P_V_TEMP_VCC(float *I, float *P, float *V, float *TEMP, float *VCC)
604 {
605  // byte array to store register values
606  byte bytes[12];
607 
608  // read measurement results from device
609  LTC2947_RD_BYTES(LTC2947_VAL_I, 6, bytes); // I[23:0] P[23:0] starting at data[0]
610  LTC2947_RD_BYTES(LTC2947_VAL_V, 6, bytes + 6); // V[15:0] TEMP[15:0] VDVCC[15:0] starting at data[6]
611 
612  // convert to floating point values
613  // Note: definitions in LTC2947.h are given in mA, mW, mV
614  // so they have to be mutliplied by 1e-3 to get A, W, V respectively
615  *I = LTC2947_3BytesToInt32(bytes) * LTC2947_LSB_I * 1e-3; // calc current in amps
616  *P = LTC2947_3BytesToInt32(bytes + 3) * LTC2947_LSB_P * 1e-3; // calc power in watts
617  *V = LTC2947_2BytesToInt16(bytes + 6) * LTC2947_LSB_V * 1e-3; // calc voltage in volts
618  *TEMP = LTC2947_2BytesToInt16(bytes + 6 + 2) * LTC2947_LSB_TEMP + LTC2947_OFFS_TEMP; // calc temperature in degree celcius
619  *VCC = LTC2947_2BytesToInt16(bytes + 6 + 4) * LTC2947_LSB_VDVCC * 1e-3; // calc supply voltage in volts
620 }
621 
622 void LTC2947_Read_Abs_C_E_TB(boolean accuSet1, double *C, boolean *signC, double *E, boolean *signE, double *TB)
623 {
624  // byte array to store register values
625  byte bytes[16];
626 
627  // read measurement results from device
628  if (accuSet1)
629  // read accumulated quantities set 1: C1[47:0] E1[47:0] TB1[31:0]
630  LTC2947_RD_BYTES(LTC2947_VAL_C1, 16, bytes);
631  else
632  // read accumulated quantities set 2: C2[47:0] E2[47:0] TB2[31:0]
633  LTC2947_RD_BYTES(LTC2947_VAL_C2, 16, bytes);
634 
635  // calculate absolute value of Cx and store sign
636  *signC = LTC2947_Abs(bytes, 6);
637  // convert unsigned bytes to double value in As
639 
640  // calculate absolute value of Ex and store sign
641  *signE = LTC2947_Abs(bytes + 6, 6);
642  // convert unsigned bytes to double value in Ws
643  *E = LTC2947_UnsignedBytesToDouble(bytes + 6, 6, LTC2947_LSB_E1);
644 
645  // calc time in seconds
646  *TB = LTC2947_4BytesToUInt32(bytes + 12) * LTC2947_LSB_TB1;
647 }
648 
649 void LTC2947_Read_C_E_TB(boolean accuSet1, double *C, double *E, double *TB)
650 {
651  // byte array to store register values
652  byte bytes[16];
653 
654  // read measurement results from device
655  if (accuSet1)
656  // read accumulated quantities set 1: C1[47:0] E1[47:0] TB1[31:0]
657  LTC2947_RD_BYTES(LTC2947_VAL_C1, 16, bytes);
658  else
659  // read accumulated quantities set 2: C2[47:0] E2[47:0] TB2[31:0]
660  LTC2947_RD_BYTES(LTC2947_VAL_C2, 16, bytes);
661 
662  // convert signed bytes to double value in As
664 
665  // convert signed bytes to double value in Ws
666  *E = LTC2947_SignedBytesToDouble(bytes + 6, 6, LTC2947_LSB_E1);
667 
668  // calc time in seconds
669  *TB = LTC2947_4BytesToUInt32(bytes + 6 + 6) * LTC2947_LSB_TB1;
670 }
#define bitMaskSetClr(value, bitMask, setNotClr)
Definition: LTC2947.h:81
#define I2C_WRITE_BIT
Definition: LT_I2C.h:64
#define LTC2947_I2C_ADDR_LL
Definition: LTC2947.h:102
#define LTC2947_ARA_ERROR
general I2C communication error
Definition: LTC2947.h:1508
long ret
int8_t LTC2947_I2CWrBlock(uint8_t slvAddr, uint8_t regAddr, uint8_t length, uint8_t *values)
write byte array via I2C interface
Definition: LTC2947.cpp:414
int8_t LTC2947_I2CWrByte(uint8_t slvAddr, uint8_t regAddr, uint8_t value)
write single byte via I2C
Definition: LTC2947.cpp:469
#define LTC2947_LSB_TB1
Definition: LTC2947.h:920
#define LTC2947_SPI_READ_CMD
Definition: LTC2947.h:110
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
uint32_t LTC2947_4BytesToUInt32(byte *bytes)
Converts an array of 4 bytes to 32-bit unsigned integer.
Definition: LTC2947.cpp:311
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
boolean LTC2947_Abs(uint8_t *bytes, uint8_t length)
Calculates the absolute value of a signed value with arbitrary number of bytes.
Definition: LTC2947.cpp:96
#define output_high(pin)
Set "pin" high.
Definition: Linduino.h:75
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_PGCTL_PAGE
Definition: LTC2947.h:1279
#define LTC2947_BM_GPIOSTATCL_GPI
Definition: LTC2947.h:1036
int32_t LTC2947_3BytesToInt32(byte *bytes)
converts an array of 3 bytes to 32-bit signed integer
Definition: LTC2947.cpp:282
void LTC2947_Read_Abs_C_E_TB(boolean accuSet1, double *C, boolean *signC, double *E, boolean *signE, double *TB)
Reads charge (C), energy (E) and time (TB) from the device.
Definition: LTC2947.cpp:622
#define LTC2947_CS
Definition: LTC2947.h:117
Header File for Linduino Libraries and Demo Code.
#define LTC2947_BM_GPIOSTATCL_GPO
Definition: LTC2947.h:1040
#define LTC2947_ARA_OTHER_RESPONSE
got ARA response from some other I2C slave
Definition: LTC2947.h:1512
#define LTC2947_VAL_I
Definition: LTC2947.h:792
void i2c_stop()
Write stop bit to the hardware I2C port.
Definition: LT_I2C.cpp:462
int8_t LTC2947_I2CRdBlock(uint8_t slvAddr, uint8_t regAddr, uint8_t length, uint8_t *values)
read multiple bytes via I2C
Definition: LTC2947.cpp:436
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_VAL_C2
Definition: LTC2947.h:753
#define LTC2947_ARA_NO_RESPONSE
got NO ARA response
Definition: LTC2947.h:1514
uint16_t LTC2947_2BytesToUInt16(byte *bytes)
Converts an array of 2 bytes to 16-bit unsigned integer.
Definition: LTC2947.cpp:342
void LTC2947_SerialPrint8hex(uint8_t val)
Prints a 8-bit value in 2-character hexadecimal format with left padded zeros.
Definition: LTC2947.cpp:152
int8_t i2c_start()
Write start bit to the hardware I2C port.
Definition: LT_I2C.cpp:425
double LTC2947_SignedBytesToDouble(uint8_t *signedBytes, uint8_t length, double lsb)
Converts a signed value of arbitrary number of bytes to a floating point value with the scaling facto...
Definition: LTC2947.cpp:247
#define LTC2947_VAL_V
Definition: LTC2947.h:798
static uint8_t address
Definition: DC2091A.ino:83
union LT_union_int32_4bytes data
Definition: DC2094A.ino:138
#define WITH_NACK
Use with i2c_read(WITH_NACK) to read without an acknowledge.
Definition: LT_I2C.h:91
#define LTC2947_LSB_C1
Definition: LTC2947.h:916
void LTC2947_SerialPrint32hex(uint32_t val)
Prints a 32-bit value in 8-character hexadecimal format with left padded zeros.
Definition: LTC2947.cpp:163
boolean LTC2947_SPI_Mode_Enabled
controlled by LTC2947_InitI2C / LTC2947_InitSPI to switch between I2C / SPI mode
Definition: LTC2947.cpp:82
int8_t i2c_write(uint8_t data)
Send a data byte to hardware I2C port.
Definition: LT_I2C.cpp:470
#define output_low(pin)
Set "pin" low.
Definition: Linduino.h:72
int16_t LTC2947_2BytesToInt16(byte *bytes)
converts an array of 2 bytes to 16-bit signed integer
Definition: LTC2947.cpp:301
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_LSB_TEMP
Definition: LTC2947.h:958
#define bitMaskSetChk(value, bitMask)
Definition: LTC2947.h:75
#define I2C_READ_BIT
Definition: LT_I2C.h:63
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
#define LTC2947_OFFS_TEMP
Definition: LTC2947.h:960
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
#define LTC2947_ALERT_RESP_ADDR
The general alert response address.
Definition: LTC2947.h:1518
#define LTC2947_VAL_C1
Definition: LTC2947.h:744
#define LTC2947_LSB_VDVCC
Definition: LTC2947.h:962
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
#define LTC2947_REG_PGCTL
Definition: LTC2947.h:246
#define LTC2947_LSB_V
Definition: LTC2947.h:956
LT_I2C: Routines to communicate with ATmega328P&#39;s hardware I2C port.
int8_t LTC2947_SpiRdBlock(uint8_t address, uint8_t length, uint8_t *values)
read array of bytes from the SPI interface
Definition: LTC2947.cpp:374
#define bitMaskClrChk(value, bitMask)
Definition: LTC2947.h:76
int8_t i2c_repeated_start()
Write a repeat start bit to the hardware I2C port.
Definition: LT_I2C.cpp:444
#define LTC2947_REG_OPCTL
Definition: LTC2947.h:243
int32_t read_int()
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
int32_t LTC2947_4BytesToInt32(byte *bytes)
Converts an array of 4 bytes to 32-bit signed integer.
Definition: LTC2947.cpp:265
void LTC2947_SerialPrint64hex(uint64_t uint64Val)
Prints a 64-bit value in 16-character hexadecimal format with left padded zeros.
Definition: LTC2947.cpp:169
#define LTC2947_LSB_I
Definition: LTC2947.h:952
float read_float()
#define LTC2947_ARA_LTC2947_RESPONSE
got ARA response from LTC2947
Definition: LTC2947.h:1510
#define LTC2947_LSB_P
Definition: LTC2947.h:954
#define LTC2947_SPI_WRITE_CMD
Definition: LTC2947.h:111
int8_t LTC2947_I2CRdByte(uint8_t slvAddr, uint8_t regAddr, uint8_t *value)
read single byte via I2C
Definition: LTC2947.cpp:485
uint8_t i2c_read(int8_t ack)
Read a data byte from the hardware I2C port.
Definition: LT_I2C.cpp:491
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_E1
Definition: LTC2947.h:918
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
uint32_t LTC2947_3BytesToUInt32(byte *bytes)
converts an array of 3 bytes to 32-bit unsigned integer
Definition: LTC2947.cpp:328
LTC2947: LTC2947 a high-precision power and energy monitor with an internal sense resistor supporting...
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
static int i
Definition: DC2430A.ino:184
int8_t LTC2947_SpiWrByte(uint8_t address, uint8_t value)
write single byte to SPI interface
Definition: LTC2947.cpp:390
#define WITH_ACK
Use with i2c_read(WITH_ACK) to read with an acknowledge.
Definition: LT_I2C.h:90
boolean LTC2947_GetCurrentPageSelect()
reads LTC2947&#39;s page control register to determine the currently selected memory page ...
Definition: LTC2947.cpp:591
double LTC2947_BytesToDouble(uint8_t *bytes, uint8_t length, boolean sig, double lsb)
Converts a signed or unsigned value of arbitrary number of bytes to a floating point number...
Definition: LTC2947.cpp:121
double LTC2947_UnsignedBytesToDouble(uint8_t *unsignedBytes, uint8_t length, double lsb)
Converts an unsigned value of arbitrary number of bytes to a floating point value with the scaling fa...
Definition: LTC2947.cpp:137
#define LTC2947_REG_GPIOSTATCL
Definition: LTC2947.h:168
#define LTC2947_BM_GPIOSTATCL_GPOEN
Definition: LTC2947.h:1032
#define LTC2947_ARA_RESPONSE_WO_WR
got ARA response from any slave but wihtout the expected WR bit
Definition: LTC2947.h:1516
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
int8_t LTC2947_SpiWrBlock(uint8_t address, uint8_t length, uint8_t *values)
writes block (array) of bytes to the SPI interface
Definition: LTC2947.cpp:358
int8_t LTC2947_SpiRdByte(uint8_t address, uint8_t *value)
read single byte from SPI interface
Definition: LTC2947.cpp:402