Linduino  1.3.0
Linear Technology Arduino-Compatible Demonstration Board
DC1880A.ino
Go to the documentation of this file.
1 /*!
2 Linear Technology DC1880A Demonstration Board
3 
4 @verbatim
5 
6 SETUP:
7  Set the terminal baud rate to 115200 and select the newline terminator.
8  External power supply is required.
9 
10 USER INPUT DATA FORMAT:
11  decimal : 14
12  hex : 0x0E (Data), 0xE (Reg)
13 
14 @endverbatim
15 
16 http://www.linear.com/product/LTC2874
17 
18 http://www.linear.com/product/LTC2874#demoboards
19 
20 
21 Copyright 2018(c) Analog Devices, Inc.
22 
23 All rights reserved.
24 
25 Redistribution and use in source and binary forms, with or without
26 modification, are permitted provided that the following conditions are met:
27  - Redistributions of source code must retain the above copyright
28  notice, this list of conditions and the following disclaimer.
29  - Redistributions in binary form must reproduce the above copyright
30  notice, this list of conditions and the following disclaimer in
31  the documentation and/or other materials provided with the
32  distribution.
33  - Neither the name of Analog Devices, Inc. nor the names of its
34  contributors may be used to endorse or promote products derived
35  from this software without specific prior written permission.
36  - The use of this software may or may not infringe the patent rights
37  of one or more patent holders. This license does not release you
38  from the requirement that you obtain separate licenses from these
39  patent holders to use this software.
40  - Use of the software either in source or binary form, must be run
41  on or directly connected to an Analog Devices Inc. component.
42 
43 THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
44 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
45 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
46 IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
47 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
48 LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
49 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
50 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
51 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
52 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53 
54 IO-Link is a registered trademark of PROFIBUS User Organization (PNO).
55 */
56 
57 /*! @file
58  @ingroup LTC2874
59 */
60 
61 #include <Arduino.h>
62 #include <stdint.h>
63 #include "Linduino.h"
64 #include "UserInterface.h"
65 #include "LT_I2C.h"
66 #include "LT_SPI.h"
67 #include "LTC2874.h"
68 #include "QuikEval_EEPROM.h"
69 #include <Wire.h>
70 #include <SPI.h>
71 
72 
73 // Function Prototypes
74 void print_title();
75 void print_prompt();
76 uint8_t reg_test();
78 
79 // Menu selections from print_prompt
80 void menu_1_cq();
81 void menu_2_lplus();
82 void menu_3_wakeup_cq();
83 void menu_4_24v_mode();
84 void menu_5_sio_mode();
85 void menu_6_set_illm();
86 void menu_7_clear_event();
87 void menu_8_update_all();
88 void menu_9_reset();
91 void menu_12_read_bit();
94 
95 
96 // Demo Board Name
97 char demo_name[] = "DC1880"; //!< Demo Board Name stored in QuikEval EEPROM
98 
99 // ***Global Variables***
100 
101 uint8_t demo_board_connected; //!< Set to 1 if the board is connected
102 
103 //******************************** Initialize Linduino *******************************
104 //! Initialize Linduino
105 
106 void setup()
107 // Setup the Program
108 {
109  quikeval_I2C_init(); //! Initializes Linduino I2C port.
110 
111  output_high(LTC2874_CS); //! Pulls LTC2874 Chip Select High
112 
113  quikeval_SPI_init(); //! Configures the SPI port for 4Mhz SCK
114  quikeval_SPI_connect(); //! Connects SPI to QuikEval port
115  Serial.begin(115200); //! Initializes the serial port to the PC
116  print_title(); //! Displays the title
118 
119  //! Checks if correct demo board is connected.
122  //! Prints the prompt if the correct demo board is connected
124  {
125  print_prompt();
126  }
127  else
128  {
130  demo_board_connected = true;
131  }
132 }
133 
134 
135 //*************************************** LOOP ***************************************
136 //! Repeats Linduino loop
137 
138 void loop()
139 {
140  // The main control loop
141  if (demo_board_connected) //! Does nothing if the demo board is not connected.
142  {
143  if (Serial.available()) //! Checks if user input is available.
144  {
145  int16_t user_command; // User input command
146 
147  user_command = read_int(); //! Reads the user command (if available).
148  Serial.println(user_command);
149  Serial.flush();
150  switch (user_command)
151  {
152  case 1:
153  menu_1_cq();
154  break;
155 
156  case 2:
157  menu_2_lplus();
158  break;
159 
160  case 3:
162  break;
163 
164  case 4:
165  menu_4_24v_mode();
166  break;
167 
168  case 5:
169  menu_5_sio_mode();
170  break;
171 
172  case 6:
173  menu_6_set_illm();
174  break;
175 
176  case 7:
178  break;
179 
180  case 8:
182  break;
183 
184  case 9:
185  menu_9_reset();
186  break;
187 
188  case 10:
190  break;
191 
192  case 11:
194  break;
195 
196  case 12:
198  break;
199 
200  case 13:
202  break;
203 
204  case 14:
206  break;
207 
208  default:
209  Serial.println("Incorrect Option");
210  break;
211  }
212 
213  Serial.println("");
214  Serial.println("*************************");
215  print_prompt();
216  }
217  }
218 }
219 
220 //************************************************************************************
221 //! Menu 1: Enable/Disable CQ output for specified port
222 //************************************************************************************
223 void menu_1_cq(void)
224 {
225  uint8_t port, value = 0;
226 
227  Serial.println(F("Select CQ output (1,2,3,4, 5=ALL)")); //get port
228  port = read_int();
229  if (port == 5)
230  {
231  Serial.println("All");
232  }
233  else
234  {
235  Serial.println(port);
236  }
237 
238  if ((port < 1) || (port > 5)) //check limits
239  {
240  Serial.println(F("Selection out of range"));
241  return;
242  }
243 
244  Serial.println(F("Select 1 to Enable or 0 to Disable")); //get value
245  value = read_int();
246  Serial.println(value);
247 
248  if ((value < 0) || (value > 1)) //check limits for bit
249  {
250  Serial.println(F("Selection out of range"));
251  return;
252  }
253 
254  LTC2874_cq_output(port, value); //write to register
255 
256  Serial.print(F("CQ output"));
257  if (port ==5)
258  {
259  Serial.print("s are ");
260  }
261  else
262  {
263  Serial.print(" ");
264  Serial.print(port);
265  Serial.print(F(" is "));
266  }
267  Serial.println(value);
268 }
269 
270 //************************************************************************************
271 //! Menu 2: Enable/Disable L+ output for specified port
272 //************************************************************************************
273 void menu_2_lplus(void)
274 {
275  uint8_t port, value = 0;
276 
277  Serial.println(F("Select L+ output (1,2,3,4, 5=ALL)"));
278  port = read_int();
279  if (port == 5)
280  {
281  Serial.println("All");
282  }
283  else
284  {
285  Serial.println(port);
286  }
287 
288  if ((port < 1) || (port > 5)) //check limits
289  {
290  Serial.println(F("Selection out of range"));
291  return;
292  }
293 
294  Serial.println(F("Select 1 to Enable or 0 to Disable"));
295  value = read_int();
296  Serial.println(value);
297 
298  if ((value < 0) || (value > 1)) //check limits for bit
299  {
300  Serial.println(F("Selection out of range"));
301  return;
302  }
303 
304  LTC2874_lplus_output(port, value);
305 
306  Serial.print(F("L+ output"));
307  if (port ==5)
308  {
309  Serial.print("s are ");
310  }
311  else
312  {
313  Serial.print(" ");
314  Serial.print(port);
315  Serial.print(F(" is "));
316  }
317  Serial.println(value);
318 }
319 
320 //************************************************************************************
321 //! Menu 3: Generate Wake-Up Request (WURQ) on CQ output
322 //************************************************************************************
324 {
325  uint8_t data, port = 0;
326 
327  Serial.println(F("Generate Wakeup for CQ output (1,2,3,4)"));
328  port = read_int();
329  Serial.println(port);
330 
331  if ((port < 1) || (port > 4)) //check limits
332  {
333  Serial.println(F("Selection out of range"));
334  return;
335  }
337  Serial.print("Wake-Up Request generated for CQ");
338  Serial.print(port);
339 }
340 
341 //************************************************************************************
342 //! Menu 4: Change value of 24VMODE bit
343 //************************************************************************************
344 void menu_4_24v_mode(void)
345 {
346  uint8_t value = 0;
347  Serial.println(F("Enable (1) or Disable (0) 24V Mode"));
348  value = read_int();
349 
350  if ((value < 0) || (value > 1)) //check limits
351  {
352  Serial.println(F("Selection out of range"));
353  return;
354  }
355 
356  LTC2874_24v_mode(value);
357  Serial.print(F("24VMODE = "));
358  Serial.println(value);
359 }
360 
361 //************************************************************************************
362 //! Menu 5: Change SIO_MODE setting for specified port.
363 //************************************************************************************
364 void menu_5_sio_mode(void) //!<
365 {
366  uint8_t port = 0;
367 
368  Serial.println(F("Enable SIO mode for CQ output (1,2,3,4, 5=ALL)"));
369  port = read_int();
370  if (port == 5)
371  {
372  Serial.println("All");
373  }
374  else
375  {
376  Serial.println(port);
377  }
378 
379  if ((port < 1) || (port > 5)) //check limits
380  {
381  Serial.println(F("Selection out of range"));
382  return;
383  }
384  Serial.print(F("SIO mode set for "));
385  if (port ==5)
386  {
387  Serial.print("ALL");
388  }
389  else
390  {
391  Serial.print("port ");
392  Serial.print(port);
393  }
394  LTC2874_sio_mode(port);
395 }
396 
397 //************************************************************************************
398 //! Menu 6: Change ILLM setting for specified port.
399 //************************************************************************************
400 void menu_6_set_illm(void)
401 {
402  uint8_t port, value = 0;
403 
404  Serial.println(F("Select port for ILLM (1,2,3,4, 5=All)"));
405  port = read_int();
406 
407  if ((port < 1) || (port > 5)) //check limits
408  {
409  Serial.println(F("Selection out of range"));
410  return;
411  }
412  if (port == 5)
413  {
414  Serial.println("All");
415  }
416  else
417  {
418  Serial.println(port);
419  }
420 
421  Serial.println(F("Enter value to write (0x0-0x3); use Hex 0xn format."));
422  value = read_int();
423  Serial.print("0x");
424  Serial.println(value, HEX);
425 
426  if ((value < 0x0) || (value > 0x3)) //check limits
427  {
428  Serial.println(F("Value out of range"));
429  return;
430  }
431  //! Update internal register
432  LTC2874_write_ILLM_value(port, value);
433 
434  return;
435 }
436 
437 //************************************************************************************
438 //! Menu 7: Clear all Event registers
439 //************************************************************************************
441 {
442  Serial.println(F("Event registers cleared"));
447 }
448 //************************************************************************************
449 //! Menu 8: Update all registers
450 //************************************************************************************
452 {
453  Serial.println(F("All registers updated"));
455  return;
456 }
457 
458 //************************************************************************************
459 //! Menu 9: Reset LTC2874
460 //************************************************************************************
461 void menu_9_reset(void)
462 {
463  Serial.println(F("LTC2874 has been reset"));
464  LTC2874_reset();
465  return;
466 }
467 
468 //************************************************************************************
469 //! Menu 10: Read byte of data from a register
470 //************************************************************************************
472 {
473  uint8_t address, data = 0;
474 
475  Serial.println(F("Select Register to be read (0x0-0xE); use Hex 0xn format."));
476  address = read_int();
477  if ((address > 0xE ) || (address < 0x0)) //If user enters an invalid option
478  {
479  Serial.println("No registers in this range");
480  return;
481  }
482 
483  data = LTC2874_read_reg(address);
484 
485  Serial.print("Register 0x");
486  Serial.print(address, HEX);
487  Serial.print(" reads 0x");
488  Serial.println (data, HEX);
489  return;
490 }
491 
492 //************************************************************************************
493 //! Menu 11: Write byte of data to a register
494 //************************************************************************************
496 {
497  uint8_t data, address = 0;
498 
499  address = reg_test();
500  if (address == 0)
501  {
502  return;
503  }
504 
505  Serial.print("Selected Register is 0x");
506  Serial.println(address, HEX);
507 
508  Serial.println(F("Enter data to load in register; use Hex 0xnn format."));
509  data = read_int();
510 
511  Serial.print("Data loaded is 0x");
512  Serial.println(data, HEX);
513 
514  LTC2874_write_register_update_all(address, data);
515  return;
516 }
517 
518 //************************************************************************************
519 //! Menu 12: Read one bit from a register
520 //************************************************************************************
522 {
523  uint8_t value, address = 0;
524 
525  Serial.println(F("Select Register that contains bit to read (0x0-0xE); use Hex 0xn format."));
526  Serial.println();
527  address = read_int();
528 
529  if ((address > 0xE ) || (address < 0x0)) //If user enters an invalid option
530  {
531  Serial.println("No registers in this range");
532  return;
533  }
534 
535  Serial.print("Selected Register is 0x");
536  Serial.println(address, HEX);
537 
538  Serial.println(F("Enter bit position (0-7) for bit to read"));
539  value = read_int();
540  Serial.print("Bit position ");
541  Serial.print(value);
542  value = 0x01 << value;
543 
544  value = LTC2874_read_bit(address, value );
545  Serial.print(" = ");
546  Serial.println(value);
547  return;
548 }
549 
550 //************************************************************************************
551 //! Menu 13: Set one bit in writable register
552 //************************************************************************************
554 {
555  uint8_t data, address = 0;
556 
557  address = reg_test();
558  if (address == 0)
559  {
560  return;
561  }
562 
563  Serial.print("Selected Register is 0x");
564  Serial.println(address, HEX);
565 
566  Serial.println(F("Enter bit position (0-7) to Set"));
567  data = read_int();
568 
569  Serial.print("Bit position ");
570  Serial.print(data);
571  data = 0x01 << data;
572  LTC2874_write_bit_set_update_all(address, data); //! Update
573  Serial.print(" has been Set");
574  return;
575 }
576 
577 //************************************************************************************
578 //! Menu 14: Clear one bit in writable register
579 //************************************************************************************
581 {
582  uint8_t data, address = 0;
583 
584  address = reg_test();
585  if (address == 0)
586  {
587  return;
588  }
589 
590  Serial.print("Selected Register is 0x");
591  Serial.println(address, HEX);
592 
593  Serial.println(F("Enter bit position (0-7) to Clear"));
594  data = read_int();
595 
596  Serial.print("Bit position ");
597  Serial.print(data);
598  data = 0x01 << data;
599  LTC2874_write_bit_clr_update_all(address, data); //! Update
600  Serial.print(" has been Cleared");
601  return;
602 }
603 
604 //************************************************************************************
605 //! Print the title block
606 //************************************************************************************
608 {
609  Serial.println("*****************************************************************");
610  Serial.println("* DC1880A Demonstration Program *");
611  Serial.println("* *");
612  Serial.println("* This program demonstrates communication with the LTC2874 *");
613  Serial.println("* Quad IO-Link Master Hot Swap Controller and PHY *");
614  Serial.println("* *");
615  Serial.println("* *");
616  Serial.println("* *");
617  Serial.println("* Set the baud rate to 115200 select the newline terminator. *");
618  Serial.println("*****************************************************************");
619 }
620 
621 //************************************************************************************
622 //! Print main menu and prompt user for an input command
623 //************************************************************************************
625 {
626  Serial.println("\nLTC2874 Demo Menu:");
627 
628  Serial.println(" 1-CQ Output Enable/Disable");
629  Serial.println(" 2-L+ Output Enable/Disable");
630  Serial.println(" 3-Generate Wake-Up Request (WURQ)");
631  Serial.println(" 4-24V IO-Link Mode");
632  Serial.println(" 5-SIO Mode");
633  Serial.println(" 6-Select ILLM Sinking Current");
634  Serial.println(" 7-Clear Event Registers");
635  Serial.println(" 8-Update All");
636  Serial.println(" 9-Reset");
637  Serial.println(" 10-Read Register");
638  Serial.println(" 11-Write Register");
639  Serial.println(" 12-Read Bit");
640  Serial.println(" 13-Set Bit");
641  Serial.println(" 14-Clear Bit");
642 
643  Serial.println();
644 
645  Serial.print("Enter a command: ");
646 }
647 
648 //************************************************************************************
649 //! Test register number against valid range for Write
650 //************************************************************************************
651 uint8_t reg_test()
652 {
653  uint8_t address;
654 
655  Serial.println(F("Select Register to write to; use Hex 0xn format."));
656  Serial.println(F("NOTE: 0x0,0x6 and 0x7 are read only."));
657  Serial.println();
658  address = read_int();
659 
660  if ((address > 0xF ) || (address < 0x0)) //If user enters an invalid option
661  {
662  Serial.println("Error: Invalid register");
663  return(0);
664  }
665  else if (address == 0)
666  {
667  Serial.println("Error: Register 0x0 is read only");
668  return(0);
669  }
670  else if (address == 5)
671  {
672  Serial.println("Error: Only lower nibble of 0x5 is writable");
673  }
674  else if (address == 6)
675  {
676  Serial.println("Error: Register 0x6 is read only");
677  return(0);
678  }
679  else if (address == 7)
680  {
681  Serial.println("Error: Register 0x7 is read only");
682  return(0);
683  }
684 
685  return(address);
686 }
687 
688 //************************************************************************************
689 //! Print warning prompt
690 //************************************************************************************
692 {
693  Serial.println(F("No demo board connected."));
694  Serial.println(F("However, the Linduino will attempt to proceed..."));
695 }
696 
static uint8_t reg_test()
Test register number against valid range for Write.
Definition: DC1880A.ino:651
static void menu_1_cq()
Menu 1: Enable/Disable CQ output for specified port.
Definition: DC1880A.ino:223
unsigned char user_command
static void menu_11_write_register()
Menu 11: Write byte of data to a register.
Definition: DC1880A.ino:495
#define LTC2874_EVENT4_REG5
Definition: LTC2874.h:137
void LTC2874_lplus_output(uint8_t port, uint8_t value)
Enables or Disables L+ output for specified port, then Updates.
Definition: LTC2874.cpp:131
void LTC2874_sio_mode(uint8_t port)
Sets SIO_MODE bit (and also Clears SLEW bit) for specified port, then Updates.
Definition: LTC2874.cpp:174
#define output_high(pin)
Set "pin" high.
Definition: Linduino.h:75
static void menu_2_lplus()
Menu 2: Enable/Disable L+ output for specified port.
Definition: DC1880A.ino:273
Header File for Linduino Libraries and Demo Code.
static void loop()
Repeats Linduino loop.
Definition: DC1880A.ino:138
static void menu_4_24v_mode()
Menu 4: Change value of 24VMODE bit.
Definition: DC1880A.ino:344
LTC2874: Quad IO-Link Master Hot Swap Power Controller and PHY.
static void menu_3_wakeup_cq()
Menu 3: Generate Wake-Up Request (WURQ) on CQ output.
Definition: DC1880A.ino:323
static void print_warning_prompt()
Print warning prompt.
Definition: DC1880A.ino:691
static uint8_t address
Definition: DC2091A.ino:83
union LT_union_int32_4bytes data
Definition: DC2094A.ino:138
static void menu_6_set_illm()
Menu 6: Change ILLM setting for specified port.
Definition: DC1880A.ino:400
void LTC2874_write_register(uint8_t LTC2874_register, uint8_t LTC2874_data)
Writes byte of data to a register without Updating.
Definition: LTC2874.cpp:641
static void menu_10_read_register()
Menu 10: Read byte of data from a register.
Definition: DC1880A.ino:471
void LTC2874_cq_output(uint8_t port, uint8_t value)
Enables or Disables CQ output for specified port, then Updates.
Definition: LTC2874.cpp:88
#define LTC2874_EVENT2_REG3
Definition: LTC2874.h:135
QuikEval EEPROM Library.
static void menu_14_write_bit_clr()
Menu 14: Clear one bit in writable register.
Definition: DC1880A.ino:580
void LTC2874_write_ILLM_value(uint8_t port, uint8_t value)
Changes ILLM (Sinking current) setting for specified port without Updating.
Definition: LTC2874.cpp:283
static void menu_12_read_bit()
Menu 12: Read one bit from a register.
Definition: DC1880A.ino:521
static void print_title()
Print the title block.
Definition: DC1880A.ino:607
void quikeval_SPI_init(void)
Configure the SPI port for 4Mhz SCK.
Definition: LT_SPI.cpp:151
static void setup()
Initialize Linduino.
Definition: DC1880A.ino:106
void LTC2874_reset(void)
Resets LTC2874, returning default values to registers.
Definition: LTC2874.cpp:582
int8_t discover_demo_board(char *demo_name)
Read the ID string from the EEPROM and determine if the correct board is connected.
#define LTC2874_EVENT3_REG4
Definition: LTC2874.h:136
uint8_t LTC2874_read_bit(uint8_t LTC2874_register, uint8_t LTC2874_bit)
Reads a data BIT from specified register.
Definition: LTC2874.cpp:618
static void menu_5_sio_mode()
Menu 5: Change SIO_MODE setting for specified port.
Definition: DC1880A.ino:364
LT_SPI: Routines to communicate with ATmega328P&#39;s hardware SPI port.
static void menu_9_reset()
Menu 9: Reset LTC2874.
Definition: DC1880A.ino:461
void LTC2874_wakeup_request(uint8_t port)
Sends WURQ (Wake-up Request) on specified port.
Definition: LTC2874.cpp:433
#define LTC2874_EVENT1_REG2
Definition: LTC2874.h:134
LT_I2C: Routines to communicate with ATmega328P&#39;s hardware I2C port.
static void print_prompt()
Print main menu and prompt user for an input command.
Definition: DC1880A.ino:624
char demo_name[]
Demo Board Name stored in QuikEval EEPROM.
Definition: DC1880A.ino:97
void quikeval_SPI_connect()
Connect SPI pins to QuikEval connector through the Linduino MUX. This will disconnect I2C...
Definition: LT_SPI.cpp:138
int32_t read_int()
void LTC2874_write_bit_clr_update_all(uint8_t LTC2874_register, uint8_t LTC2874_bit)
Clears a register bit, then Updates.
Definition: LTC2874.cpp:556
void LTC2874_update_all(void)
Updates all registers.
Definition: LTC2874.cpp:461
void LTC2874_write_register_update_all(uint8_t LTC2874_register, uint8_t LTC2874_data)
Writes byte of data to a register, then Updates.
Definition: LTC2874.cpp:478
void LTC2874_24v_mode(uint8_t value)
Changes value of the 24VMODE bit, then Updates.
Definition: LTC2874.cpp:218
void LTC2874_write_bit_set_update_all(uint8_t LTC2874_register, uint8_t LTC2874_bit)
Sets a register bit, then Updates.
Definition: LTC2874.cpp:530
uint8_t LTC2874_read_reg(uint8_t LTC2874_register)
Reads data byte from specified register.
Definition: LTC2874.cpp:598
void quikeval_I2C_init(void)
Initializes Linduino I2C port.
Definition: LT_I2C.cpp:394
#define LTC2874_CS
Definition: LTC2874.h:84
void quikeval_I2C_connect(void)
Switch MUX to connect I2C pins to QuikEval connector.
Definition: LT_I2C.cpp:401
static void menu_13_write_bit_set()
Menu 13: Set one bit in writable register.
Definition: DC1880A.ino:553
static void menu_7_clear_event()
Menu 7: Clear all Event registers.
Definition: DC1880A.ino:440
static uint8_t demo_board_connected
Set to 1 if the board is connected.
Definition: DC1880A.ino:101
static void menu_8_update_all()
Menu 8: Update all registers.
Definition: DC1880A.ino:451