| Linduino 1.3.0 Linear Technology Arduino-Compatible Demonstration Board

program.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 <LT_PMBus.h>
67 #include <nvm.h>
68 #include <avr/boot.h>
69 #include "data.h"
70
71 #define SIGRD 5
72 #define LTC3880_I2C_ADDRESS 0x30
73 #define LTC2974_I2C_ADDRESS 0x32
74 #define LTC2977_I2C_ADDRESS 0x33
75
76 // Global variables
77 static uint8_t ltc3880_i2c_address;
78 static uint8_t ltc2974_i2c_address;
79 static uint8_t ltc2977_i2c_address;
80
81 static LT_SMBusNoPec *smbusNoPec = new LT_SMBusNoPec();
82 static LT_SMBusPec *smbusPec = new LT_SMBusPec();
83 static NVM *nvm = new NVM(smbusNoPec, smbusPec);
84
85 static LT_SMBus *smbus = smbusNoPec;
86 static LT_PMBus *pmbus = new LT_PMBus(smbus);
87
88 static bool pec = false;
89
90 static uint8_t dc1613_addresses[] = { LTC3880_I2C_ADDRESS, LTC2974_I2C_ADDRESS, LTC2977_I2C_ADDRESS };
91
92 //! Wait for nvm operation to complete
93 //! @return void
94 void wait_for_nvm()
95 {
96 delay(2); // Allow time for action to start.
97
98 smbus->waitForAck(ltc3880_i2c_address, 0x00);
99 pmbus->waitForNotBusy(ltc3880_i2c_address);
100 pmbus->waitForNvmDone(ltc3880_i2c_address);
101
102 pmbus->waitForNotBusy(ltc2974_i2c_address);
103
104 pmbus->waitForNotBusy(ltc2977_i2c_address);
105 }
106
107 //! Program the nvm
108 //! @return void
109 void program_nvm ()
110 {
111 bool worked;
112
113 Serial.println(F("Please wait for programming EEPROM..."));
114 worked = nvm->programWithData(isp_data);
115 wait_for_nvm();
116 // Programming creates a fault when a Poll on Ack generates a Busy Fault just after
117 // a Clear Fault Log.
118 pmbus->clearFaults(ltc2977_i2c_address);
119 Serial.println(F("Programming Complete (RAM and EEPROM may not match until reset)"));
120 }
121
122 //! Verify the nvm
123 //! @return void
124 void verify_nvm ()
125 {
126 bool worked;
127
128 Serial.println(F("Please wait for verification of EEPROM..."));
129 worked = nvm->verifyWithData(isp_data);
130 wait_for_nvm();
131
132 if (worked == 0)
133 Serial.println(F("Verification complete: Invalid EEPROM data"));
134 else
135 {
136 Serial.println(F("Verification complete: Valid EEPROM data"));
137 }
138
139 // Ensure there is no write protect so that the clear faults option works.
140 pmbus->disableWriteProtectGlobal();
141 }
142
143 //! Restore nvm to ram
144 //! @return void
145 void restore_nvm ()
146 {
147 smbus->writeByte(LTC3880_I2C_ADDRESS, MFR_EEPROM_STATUS, 0x00);
148
149 Serial.println(F("Restore User All"));
150 pmbus->restoreFromNvmGlobal();
151 wait_for_nvm();
152 Serial.println(F("Restore Complete (EEPROM written to RAM)"));
153 }
154
155 //! Reset all devices
156 //! @return void
157 void reset_all_devices ()
158 {
159 Serial.println(F("Resseting all devices"));
160 pmbus->startGroupProtocol();
161 pmbus->reset(ltc3880_i2c_address);
162 pmbus->restoreFromNvm(ltc2974_i2c_address);
163 pmbus->restoreFromNvm(ltc2977_i2c_address);
164 pmbus->executeGroupProtocol();
165
166 smbus->waitForAck(ltc3880_i2c_address, 0x00);
167 pmbus->waitForNotBusy(ltc3880_i2c_address);
168
169 pmbus->waitForNotBusy(ltc2974_i2c_address);
170
171 pmbus->waitForNotBusy(ltc2977_i2c_address);
172 Serial.println(F("All devices reset (RAM == EEPROM)"));
173 }
174
175 //! Initialize Linduino
176 //! @return void
177 void setup()
178 {
179 Serial.begin(115200); //! Initialize the serial port to the PC
180 /*
181 byte sig0;
182 byte sig2;
183 byte sig4;
184 sig0 = boot_signature_byte_get (0);
185 sig2 = boot_signature_byte_get (2);
186 sig4 = boot_signature_byte_get (4);
187 if (sig0 != 0x1E || sig2 != 0x98 | sig4 != 0x01)
188 {
189 Serial.println("Sketch only runs on Mega 2560");
190 return;
191 }
192 */
193 print_title();
194 ltc3880_i2c_address = LTC3880_I2C_ADDRESS;
195 ltc2974_i2c_address = LTC2974_I2C_ADDRESS;
196 ltc2977_i2c_address = LTC2977_I2C_ADDRESS;
197 print_prompt();
198 }
199
200 //! Repeats Linduino loop
201 //! @return void
202 void loop()
203 {
204 uint8_t user_command;
205 uint8_t res;
206 uint8_t model[7];
207 uint8_t revision[10];
208 uint8_t *addresses = NULL;
209
210 if (Serial.available()) //! Checks for user input
211 {
212 user_command = read_int(); //! Reads the user command
213 if (user_command != 'm')
214 Serial.println(user_command);
215
216 switch (user_command) //! Prints the appropriate submenu
217 {
218 case 1:
219 program_nvm();
220 break;
221 case 2:
222 verify_nvm();
223 // Lock the NVM in case the verify failed.
224 pmbus->smbus()->writeByte(0x5b, MFR_EE_UNLOCK, 0x00);
225 break;
226 case 3:
227 restore_nvm();
228 break;
229 case 4:
230 program_nvm();
231 reset_all_devices();
232 break;
233 case 5:
234 pmbus->clearFaultsGlobal();
235 break;
236 case 6:
237 pmbus->enablePec(ltc3880_i2c_address);
238 pmbus->enablePec(ltc2974_i2c_address);
239 pmbus->enablePec(ltc2977_i2c_address);
240 smbus = smbusPec;
241 pmbus->smbus(smbus);
242 pec = true;
243 break;
244 case 7:
245 pmbus->disablePec(ltc3880_i2c_address);
246 pmbus->disablePec(ltc2974_i2c_address);
247 pmbus->disablePec(ltc2977_i2c_address);
248 smbus = smbusNoPec;
249 pmbus->smbus(smbus);
250 pec = false;
251 break;
252 case 8:
253 addresses = smbus->probe(0);
254 while (*addresses != 0)
255 {
256 Serial.print(F("ADDR 0x"));
257 Serial.println(*addresses++, HEX);
258 }
259 break;
260 case 9:
261 reset_all_devices();
262 break;
263 default:
264 Serial.println(F("Incorrect Option"));
265 break;
266 }
267 print_prompt();
268 }
269 }
270
271 //! Prints the title block when program first starts.
272 //! @return void
273 void print_title()
274 {
275 Serial.print(F("\n********************************************************************\n"));
276 Serial.print(F("* DC1962C In Flight Update Demonstration Program (MEGA 2560 Only) *\n"));
277 Serial.print(F("* *\n"));
278 Serial.print(F("* This program demonstrates how to program EEPROM from hex data. *\n"));
279 Serial.print(F("* *\n"));
280 Serial.print(F("* Set the baud rate to 115200 and select the newline terminator. *\n"));
281 Serial.print(F("* *\n"));
282 Serial.print(F("********************************************************************\n"));
283 }
284
285 //! Prints main menu.
286 //! @return void
287 void print_prompt()
288 {
289 Serial.print(F("\n 1-Program\n"));
290 Serial.print(F(" 2-Verify\n"));
291 Serial.print(F(" 3-Restore\n"));
292 Serial.print(F(" 4-Program and Apply\n"));
293 Serial.print(F(" 5-Clear Faults\n"));
294 Serial.print(F(" 6-PEC On\n"));
295 Serial.print(F(" 7-PEC Off\n"));
296 Serial.print(F(" 8-Bus Probe\n"));
297 Serial.print(F(" 9-Reset\n"));
298 Serial.print(F("\nEnter a command:"));
299 }
LT_PMBus::waitForNvmDone
uint8_t waitForNvmDone(uint8_t address)
Read MFR_EEPROM_STATUS until done (LTC388X only)
Definition: LT_PMBus.cpp:3278
program_nvm
static void program_nvm()
Program the nvm.
Definition: program.ino:109
user_command
unsigned char user_command
Definition: Serial_EEPROM_Test.ino:75
ltc3880_i2c_address
static uint8_t ltc3880_i2c_address
Definition: program.ino:77
smbus
static LT_SMBus * smbus
Definition: program.ino:85
ltc2974_i2c_address
static uint8_t ltc2974_i2c_address
Definition: program.ino:78
smbusPec
static LT_SMBusPec * smbusPec
Definition: program.ino:82
dc1613_addresses
static uint8_t dc1613_addresses[]
Definition: program.ino:90
LT_PMBus::reset
void reset(uint8_t address)
Issue reset to one device.
Definition: LT_PMBus.cpp:2912
LT_PMBus::disableWriteProtectGlobal
void disableWriteProtectGlobal(void)
Disable the write protect.
Definition: LT_PMBus.cpp:2556
print_title
static void print_title()
Prints the title block when program first starts.
Definition: program.ino:273
Linduino.h
Header File for Linduino Libraries and Demo Code.
data.h
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
smbusNoPec
static LT_SMBusNoPec * smbusNoPec
Definition: program.ino:81
print_prompt
static void print_prompt()
Prints main menu.
Definition: program.ino:287
LT_PMBus::clearFaults
void clearFaults(uint8_t address)
Clear the faults of the existing page.
Definition: LT_PMBus.cpp:2566
pmbus
static LT_PMBus * pmbus
Definition: program.ino:86
nvm
static NVM * nvm
Definition: program.ino:83
LT_PMBus::disablePec
void disablePec(uint8_t address)
Disable pec for all transactions.
Definition: LT_PMBus.cpp:3210
NVM::programWithData
bool programWithData(const unsigned char *)
Program with hex data.
Definition: nvm.cpp:96
nvm.h
Copyright 2018(c) Analog Devices, Inc.
LT_SMBusPec
Definition: LT_SMBusPec.h:61
LT_PMBus::waitForNotBusy
uint8_t waitForNotBusy(uint8_t address)
Read MFR_COMMON until not Busy.
Definition: LT_PMBus.cpp:3254
LT_SMBus
Definition: LT_SMBus.h:61
ltc2977_i2c_address
static uint8_t ltc2977_i2c_address
Definition: program.ino:79
verify_nvm
static void verify_nvm()
Verify the nvm.
Definition: program.ino:124
wait_for_nvm
static void wait_for_nvm()
Wait for nvm operation to complete.
Definition: program.ino:94
LT_PMBus::startGroupProtocol
void startGroupProtocol(void)
starts group protocol
Definition: LT_PMBus.cpp:3350
LT_SMBus::waitForAck
virtual uint8_t waitForAck(uint8_t address, uint8_t command)=0
Read with the address and command in loop until ack, then issue stop.
MFR_EE_UNLOCK
#define MFR_EE_UNLOCK
Definition: LT_PMBus.h:125
LTC2974_I2C_ADDRESS
#define LTC2974_I2C_ADDRESS
Definition: program.ino:73
LT_SMBus::writeByte
virtual void writeByte(uint8_t address, uint8_t command, uint8_t data)=0
SMBus write byte command.
NVM::verifyWithData
bool verifyWithData(const unsigned char *)
Verifies board NVM with hex data.
Definition: nvm.cpp:111
pec
static bool pec
Definition: program.ino:88
loop
static void loop()
Repeats Linduino loop.
Definition: program.ino:202
NVM
Definition: nvm.h:59
LT_PMBus::smbus
LT_SMBus * smbus()
Definition: LT_PMBus.h:401
LT_SMBus::probe
virtual uint8_t * probe(uint8_t command)=0
SMBus bus probe.
restore_nvm
static void restore_nvm()
Restore nvm to ram.
Definition: program.ino:145
UserInterface.h
read_int
int32_t read_int()
Definition: UserInterface.cpp:93
LTC3880_I2C_ADDRESS
#define LTC3880_I2C_ADDRESS
Definition: program.ino:72
LT_PMBus::clearFaultsGlobal
void clearFaultsGlobal(void)
Clear all the faults for all pages of all devices.
Definition: LT_PMBus.cpp:2606
LT_PMBus::executeGroupProtocol
void executeGroupProtocol(void)
ends group protocol
Definition: LT_PMBus.cpp:3356
LT_PMBus::restoreFromNvm
void restoreFromNvm(uint8_t address)
Restore device from NVM.
Definition: LT_PMBus.cpp:2663
LTC2977_I2C_ADDRESS
#define LTC2977_I2C_ADDRESS
Definition: program.ino:74
LT_PMBus.h
LTC PMBus Support.
MFR_EEPROM_STATUS
#define MFR_EEPROM_STATUS
Definition: LT_PMBus.h:148
LT_PMBus::restoreFromNvmGlobal
void restoreFromNvmGlobal(void)
Restore all devices from NVM.
Definition: LT_PMBus.cpp:2683
setup
static void setup()
Initialize Linduino.
Definition: program.ino:177
reset_all_devices
static void reset_all_devices()
Reset all devices.
Definition: program.ino:157
LT_PMBus
PMBus communication.
Definition: LT_PMBus.h:370