Linduino  1.3.0
Linear Technology Arduino-Compatible Demonstration Board
device_logger.ino
Go to the documentation of this file.
1 /*!
2 Linear Technology DC1962C Demonstration Board
3 LTC3880, LTC2974, LTC2977: Power Management Solution for Application Processors
4 
5 This sketch has only been tested on a Mega 2560. It is known to fail
6 on Aarduino Uno and Linduino due to size of RAM.
7 
8 @verbatim
9 
10 NOTES
11  Setup:
12  Set the terminal baud rate to 115200 and select the newline terminator.
13 
14 @endverbatim
15 
16 http://www.linear.com/product/LTC3880
17 
18 http://www.linear.com/product/LTC2974
19 
20 http://www.linear.com/product/LTC2977
21 
22 http://www.linear.com/demo/DC1962C
23 
24 
25 Copyright 2018(c) Analog Devices, Inc.
26 
27 All rights reserved.
28 
29 Redistribution and use in source and binary forms, with or without
30 modification, are permitted provided that the following conditions are met:
31  - Redistributions of source code must retain the above copyright
32  notice, this list of conditions and the following disclaimer.
33  - Redistributions in binary form must reproduce the above copyright
34  notice, this list of conditions and the following disclaimer in
35  the documentation and/or other materials provided with the
36  distribution.
37  - Neither the name of Analog Devices, Inc. nor the names of its
38  contributors may be used to endorse or promote products derived
39  from this software without specific prior written permission.
40  - The use of this software may or may not infringe the patent rights
41  of one or more patent holders. This license does not release you
42  from the requirement that you obtain separate licenses from these
43  patent holders to use this software.
44  - Use of the software either in source or binary form, must be run
45  on or directly connected to an Analog Devices Inc. component.
46 
47 THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
48 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
49 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
50 IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
51 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
52 LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
53 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
54 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
55 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
56 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
57 */
58 
59 /*! @file
60  @ingroup DC1962
61 */
62 
63 #include <Arduino.h>
64 #include <stdint.h>
65 
66 #include <LT_SMBusPec.h>
67 #include <LT_SMBusNoPec.h>
68 #include <LT_SMBusGroup.h>
69 #include <LT_PMBus.h>
70 #include <LT_PMBusMath.h>
71 #include <LT_PMBusDevice.h>
72 #include <LT_PMBusRail.h>
73 #include <LT_PMBusDetect.h>
74 #include <LT_PMBusDetect.h>
75 #include <LT_PMBusSpeedTest.h>
76 #include <LT_PMBusDeviceLTC3880.h>
77 #include <LT_FaultLog.h>
78 #include <LT_3880FaultLog.h> // For compilation of library
79 
80 static bool doprint = false;
81 
82 #define POLL_DELAY 200
83 
84 static LT_SMBusNoPec *smbusNoPec = new LT_SMBusNoPec(100000); // Start at slow speed
85 static LT_SMBusPec *smbusPec = new LT_SMBusPec(100000); // Start at slow speed
86 static LT_PMBus *pmbusNoPec = new LT_PMBus(smbusNoPec);
87 static LT_PMBus *pmbusPec = new LT_PMBus(smbusPec);
88 static LT_PMBusDetect *detector = new LT_PMBusDetect(pmbusNoPec);
91 static int index = 0;
92 static int channel = 0;
93 
94 //! Initialize Linduino
95 //! @return void
96 void setup()
97 {
98  uint32_t speed = 500000;
99 
100  Serial.begin(115200); //! Initialize the serial port to the PC
101 
102  if (doprint) Serial.println(F("Detecting Addresses..."));
103  detector->detect();
104  device = (devices = detector->getDevices());
105  while (*device != NULL)
106  {
107  if (doprint) Serial.print(F(" Type: "));
108  if (doprint) Serial.print((*device)->getType());
109  if (doprint) Serial.print(F(" Address: "));
110  if (doprint) Serial.print((*device)->getAddress(), HEX);
111 
112  if (doprint) Serial.print(F(", Speed: "));
113  if (doprint) Serial.print((*device)->getMaxSpeed(), DEC);
114  if (doprint) Serial.println();
115 
116  // Switch the device to Pec
117  pmbusNoPec->enablePec((*device)->getAddress());
118  (*device)->changePMBus(pmbusPec);
119 
120  // Speed test to find fastest speed the bus can operate at.
121  if (speed > (*device)->getMaxSpeed())
122  speed = (*device)->getMaxSpeed();
123 
124  device++;
125  }
126 
127  if (doprint) Serial.print("Changing bus speed to ");
128  if (doprint) Serial.println(speed, DEC);
129  // This will change the speed of the I2C bus and enable clock stretching if > 100kHz
130  // Only affects Pec becuase the device was switched to Pec.
131  device = devices;
132  while ((*device) != 0)
133  {
134  (*device)->setSpeed(speed);
135  device++;
136  }
137  // Change the NoPec version to keep out world consistent.
138  pmbusNoPec->smbus()->i2cbus()->changeSpeed(speed);
139 
140  Serial.println(F("Index,DeviceId,Channel,MfrSpecialId,Time,DeviceAddress,DevicePage,TelemetryCommand,TelemetryType,ValueLength,Value,FloatValue"));
141 
142 }
143 
144 void print_info(LT_PMBusDevice *device, int id)
145 {
146  unsigned long time;
147 
148  time = micros();
149 
150  Serial.print(index);
151  Serial.print(F(","));
152  Serial.print(id);
153  Serial.print(F(","));
154  Serial.print(channel++);
155  Serial.print(F(","));
156 
157  id = device->readMfrSpecialId();
158  Serial.print(F("0x"));
159  Serial.print(id, HEX);
160  Serial.print(F(","));
161 
162  Serial.print(time);
163  Serial.print(F(",0x"));
164  Serial.print(device->getAddress(), HEX);
165  Serial.print(F(",0x"));
166 
167 }
168 
169 //! Repeats Linduino loop
170 //! @return void
171 void loop()
172 {
173  float f;
174  uint16_t val16;
175  uint8_t val8;
176  uint8_t page;
177  int id = 0 ;
178 
179  if (index > 100)
180  return;
181 
182  // Telemetry
183  device = devices;
184  channel = 0;
185  while ((*device) != NULL)
186  {
187  if ((*device)->hasCapability(HAS_STATUS_WORD))
188  {
189  for (page = 0; page < (*device)->getNumPages(); page++)
190  {
191  (*device)->setPage(page);
192  val16 = (*device)->smbus()->readWord((*device)->getAddress(), STATUS_WORD);
193  print_info(*device, id);
194  Serial.print(page, HEX);
195  Serial.print(F(",0x"));
196  Serial.print(STATUS_WORD, HEX);
197  Serial.print(F(",STATUS_WORD,2,0x"));
198  Serial.print(val16, HEX);
199  Serial.print(F(","));
200  Serial.println(val16, DEC);
201  }
202  }
203 
204  if ((*device)->hasCapability(HAS_VIN))
205  {
206  val16 = (*device)->smbus()->readWord((*device)->getAddress(), READ_VIN);
207  print_info(*device, id);
208  Serial.print(0x00, HEX);
209  Serial.print(F(",0x"));
210  Serial.print(READ_VIN, HEX);
211  Serial.print(F(",READ_VIN,2,0x"));
212  Serial.print(val16, HEX);
213  Serial.print(F(","));
214  Serial.println(math_.lin11_to_float(val16), DEC);
215  }
216 
217  if ((*device)->hasCapability(HAS_VOUT))
218  {
219  for (page = 0; page < (*device)->getNumPages(); page++)
220  {
221  (*device)->setPage(page);
222  val16 = (*device)->smbus()->readWord((*device)->getAddress(), READ_VOUT);
223  val8 = (*device)->smbus()->readByte((*device)->getAddress(), VOUT_MODE);
224  print_info(*device, id);
225  Serial.print(page, HEX);
226  Serial.print(F(",0x"));
227  Serial.print(READ_VOUT, HEX);
228  Serial.print(F(",READ_VOUT,2,0x"));
229  Serial.print(val16, HEX);
230  Serial.print(F(","));
231  Serial.println(math_.lin16_to_float(val16, val8 & 0x1F), DEC);
232  }
233  }
234 
235  if ((*device)->hasCapability(HAS_IIN))
236  {
237  for (page = 0; page < (*device)->getNumPages(); page++)
238  {
239  (*device)->setPage(page);
240  val16 = (*device)->smbus()->readWord((*device)->getAddress(), READ_IIN);
241  print_info(*device, id);
242  Serial.print(page, HEX);
243  Serial.print(F(",0x"));
244  Serial.print(READ_IIN, HEX);
245  Serial.print(F(",READ_IIN,2,0x"));
246  Serial.print(val16, HEX);
247  Serial.print(F(","));
248  Serial.println(math_.lin11_to_float(val16), DEC);
249  }
250  }
251 
252  if ((*device)->hasCapability(HAS_IOUT))
253  {
254  for (page = 0; page < (*device)->getNumPages(); page++)
255  {
256  (*device)->setPage(page);
257  val16 = (*device)->smbus()->readWord((*device)->getAddress(), READ_IOUT);
258  print_info(*device, id);
259  Serial.print(page, HEX);
260  Serial.print(F(",0x"));
261  Serial.print(READ_IOUT, HEX);
262  Serial.print(F(",READ_IOUT,2,0x"));
263  Serial.print(val16, HEX);
264  Serial.print(F(","));
265  Serial.println(math_.lin11_to_float(val16), DEC);
266  }
267  }
268 
269  if ((*device)->hasCapability(HAS_PIN))
270  {
271  for (page = 0; page < (*device)->getNumPages(); page++)
272  {
273  (*device)->setPage(page);
274  val16 = (*device)->smbus()->readWord((*device)->getAddress(), READ_PIN);
275  print_info(*device, id);
276  Serial.print(page, HEX);
277  Serial.print(F(",0x"));
278  Serial.print(READ_PIN, HEX);
279  Serial.print(F(",READ_PIN,2,0x"));
280  Serial.print(val16, HEX);
281  Serial.print(F(","));
282  Serial.println(math_.lin11_to_float(val16), DEC);
283  }
284  }
285 
286  if ((*device)->hasCapability(HAS_POUT))
287  {
288  for (page = 0; page < (*device)->getNumPages(); page++)
289  {
290  (*device)->setPage(page);
291  val16 = (*device)->smbus()->readWord((*device)->getAddress(), READ_POUT);
292  print_info(*device, id);
293  Serial.print(page, HEX);
294  Serial.print(F(",0x"));
295  Serial.print(READ_POUT, HEX);
296  Serial.print(F(",READ_POUT,2,0x"));
297  Serial.print(val16, HEX);
298  Serial.print(F(","));
299  Serial.println(math_.lin11_to_float(val16), DEC);
300  }
301  }
302  /*
303  if ((*device)->hasCapability(HAS_TEMP))
304  {
305  for (page = 0; page < (*device)->getNumPages(); page++)
306  {
307  (*device)->setPage(page);
308  val16 = (*device)->smbus()->readWord((*device)->getAddress(), READ_ITEMP);
309  Serial.print(page, HEX); Serial.print(F(",0x"));
310  Serial.print(READ_ITEMP, HEX);Serial.print(F(",READ_ITEMP,2,0x"));Serial.print(val16, HEX);Serial.print(F(","));Serial.println(math_.lin11_to_float(val16), DEC);
311  }
312  }
313  */
314  id++;
315  device++;
316  }
317  index++;
318  delay(POLL_DELAY);
319 
320 
321 
322 }
static LT_PMBus * pmbusPec
#define READ_POUT
Definition: LT_PMBus.h:120
LTC PSM Device.
#define HAS_VIN
uint8_t getAddress()
Get the address.
virtual void setSpeed(uint32_t speed)
Set the speed. If > 100000, enable clock stretching.
LTC SMBus Support: Implementation for a shared SMBus layer.
LTC SMBus Support: Implementation for a shared SMBus layer.
static LT_SMBusPec * smbusPec
float lin16_to_float(lin16_t lin16_mant, lin16m_t vout_mode)
void enablePec(uint8_t address)
Enable pec for all transactions.
Definition: LT_PMBus.cpp:3173
#define HAS_POUT
#define READ_IOUT
Definition: LT_PMBus.h:116
LT_PMBusMath math_
float lin11_to_float(lin11_t xin)
LTC PMBus Support.
static LT_PMBusDevice ** devices
#define VOUT_MODE
Definition: LT_PMBus.h:76
static void print_info(LT_PMBusDevice *device, int id)
#define POLL_DELAY
LTC SMBus Support: Implementation for a LTC3880 Fault Log.
static int channel
LT_PMBusDevice ** getDevices()
uint16_t readMfrSpecialId()
static LT_PMBus * pmbusNoPec
void changeSpeed(uint32_t speed)
Change the speed of the bus.
Definition: LT_I2CBus.cpp:73
LTC PMBus Support: Implementation for a LTC Fault Log.
#define STATUS_WORD
Definition: LT_PMBus.h:106
LT_SMBus * smbus()
Definition: LT_PMBus.h:401
LTC PSM Device Dector.
static LT_PMBusDevice ** device
LTC SMBus Support: Implementation for a shared SMBus layer.
virtual LT_I2CBus * i2cbus(void)=0
static int index
#define HAS_IOUT
Library Header File for LT_PMBusDevice.
#define HAS_PIN
LTC PMBus Support.
static bool doprint
#define READ_PIN
Definition: LT_PMBus.h:121
LTC PSM SpeedTest.
void detect()
Detect devices on bus.
#define HAS_IIN
static LT_SMBusNoPec * smbusNoPec
#define HAS_STATUS_WORD
static void loop()
Repeats Linduino loop.
LTC PMBus Support: Math conversion routines.
#define READ_VOUT
Definition: LT_PMBus.h:115
#define READ_VIN
Definition: LT_PMBus.h:113
static LT_PMBusDetect * detector
#define HAS_VOUT
static void setup()
Initialize Linduino.
#define READ_IIN
Definition: LT_PMBus.h:114
PMBus communication.
Definition: LT_PMBus.h:370