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 
83 static NVM *nvm = new NVM(smbusNoPec, smbusPec);
84 
86 static LT_PMBus *pmbus = new LT_PMBus(smbus);
87 
88 static bool pec = false;
89 
91 
92 //! Wait for nvm operation to complete
93 //! @return void
95 {
96  delay(2); // Allow time for action to start.
97 
98  smbus->waitForAck(ltc3880_i2c_address, 0x00);
101 
103 
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.
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 {
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
158 {
159  Serial.println(F("Resseting all devices"));
160  pmbus->startGroupProtocol();
161  pmbus->reset(ltc3880_i2c_address);
164  pmbus->executeGroupProtocol();
165 
166  smbus->waitForAck(ltc3880_i2c_address, 0x00);
168 
170 
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();
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();
232  break;
233  case 5:
234  pmbus->clearFaultsGlobal();
235  break;
236  case 6:
240  smbus = smbusPec;
241  pmbus->smbus(smbus);
242  pec = true;
243  break;
244  case 7:
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:
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
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
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 }
uint8_t waitForNvmDone(uint8_t address)
Read MFR_EEPROM_STATUS until done (LTC388X only)
Definition: LT_PMBus.cpp:3278
static void program_nvm()
Program the nvm.
Definition: program.ino:109
unsigned char user_command
static uint8_t ltc3880_i2c_address
Definition: program.ino:77
static LT_SMBus * smbus
Definition: program.ino:85
static uint8_t ltc2974_i2c_address
Definition: program.ino:78
static LT_SMBusPec * smbusPec
Definition: program.ino:82
static uint8_t dc1613_addresses[]
Definition: program.ino:90
void reset(uint8_t address)
Issue reset to one device.
Definition: LT_PMBus.cpp:2912
void disableWriteProtectGlobal(void)
Disable the write protect.
Definition: LT_PMBus.cpp:2556
static void print_title()
Prints the title block when program first starts.
Definition: program.ino:273
Header File for Linduino Libraries and Demo Code.
void enablePec(uint8_t address)
Enable pec for all transactions.
Definition: LT_PMBus.cpp:3173
static LT_SMBusNoPec * smbusNoPec
Definition: program.ino:81
static void print_prompt()
Prints main menu.
Definition: program.ino:287
void clearFaults(uint8_t address)
Clear the faults of the existing page.
Definition: LT_PMBus.cpp:2566
static LT_PMBus * pmbus
Definition: program.ino:86
static NVM * nvm
Definition: program.ino:83
void disablePec(uint8_t address)
Disable pec for all transactions.
Definition: LT_PMBus.cpp:3210
bool programWithData(const unsigned char *)
Program with hex data.
Definition: nvm.cpp:96
Copyright 2018(c) Analog Devices, Inc.
uint8_t waitForNotBusy(uint8_t address)
Read MFR_COMMON until not Busy.
Definition: LT_PMBus.cpp:3254
static uint8_t ltc2977_i2c_address
Definition: program.ino:79
static void verify_nvm()
Verify the nvm.
Definition: program.ino:124
static void wait_for_nvm()
Wait for nvm operation to complete.
Definition: program.ino:94
void startGroupProtocol(void)
starts group protocol
Definition: LT_PMBus.cpp:3350
virtual uint8_t waitForAck(uint8_t address, uint8_t command)=0
Read with the address and command in loop until ack, then issue stop.
#define MFR_EE_UNLOCK
Definition: LT_PMBus.h:125
#define LTC2974_I2C_ADDRESS
Definition: program.ino:73
virtual void writeByte(uint8_t address, uint8_t command, uint8_t data)=0
SMBus write byte command.
bool verifyWithData(const unsigned char *)
Verifies board NVM with hex data.
Definition: nvm.cpp:111
static bool pec
Definition: program.ino:88
static void loop()
Repeats Linduino loop.
Definition: program.ino:202
Definition: nvm.h:59
LT_SMBus * smbus()
Definition: LT_PMBus.h:401
virtual uint8_t * probe(uint8_t command)=0
SMBus bus probe.
static void restore_nvm()
Restore nvm to ram.
Definition: program.ino:145
int32_t read_int()
#define LTC3880_I2C_ADDRESS
Definition: program.ino:72
void clearFaultsGlobal(void)
Clear all the faults for all pages of all devices.
Definition: LT_PMBus.cpp:2606
void executeGroupProtocol(void)
ends group protocol
Definition: LT_PMBus.cpp:3356
void restoreFromNvm(uint8_t address)
Restore device from NVM.
Definition: LT_PMBus.cpp:2663
#define LTC2977_I2C_ADDRESS
Definition: program.ino:74
LTC PMBus Support.
#define MFR_EEPROM_STATUS
Definition: LT_PMBus.h:148
void restoreFromNvmGlobal(void)
Restore all devices from NVM.
Definition: LT_PMBus.cpp:2683
static void setup()
Initialize Linduino.
Definition: program.ino:177
static void reset_all_devices()
Reset all devices.
Definition: program.ino:157
PMBus communication.
Definition: LT_PMBus.h:370