Linduino  1.3.0
Linear Technology Arduino-Compatible Demonstration Board
DC1605B.ino
Go to the documentation of this file.
1 /*!
2 Linear Technology DC1605B Demonstration Board.
3 LTC2936: Programable Hex Voltage Supervisor with Comparator Outputs and EEPROM
4 
5 @verbatim
6 
7  Setup:
8  Set the terminal baud rate to 115200 and select the newline terminator.
9 
10 @endverbatim
11 
12 http://www.linear.com/product/LTC2936
13 
14 http://www.linear.com/demo/DC1605B
15 
16 
17 Copyright 2018(c) Analog Devices, Inc.
18 
19 All rights reserved.
20 
21 Redistribution and use in source and binary forms, with or without
22 modification, are permitted provided that the following conditions are met:
23  - Redistributions of source code must retain the above copyright
24  notice, this list of conditions and the following disclaimer.
25  - Redistributions in binary form must reproduce the above copyright
26  notice, this list of conditions and the following disclaimer in
27  the documentation and/or other materials provided with the
28  distribution.
29  - Neither the name of Analog Devices, Inc. nor the names of its
30  contributors may be used to endorse or promote products derived
31  from this software without specific prior written permission.
32  - The use of this software may or may not infringe the patent rights
33  of one or more patent holders. This license does not release you
34  from the requirement that you obtain separate licenses from these
35  patent holders to use this software.
36  - Use of the software either in source or binary form, must be run
37  on or directly connected to an Analog Devices Inc. component.
38 
39 THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
40 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
41 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
42 IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
43 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
44 LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
45 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
46 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
47 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
48 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
49 */
50 
51 /*! @file
52  @ingroup LTC2936
53 */
54 
55 #include <Arduino.h>
56 #include <stdint.h>
57 #include "Linduino.h"
58 #include "UserInterface.h"
59 #include "LT_I2CBus.h"
60 #include "Wire.h"
61 #include "LT_SMBusNoPec.h"
62 #include "LTC2936.h"
63 
64 // LTC2637 DAC on the DC1605B board
65 #define DC1605_DAC_ADDRESS 0x22 //7-bit global address for DAC
66 
67 // LTC2936 I2C address (selectable by two jumpers on the board)
68 #define LTC2936_I2C_ADDRESS 0x58 // 10
69 
70 // Global variables
71 static uint8_t ltc2936_i2c_address;
72 static uint8_t dc1605_dac_address;
73 static LT_SMBus *smbus = new LT_SMBusNoPec();
74 
75 //! Initialize Linduino
76 //! @return void
77 void setup()
78 {
79  Serial.begin(115200); //! Initialize the serial port to the PC
80  print_title();
83  print_prompt();
84 
86  {
88  }
89 }
90 
91 //! Repeats Linduino loop
92 //! @return void
93 void loop()
94 {
95  uint8_t user_command;
96  uint8_t *addresses = NULL;
97  uint16_t res;
98 
99  if (Serial.available()) //! Checks for user input
100  {
101  user_command = read_int(); //! Reads the user command
102  Serial.println(user_command);
103 
104  switch (user_command) //! Prints the appropriate submenu
105  {
106  case 0:
108  {
110  }
111  break;
112  case 1:
114  {
116  }
118  break;
119  case 2:
121  {
123  }
125  Serial.println(res, HEX);
126  break;
127  case 3:
129  {
131  }
133  break;
134  case 4:
135  // write to the LTC2637 DACs on the DC1605 board
137  delay(1);
139  delay(1);
141  delay(1);
143  delay(1);
145  delay(1);
147  break;
148  case 5:
150  {
152  }
154  break;
155  case 6:
156  // margin the supplies to the 20% high side
157  // write to the LTC2637 DACs on the DC1605 board
159  delay(1);
161  delay(1);
163  delay(1);
165  delay(1);
167  delay(1);
169  break;
170  case 7:
172  {
174  }
176  break;
177  case 8:
178  addresses = smbus->probe(0);
179  while (*addresses != 0)
180  {
181  Serial.print(F("ADDR 0x"));
182  Serial.println(*addresses++, HEX);
183  }
184  break;
185  default:
186  Serial.println(F("Incorrect Option"));
187  break;
188  }
189  print_prompt();
190  }
191 }
192 
193 // Function Definitions
194 
195 //! Prints the title block when program first starts.
197 {
198  Serial.print(F("\n*****************************************************************\n"));
199  Serial.print(F("* DC1605B Demonstration Program *\n"));
200  Serial.print(F("* *\n"));
201  Serial.print(F("* This program demonstrates how to send and receive data from *\n"));
202  Serial.print(F("* the DC1605B demo board. *\n"));
203  Serial.print(F("* *\n"));
204  Serial.print(F("* Set the baud rate to 115200 and select the newline terminator.*\n"));
205  Serial.print(F("* *\n"));
206  Serial.print(F("*****************************************************************\n"));
207 }
208 
209 //! Prints main menu.
211 {
212  Serial.print(F(" 1-Write LTC2936 registers with default settings\n"));
213  Serial.print(F(" 2-Read Status (STATUS_WORD)\n"));
214  Serial.print(F(" 3-Read All Registers\n"));
215  Serial.print(F(" 4-Set DAC voltages on Vn pins to interesting values\n"));
216  Serial.print(F(" 5-Change LTC2936 voltage thresholds to match interesting DAC voltages\n"));
217  Serial.print(F(" 6-Set DAC voltages on Vn pins to +20% high values\n"));
218  Serial.print(F(" 7-Clear LTC2936 ALERTB\n"));
219  Serial.print(F(" 8-Bus Probe\n"));
220  Serial.print(F("\nEnter a command:"));
221 }
222 
223 //! Prints a warning if the demo board is not detected.
225 {
226  Serial.println(F("\nWarning: Demo board not detected. Linduino will attempt to proceed."));
227 }
228 
229 
230 //! Return 1 if the LTC2936 is write-protected
231 // 0 otherwise
233 {
234  uint16_t res;
235 
236  res = smbus->readWord(ltc2936_i2c_address, LTC2936_STATUS_WORD);
237 
238  //b[0] is the write-protect bit
239  return ((res&0x0001) == 0x0001) ? 1 : 0;
240 }
241 
242 //! Return 1 if the ltc2936 device address is 0x50 - 0x57
243 //! which are the DC1605B EEPROM address, and will cause problems with Linduino
245 {
246  if ((ltc2936_i2c_address >= 0x50) && (ltc2936_i2c_address <= 0x57))
247  return 1;
248  else
249  return 0;
250 }
251 
252 //! Print a warning message to go with the 0x5n address
254 {
255  Serial.println(F("\nWARNING: Linduino should not be used to address address 0x5n."));
256  Serial.println(F("WARNING: Addresses 0x5n are shared by the DC1605B EEPROM."));
257  Serial.println(F("WARNING: When using Linduino, set ASEL1 jumper = 1"));
258 }
259 
260 //! Read all registers from RAM
262 {
263  uint16_t res;
264  res = smbus->readWord(ltc2936_i2c_address, LTC2936_WRITE_PROTECT);
265  Serial.print(F("\n LTC2936_WRITE_PROTECT:"));
266  Serial.println(res, HEX);
267 
268  res = smbus->readWord(ltc2936_i2c_address, LTC2936_GPI_CONFIG);
269  Serial.print(F("\n LTC2936_GPI_CONFIG: "));
270  Serial.println(res, HEX);
271 
272  res = smbus->readWord(ltc2936_i2c_address, LTC2936_GPIO1_CONFIG);
273  Serial.print(F("\n LTC2936_GPIO1_CONFIG: "));
274  Serial.println(res, HEX);
275 
276  res = smbus->readWord(ltc2936_i2c_address, LTC2936_GPIO2_3_CONFIG);
277  Serial.print(F("\n LTC2936_GPIO2_3_CONFIG: "));
278  Serial.println(res, HEX);
279 
280  res = smbus->readWord(ltc2936_i2c_address, LTC2936_V1_THR);
281  Serial.print(F("\n LTC2936_V1_THR: "));
282  Serial.println(res, HEX);
283 
284  res = smbus->readWord(ltc2936_i2c_address, LTC2936_V2_THR);
285  Serial.print(F("\n LTC2936_V2_THR: "));
286  Serial.println(res, HEX);
287 
288  res = smbus->readWord(ltc2936_i2c_address, LTC2936_V3_THR);
289  Serial.print(F("\n LTC2936_V3_THR: "));
290  Serial.println(res, HEX);
291 
292  res = smbus->readWord(ltc2936_i2c_address, LTC2936_V4_THR);
293  Serial.print(F("\n LTC2936_V4_THR: "));
294  Serial.println(res, HEX);
295 
296  res = smbus->readWord(ltc2936_i2c_address, LTC2936_V5_THR);
297  Serial.print(F("\n LTC2936_V5_THR: "));
298  Serial.println(res, HEX);
299 
300  res = smbus->readWord(ltc2936_i2c_address, LTC2936_V6_THR);
301  Serial.print(F("\n LTC2936_V6_THR: "));
302  Serial.println(res, HEX);
303 
304  res = smbus->readWord(ltc2936_i2c_address, LTC2936_V1_CONFIG);
305  Serial.print(F("\n LTC2936_V1_CONFIG: "));
306  Serial.println(res, HEX);
307 
308  res = smbus->readWord(ltc2936_i2c_address, LTC2936_V2_CONFIG);
309  Serial.print(F("\n LTC2936_V2_CONFIG: "));
310  Serial.println(res, HEX);
311 
312  res = smbus->readWord(ltc2936_i2c_address, LTC2936_V3_CONFIG);
313  Serial.print(F("\n LTC2936_V3_CONFIG: "));
314  Serial.println(res, HEX);
315 
316  res = smbus->readWord(ltc2936_i2c_address, LTC2936_V4_CONFIG);
317  Serial.print(F("\n LTC2936_V4_CONFIG: "));
318  Serial.println(res, HEX);
319 
320  res = smbus->readWord(ltc2936_i2c_address, LTC2936_V5_CONFIG);
321  Serial.print(F("\n LTC2936_V5_CONFIG: "));
322  Serial.println(res, HEX);
323 
324  res = smbus->readWord(ltc2936_i2c_address, LTC2936_V6_CONFIG);
325  Serial.print(F("\n LTC2936_V6_CONFIG: "));
326  Serial.println(res, HEX);
327 
328  res = smbus->readWord(ltc2936_i2c_address, LTC2936_HISTORY_WORD);
329  Serial.print(F("\n LTC2936_HISTORY_WORD: "));
330  Serial.println(res, HEX);
331 
332  res = smbus->readWord(ltc2936_i2c_address, LTC2936_PADS);
333  Serial.print(F("\n LTC2936_PADS: "));
334  Serial.println(res, HEX);
335 
336  res = smbus->readWord(ltc2936_i2c_address, LTC2936_BACKUP_WORD);
337  Serial.print(F("\n LTC2936_BACKUP_WORD: "));
338  Serial.println(res, HEX);
339 
340  res = smbus->readWord(ltc2936_i2c_address, LTC2936_STATUS_WORD);
341  Serial.print(F("\n LTC2936_STATUS_WORD: "));
342  Serial.println(res, HEX);
343  Serial.print(F("\n"));
344 
345 }
346 
347 //! Load demo-board default settings into RAM
349 {
350  if (ltc2936_is_write_protected(ltc2936_i2c_address) != 1)
351  {
352  smbus->writeWord(ltc2936_i2c_address, LTC2936_WRITE_PROTECT, 0xAAA8);
353  delay(1);
354  smbus->writeWord(ltc2936_i2c_address, LTC2936_GPI_CONFIG, 0x1040);
355  delay(1);
356  smbus->writeWord(ltc2936_i2c_address, LTC2936_GPIO1_CONFIG, 0x002E);
357  delay(1);
358  smbus->writeWord(ltc2936_i2c_address, LTC2936_GPIO2_3_CONFIG, 0x2E07);
359  delay(1);
360  smbus->writeWord(ltc2936_i2c_address, LTC2936_V1_THR, 0xAF87); // ov = 2.2, uv = 1.8
361  delay(1);
362  smbus->writeWord(ltc2936_i2c_address, LTC2936_V2_THR, 0xAF87); // ov = 2.2, uv = 1.8
363  delay(1);
364  smbus->writeWord(ltc2936_i2c_address, LTC2936_V3_THR, 0xAF87); // ov = 2.2, uv = 1.8
365  delay(1);
366  smbus->writeWord(ltc2936_i2c_address, LTC2936_V4_THR, 0xAF87); // ov = 2.2, uv = 1.8
367  delay(1);
368  smbus->writeWord(ltc2936_i2c_address, LTC2936_V5_THR, 0xAF87); // ov = 2.2, uv = 1.8
369  delay(1);
370  smbus->writeWord(ltc2936_i2c_address, LTC2936_V6_THR, 0xAF87); // ov = 2.2, uv = 1.8
371  delay(1);
372  smbus->writeWord(ltc2936_i2c_address, LTC2936_V1_CONFIG, 0x019C); // low range
373  delay(1);
374  smbus->writeWord(ltc2936_i2c_address, LTC2936_V2_CONFIG, 0x019C); // low range
375  delay(1);
376  smbus->writeWord(ltc2936_i2c_address, LTC2936_V3_CONFIG, 0x019C); // low range
377  delay(1);
378  smbus->writeWord(ltc2936_i2c_address, LTC2936_V4_CONFIG, 0x019C); // low range
379  delay(1);
380  smbus->writeWord(ltc2936_i2c_address, LTC2936_V5_CONFIG, 0x019C); // low range
381  delay(1);
382  smbus->writeWord(ltc2936_i2c_address, LTC2936_V6_CONFIG, 0x019C); // low range
383  }
384  else
385  {
386  // error, LTC2936 is write-protected
387  Serial.println(F("\nERROR: LTC2936 is write-protected. Cannot write to registers"));
388  }
389 }
390 
391 //! Load different voltage threshold settings into RAM
393 {
394  if (ltc2936_is_write_protected(ltc2936_i2c_address) != 1)
395  {
396  smbus->writeWord(ltc2936_i2c_address, LTC2936_WRITE_PROTECT, 0xAAA8);
397  delay(1);
398  smbus->writeWord(ltc2936_i2c_address, LTC2936_GPI_CONFIG, 0x1040);
399  delay(1);
400  smbus->writeWord(ltc2936_i2c_address, LTC2936_GPIO1_CONFIG, 0x002E);
401  delay(1);
402  smbus->writeWord(ltc2936_i2c_address, LTC2936_GPIO2_3_CONFIG, 0x2E07);
403  delay(1);
404  smbus->writeWord(ltc2936_i2c_address, LTC2936_V1_THR, 0x8769); // ov = 3.6, uv = 3.0
405  delay(1);
406  smbus->writeWord(ltc2936_i2c_address, LTC2936_V2_THR, 0x554B); // ov = 2.6, uv = 2.4
407  delay(1);
408  smbus->writeWord(ltc2936_i2c_address, LTC2936_V3_THR, 0x917D); // ov = 1.9, uv = 1.7
409  delay(1);
410  smbus->writeWord(ltc2936_i2c_address, LTC2936_V4_THR, 0x735F); // ov = 1.6, uv = 1.4
411  delay(1);
412  smbus->writeWord(ltc2936_i2c_address, LTC2936_V5_THR, 0x5541); // ov = 1.3, uv = 1.1
413  delay(1);
414  smbus->writeWord(ltc2936_i2c_address, LTC2936_V6_THR, 0x3C32); // ov = 1.05, uv = 0.95
415  delay(1);
416  smbus->writeWord(ltc2936_i2c_address, LTC2936_V1_CONFIG, 0x0C9C); // medium range
417  delay(1);
418  smbus->writeWord(ltc2936_i2c_address, LTC2936_V2_CONFIG, 0x0C9C); // medium range
419  delay(1);
420  smbus->writeWord(ltc2936_i2c_address, LTC2936_V3_CONFIG, 0x0D9C); // low range
421  delay(1);
422  smbus->writeWord(ltc2936_i2c_address, LTC2936_V4_CONFIG, 0x0D9C); // low range
423  delay(1);
424  smbus->writeWord(ltc2936_i2c_address, LTC2936_V5_CONFIG, 0x0D9C); // low range
425  delay(1);
426  smbus->writeWord(ltc2936_i2c_address, LTC2936_V6_CONFIG, 0x0D9C); // low range
427  }
428  else
429  {
430  // error, LTC2936 is write-protected
431  Serial.println(F("\nERROR: LTC2936 is write-protected. Cannot write to registers"));
432  }
433 }
434 
435 
436 //! Clear ALERTB
438 {
439  // smbus->writeWord(ltc2936_i2c_address, LTC2936_CLEAR_HISTORY, 0x0000);
440  smbus->sendByte(ltc2936_i2c_address, LTC2936_CLEAR_HISTORY);
441 }
442 
443 
444 //! program the DAC on the DC1605B demo board to a voltage
445 // refer to the LTC2637 datasheet
446 void dc1605_write_dac_voltage(uint8_t dac_address, int channel, float voltage)
447 {
448  uint8_t *data = (uint8_t *)malloc(3*sizeof(uint8_t));
449  uint8_t cmd, ch_addr;
450  uint16_t v_data;
451  float v;
452 
453  // pack the data bytes with the necessary bits
454  // channel numbers 0 - 7 correspond to letters A - H in the datasheet
455  if ((channel < 8) && (channel >= 0))
456  {
457  ch_addr = (uint8_t)channel;
458  }
459  else
460  {
461  //address all channels
462  ch_addr = 0x0F;
463  }
464  cmd = 0x30; // the write to and update command
465  data[0] = cmd | ch_addr;
466 
467  if ((voltage > 0) && (voltage < 4.096))
468  {
469  v = (voltage/4.096);
470  v_data = (uint16_t)(v*4096);
471  }
472  else
473  {
474  Serial.println(F("\nERROR: Voltage out of DAC range"));
475  }
476  data[1] = (uint8_t)(v_data >> 4); // most significant bits
477  data[2] = (uint8_t)(v_data << 4); // least significant bits
478 
479  //write the command and data to the DAC
480  Wire.beginTransmission(dac_address);
481  // LT_Wire.expectToWrite((uint16_t) 3);
482  Wire.write(data[0]);
483  Wire.write(data[1]);
484  Wire.write(data[2]);
485  Wire.endTransmission(1);
486 
487  free(data);
488  return;
489 
490 }
#define LTC2936_V2_CONFIG
Definition: LTC2936.h:99
#define LTC2936_V6_THR
Definition: LTC2936.h:97
static uint8_t dc1605_dac_address
Definition: DC1605B.ino:72
static void loop()
Repeats Linduino loop.
Definition: DC1605B.ino:93
unsigned char user_command
#define LTC2936_CLEAR_HISTORY
Definition: LTC2936.h:110
static int dc1605b_is_address_0x5n(uint8_t ltc2936_i2c_address)
Return 1 if the ltc2936 device address is 0x50 - 0x57 which are the DC1605B EEPROM address...
Definition: DC1605B.ino:244
#define LTC2936_V1_THR
Definition: LTC2936.h:92
static void setup()
Initialize Linduino.
Definition: DC1605B.ino:77
#define DC1605_DAC_ADDRESS
Definition: DC1605B.ino:65
Header File for Linduino Libraries and Demo Code.
static LT_SMBus * smbus
Definition: DC1605B.ino:73
#define LTC2936_V3_THR
Definition: LTC2936.h:94
virtual void sendByte(uint8_t address, uint8_t command)=0
SMBus send byte command.
static uint8_t ltc2936_i2c_address
Definition: DC1605B.ino:71
#define LTC2936_V3_CONFIG
Definition: LTC2936.h:100
#define LTC2936_GPIO2_3_CONFIG
Definition: LTC2936.h:91
static void ltc2936_read_registers(uint8_t ltc2936_i2c_address)
Read all registers from RAM.
Definition: DC1605B.ino:261
static uint8_t channel
LTC2305 Channel selection.
Definition: DC1444A.ino:127
static void ltc2936_demo_board_defaults(uint8_t ltc2936_i2c_address)
Load demo-board default settings into RAM.
Definition: DC1605B.ino:348
virtual void writeWord(uint8_t address, uint8_t command, uint16_t data)=0
SMBus write word command.
Header for LTC2936: Programable Hex Voltage Supervisor with Comparator Outputs and EEPROM...
union LT_union_int32_4bytes data
Definition: DC2094A.ino:138
#define LTC2936_I2C_ADDRESS
Definition: DC1605B.ino:68
#define LTC2936_V4_THR
Definition: LTC2936.h:95
#define LTC2936_V5_THR
Definition: LTC2936.h:96
LT_I2CBus: Routines to communicate to I2C by Wire Library.
#define LTC2936_V1_CONFIG
Definition: LTC2936.h:98
#define LTC2936_V5_CONFIG
Definition: LTC2936.h:102
#define LTC2936_V6_CONFIG
Definition: LTC2936.h:103
static void print_prompt()
Prints main menu.
Definition: DC1605B.ino:210
#define LTC2936_BACKUP_WORD
Definition: LTC2936.h:113
#define LTC2936_STATUS_WORD
Definition: LTC2936.h:114
static void dc1605b_print_address_warning()
Print a warning message to go with the 0x5n address.
Definition: DC1605B.ino:253
static void ltc2936_clear_alertb(uint8_t ltc2936_i2c_address)
Clear ALERTB.
Definition: DC1605B.ino:437
virtual uint8_t * probe(uint8_t command)=0
SMBus bus probe.
LTC SMBus Support: Implementation for a shared SMBus layer.
static void dc1605_write_dac_voltage(uint8_t dac_address, int channel, float voltage)
program the DAC on the DC1605B demo board to a voltage
Definition: DC1605B.ino:446
#define LTC2936_V2_THR
Definition: LTC2936.h:93
int32_t read_int()
#define LTC2936_V4_CONFIG
Definition: LTC2936.h:101
static int ltc2936_is_write_protected(uint8_t ltc2936_i2c_address)
Return 1 if the LTC2936 is write-protected.
Definition: DC1605B.ino:232
#define LTC2936_HISTORY_WORD
Definition: LTC2936.h:105
#define LTC2936_PADS
Definition: LTC2936.h:109
static void print_title()
Prints the title block when program first starts.
Definition: DC1605B.ino:196
static float voltage
Definition: DC2289AA.ino:71
static void ltc2936_demo_board_demo_thresholds(uint8_t ltc2936_i2c_address)
Load different voltage threshold settings into RAM.
Definition: DC1605B.ino:392
#define LTC2936_WRITE_PROTECT
Definition: LTC2936.h:88
static void print_warning_prompt()
Prints a warning if the demo board is not detected.
Definition: DC1605B.ino:224
#define LTC2936_GPIO1_CONFIG
Definition: LTC2936.h:90
virtual uint16_t readWord(uint8_t address, uint8_t command)=0
SMBus read word command.
#define LTC2936_GPI_CONFIG
Definition: LTC2936.h:89