| 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);
89 static LT_PMBusDevice **devices;
90 static LT_PMBusDevice **device;
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 }
pmbusPec
static LT_PMBus * pmbusPec
Definition: device_logger.ino:87
READ_POUT
#define READ_POUT
Definition: LT_PMBus.h:120
LT_PMBusDeviceLTC3880.h
LTC PSM Device.
HAS_VIN
#define HAS_VIN
Definition: LT_PMBusDevice.h:59
LT_PMBusDevice::getAddress
uint8_t getAddress()
Get the address.
Definition: LT_PMBusDevice.cpp:87
LT_PMBusDevice::setSpeed
virtual void setSpeed(uint32_t speed)
Set the speed. If > 100000, enable clock stretching.
Definition: LT_PMBusDevice.cpp:109
LT_SMBusGroup.h
LTC SMBus Support: Implementation for a shared SMBus layer.
LT_SMBusPec.h
LTC SMBus Support: Implementation for a shared SMBus layer.
smbusPec
static LT_SMBusPec * smbusPec
Definition: device_logger.ino:85
LT_PMBusDevice
Definition: LT_PMBusDevice.h:75
LT_PMBusMath::lin16_to_float
float lin16_to_float(lin16_t lin16_mant, lin16m_t vout_mode)
Definition: LT_PMBusMath.cpp:435
LT_PMBus::enablePec
void enablePec(uint8_t address)
Enable pec for all transactions.
Definition: LT_PMBus.cpp:3173
LT_SMBusNoPec
Definition: LT_SMBusNoPec.h:60
HAS_POUT
#define HAS_POUT
Definition: LT_PMBusDevice.h:62
READ_IOUT
#define READ_IOUT
Definition: LT_PMBus.h:116
math_
LT_PMBusMath math_
Definition: LT_PMBusMath.cpp:460
LT_PMBusMath::lin11_to_float
float lin11_to_float(lin11_t xin)
Definition: LT_PMBusMath.cpp:427
LT_PMBusRail.h
LTC PMBus Support.
devices
static LT_PMBusDevice ** devices
Definition: device_logger.ino:89
VOUT_MODE
#define VOUT_MODE
Definition: LT_PMBus.h:76
print_info
static void print_info(LT_PMBusDevice *device, int id)
Definition: device_logger.ino:144
LT_SMBusPec
Definition: LT_SMBusPec.h:61
POLL_DELAY
#define POLL_DELAY
Definition: device_logger.ino:82
LT_3880FaultLog.h
LTC SMBus Support: Implementation for a LTC3880 Fault Log.
channel
static int channel
Definition: device_logger.ino:92
LT_PMBusDetect::getDevices
LT_PMBusDevice ** getDevices()
Definition: LT_PMBusDetect.cpp:72
LT_PMBusDevice::readMfrSpecialId
uint16_t readMfrSpecialId()
Definition: LT_PMBusDevice.cpp:244
pmbusNoPec
static LT_PMBus * pmbusNoPec
Definition: device_logger.ino:86
LT_I2CBus::changeSpeed
void changeSpeed(uint32_t speed)
Change the speed of the bus.
Definition: LT_I2CBus.cpp:73
LT_FaultLog.h
LTC PMBus Support: Implementation for a LTC Fault Log.
STATUS_WORD
#define STATUS_WORD
Definition: LT_PMBus.h:106
LT_PMBus::smbus
LT_SMBus * smbus()
Definition: LT_PMBus.h:401
LT_PMBusDetect.h
LTC PSM Device Dector.
device
static LT_PMBusDevice ** device
Definition: device_logger.ino:90
LT_SMBusNoPec.h
LTC SMBus Support: Implementation for a shared SMBus layer.
LT_SMBus::i2cbus
virtual LT_I2CBus * i2cbus(void)=0
index
static int index
Definition: device_logger.ino:91
HAS_IOUT
#define HAS_IOUT
Definition: LT_PMBusDevice.h:60
LT_PMBusDetect
Definition: LT_PMBusDetect.h:56
LT_PMBusDevice.h
Library Header File for LT_PMBusDevice.
HAS_PIN
#define HAS_PIN
Definition: LT_PMBusDevice.h:63
LT_PMBus.h
LTC PMBus Support.
doprint
static bool doprint
Definition: device_logger.ino:80
READ_PIN
#define READ_PIN
Definition: LT_PMBus.h:121
LT_PMBusSpeedTest.h
LTC PSM SpeedTest.
LT_PMBusDetect::detect
void detect()
Detect devices on bus.
Definition: LT_PMBusDetect.cpp:85
HAS_IIN
#define HAS_IIN
Definition: LT_PMBusDevice.h:61
smbusNoPec
static LT_SMBusNoPec * smbusNoPec
Definition: device_logger.ino:84
HAS_STATUS_WORD
#define HAS_STATUS_WORD
Definition: LT_PMBusDevice.h:66
loop
static void loop()
Repeats Linduino loop.
Definition: device_logger.ino:171
LT_PMBusMath.h
LTC PMBus Support: Math conversion routines.
READ_VOUT
#define READ_VOUT
Definition: LT_PMBus.h:115
READ_VIN
#define READ_VIN
Definition: LT_PMBus.h:113
detector
static LT_PMBusDetect * detector
Definition: device_logger.ino:88
HAS_VOUT
#define HAS_VOUT
Definition: LT_PMBusDevice.h:58
setup
static void setup()
Initialize Linduino.
Definition: device_logger.ino:96
READ_IIN
#define READ_IIN
Definition: LT_PMBus.h:114
LT_PMBus
PMBus communication.
Definition: LT_PMBus.h:370