Linduino  1.3.0
Linear Technology Arduino-Compatible Demonstration Board
rail_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 <Linduino.h>
65 #include <UserInterface.h>
66 #include <stdint.h>
67 
68 #include <LT_SMBusPec.h>
69 #include <LT_PMBusMath.h>
70 #include <LT_SMBus.h>
71 #include <LT_PMBusRail.h>
72 #include <LT_I2CBus.h>
73 #include <LT_SMBusGroup.h>
74 #include <LT_PMBusDetect.h>
75 #include <LT_PMBus.h>
76 #include <LT_FaultLog.h>
77 #include <LT_PMBusDevice.h>
78 #include <LT_SMBusNoPec.h>
79 #include <LT_SMBusBase.h>
80 #include <LT_PMBusDetect.h>
81 #include <LT_PMBusSpeedTest.h>
82 #include <LT_PMBusDeviceLTC3880.h>
83 #include <LT_3880FaultLog.h> // For compilation of library
84 
85 static bool doprint = true;
86 static bool dodisplay = true;
87 
88 #define POLL_DELAY 2000
89 
90 static LT_SMBusNoPec *smbusNoPec = new LT_SMBusNoPec(100000); // Start at slow speed
91 static LT_SMBusPec *smbusPec = new LT_SMBusPec(100000); // Start at slow speed
92 static LT_PMBus *pmbusNoPec = new LT_PMBus(smbusNoPec);
93 static LT_PMBus *pmbusPec = new LT_PMBus(smbusPec);
94 static LT_PMBusDetect *detector = new LT_PMBusDetect(pmbusNoPec);
98 static LT_PMBusRail **rail;
99 static int id = 0;
100 
101 //! Initialize Linduino
102 //! @return void
103 void setup()
104 {
105  uint32_t speed = 500000;
106 
107  Serial.begin(115200); //! Initialize the serial port to the PC
108 
109  if (doprint) Serial.println(F("Detecting Addresses..."));
110  detector->detect();
111  device = (devices = detector->getDevices());
112  while (*device != NULL)
113  {
114  if (doprint) Serial.print(F(" Device: "));
115  if (doprint) Serial.print((*device)->getType());
116  if (doprint) Serial.print(F(" Address: "));
117  if (doprint) Serial.print((*device)->getAddress(), HEX);
118 
119  if (doprint) Serial.print(F(", Speed: "));
120  if (doprint) Serial.print((*device)->getMaxSpeed(), DEC);
121  if (doprint) Serial.println();
122 
123  // Switch the device to Pec
124  pmbusNoPec->enablePec((*device)->getAddress());
125  (*device)->changePMBus(pmbusPec);
126 
127  // Speed test to find fastest speed the bus can operate at.
128  if (speed > (*device)->getMaxSpeed())
129  speed = (*device)->getMaxSpeed();
130 
131  device++;
132  }
133 
134  rail = (rails = detector->getRails());
135  while (*rail != NULL)
136  {
137  if (doprint) Serial.print(F(" Rail: "));
138  if (doprint) Serial.print(F(" Address: "));
139  if (doprint) Serial.print((*rail)->getAddress(), HEX);
140  if (doprint) Serial.print(F(" Pages: "));
141  if (doprint) Serial.print((*rail)->getNoPages(), DEC);
142  if (doprint) Serial.println();
143  (*rail)->changePMBus(pmbusPec);
144  rail++;
145  }
146 
147  if (doprint) Serial.print("Changing bus speed to ");
148  if (doprint) Serial.println(speed, DEC);
149  // This will change the speed of the I2C bus and enable clock stretching if > 100kHz
150  // Only affects Pec becuase the device was switched to Pec.
151  device = devices;
152  while ((*device) != 0)
153  {
154  (*device)->setSpeed(speed);
155  device++;
156  }
157  // Change the NoPec version to keep out world consistent.
158  pmbusNoPec->smbus()->i2cbus()->changeSpeed(speed);
159 
160  Serial.println(F("Id,Time(ms),Address,NoPages,Multiphase,Type,Value"));
161 
162 }
163 
164 //! Print basic info
165 //! @return void
167 {
168  unsigned long time;
169 
170  time = millis();
171 
172  Serial.print(id++);
173  Serial.print(F(","));
174  Serial.print(time);
175  Serial.print(F(",0x"));
176  Serial.print(rail->getAddress(), HEX);
177  Serial.print(F(",0x"));
178  Serial.print(rail->readMfrSpecialId(), HEX);
179  Serial.print(F(","));
180  Serial.print(rail->getNoPages());
181  Serial.print(F(","));
182  if (rail->isMultiphase()) Serial.print(F("1"));
183  else Serial.print("0");
184  Serial.print(F(","));
185 }
186 
187 //! Repeats Linduino loop
188 //! @return void
189 void loop()
190 {
191  float f;
192  uint16_t status;
193 
194  // Telemetry
195  rail = rails;
196  while ((*rail) != NULL)
197  {
198  if ((*rail)->hasCapability(HAS_STATUS_WORD))
199  {
200  status = (*rail)->readStatusWord();
201  print_info(*rail);
202  Serial.print(F("SWORD,0x"));
203  Serial.println(status, HEX);
204  }
205 
206  if ((*rail)->hasCapability(HAS_VIN))
207  {
208  f = (*rail)->readVin(true);
209  print_info(*rail);
210  Serial.print(F("VIN,"));
211  Serial.println(f, DEC);
212  }
213 
214  if ((*rail)->hasCapability(HAS_VOUT))
215  {
216  f = (*rail)->readVout(true);
217  print_info(*rail);
218  Serial.print(F("VOUT,"));
219  Serial.println(f, DEC);
220  }
221 
222  if ((*rail)->hasCapability(HAS_IIN))
223  {
224  f = (*rail)->readIin(true);
225  print_info(*rail);
226  Serial.print(F("IIN,"));
227  Serial.println(f, DEC);
228  }
229 
230  if ((*rail)->hasCapability(HAS_IOUT))
231  {
232  f = (*rail)->readIout(true);
233  print_info(*rail);
234  Serial.print(F("Iout,"));
235  Serial.println(f, DEC);
236  }
237 
238  if ((*rail)->hasCapability(HAS_PIN))
239  {
240  f = (*rail)->readPin(true);
241  print_info(*rail);
242  Serial.print(F("PIN,"));
243  Serial.println(f, DEC);
244  }
245 
246  if ((*rail)->hasCapability(HAS_POUT))
247  {
248  f = (*rail)->readPout(true);
249  print_info(*rail);
250  Serial.print(F("POUT,"));
251  Serial.println(f, DEC);
252  }
253 
254  if ((*rail)->hasCapability(HAS_TEMP))
255  {
256  f = (*rail)->readInternalTemperature(true);
257  print_info(*rail);
258  Serial.print(F("TEMP,"));
259  Serial.println(f, DEC);
260  }
261 
262  f = (*rail)->readEfficiency(true);
263  if (f > 20.0) // Weeds out no load rails or unmeasuremable rails.
264  {
265  print_info(*rail);
266  Serial.print(F("EFF,"));
267  Serial.println(f, DEC);
268  }
269 
270  if ((*rail)->isMultiphase())
271  {
272  f = (*rail)->readPhaseBalance(true);
273  print_info(*rail);
274  Serial.print(F("IBAL,"));
275  Serial.println(f, DEC);
276  }
277 
278  rail++;
279  }
280 
281  delay(POLL_DELAY);
282 
283 
284 
285 }
static LT_PMBusDevice ** device
Definition: rail_logger.ino:96
LT_PMBusRail ** getRails()
LTC PSM Device.
uint16_t readMfrSpecialId()
Read the special of a polyphase rail.
#define HAS_VIN
LTC SMBus Support: API for a shared SMBus layer.
static LT_SMBusPec * smbusPec
Definition: rail_logger.ino:91
uint8_t getAddress()
Get ther rail address.
virtual void setSpeed(uint32_t speed)
Set the speed. If > 100000, enable clock stretching.
LTC SMBus Support: Implementation for a shared SMBus layer.
void changePMBus(LT_PMBus *pmbus)
Change the pmbus.
#define HAS_TEMP
LTC SMBus Support: Implementation for a shared SMBus layer.
String status(void)
Returns a descriptive string based on status of pins.
Definition: DC2364A.ino:217
Header File for Linduino Libraries and Demo Code.
static LT_PMBusDetect * detector
Definition: rail_logger.ino:94
static void loop()
Repeats Linduino loop.
static bool doprint
Definition: rail_logger.ino:85
void enablePec(uint8_t address)
Enable pec for all transactions.
Definition: LT_PMBus.cpp:3173
static LT_PMBusRail ** rails
Definition: rail_logger.ino:97
static LT_PMBusDevice ** devices
Definition: rail_logger.ino:95
static bool dodisplay
Definition: rail_logger.ino:86
#define HAS_POUT
LTC PMBus Support.
static void print_info(LT_PMBusRail *rail)
Print basic info.
static LT_PMBus * pmbusNoPec
Definition: rail_logger.ino:92
LTC SMBus Support: Implementation for a LTC3880 Fault Log.
LT_PMBusDevice ** getDevices()
#define POLL_DELAY
Definition: rail_logger.ino:88
static LT_PMBus * pmbusPec
Definition: rail_logger.ino:93
LT_I2CBus: Routines to communicate to I2C by Wire Library.
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.
uint8_t getNoPages()
Get the number of pages in the rail.
static void setup()
Initialize Linduino.
uint16_t readStatusWord()
Read the status word of a polyphase rail.
bool isMultiphase()
Ask if the rail is multiphase.
LT_SMBus * smbus()
Definition: LT_PMBus.h:401
static LT_SMBusNoPec * smbusNoPec
Definition: rail_logger.ino:90
LTC PSM Device Dector.
LTC SMBus Support: Implementation for a shared SMBus layer.
virtual LT_I2CBus * i2cbus(void)=0
#define HAS_IOUT
Library Header File for LT_PMBusDevice.
#define HAS_PIN
LTC PMBus Support.
LTC PSM SpeedTest.
void detect()
Detect devices on bus.
#define HAS_IIN
#define HAS_STATUS_WORD
LTC PMBus Support: Math conversion routines.
PMBusRail communication. For Multiphase Rails.
Definition: LT_PMBusRail.h:72
#define HAS_VOUT
static LT_PMBusRail ** rail
Definition: rail_logger.ino:98
LTC SMBus Support: Implementation for a shared SMBus layer.
PMBus communication.
Definition: LT_PMBus.h:370