Linduino  1.3.0
Linear Technology Arduino-Compatible Demonstration Board
DC2430A.ino
Go to the documentation of this file.
1 /*!
2 Linear Technology DC2430 Demonstration Board
3 
4 @verbatim
5 
6 DC590B USB to Serial Controller
7 
8 This file contains the routines to emulate the DC590B USB to Serial Converter. All commands
9 are supported except Uxxy the Write Port D bus. Added the 'D' delay ms command.
10 With this program, the Linduino can be used by the QuikEval program running on a PC
11 to communicate with QuikEval compatible demo boards.
12 
13 The Kxy bit bang command uses the following pin mappings :
14 0-Linduino 2
15 1-Linduino 3
16 2-Linduino 4
17 3-Linduino 5
18 4-Linduino 6
19 5-Linduino 7
20 
21 @endverbatim
22 
23 http://www.linear.com/demo/DC2430A
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 DC2430A
61 */
62 
63 
64 #include <Arduino.h>
65 #include <stdint.h>
66 #include "Linduino.h"
67 #include "QuikEval_EEPROM.h"
68 #include "LT_SPI.h"
69 #include "UserInterface.h"
70 #include "LT_I2C.h"
71 #include <Wire.h>
72 #include <SPI.h>
73 
74 // define a "spoof_board_id" to force the "i" command to return a specific ID string.
75 // This can be used to fake QuikEval into loading a specific GUI, even if the ID EEPROM
76 // is not present. A few examples are below. NOT defining will result in normal behavior,
77 // "i" command will cause EEPROM to be read.
78 
79 //#define spoof_board_id "LTC4261,Cls,D4261,01,01,DC,DC998A,--------------"
80 //#define spoof_board_id "LTC2440,Cls,D2440,01,01,DC,DC570,---------------"
81 //#define spoof_board_id "LTC2946,Cls,D2946,01,01,DC,DC2156A,-------------"
82 
83 // timeouts
84 #define READ_TIMEOUT 20
85 #define MISO_TIMEOUT 1000
86 
87 //* for DC2430 test mode
89 int DC2430_Bin = 1;
90 static int8_t demo_board_connected = 0; //!< Demo Board Name stored in QuikEval EEPROM
91 static int8_t demo_board_connected_man = 0; //!< Demo Board Name stored in QuikEval EEPROM
92 
93 // recording mode constants
94 #define RECORDING_SIZE 50
95 const byte off = 0;
96 const byte playback = 1;
97 
98 // serial mode constants
99 const byte spi_mode = 0;
100 const byte i2c_mode = 1;
101 const byte i2c_auxiliary_mode = 2;
102 
103 // hex conversion constants
104 char hex_digits[16]=
105 {
106  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
107 };
108 
109 // spi clock divider
110 const char spi_divider = SPI_CLOCK_DIV32; // configure the spi port for 4MHz SCK (500kHz@div32??)
111 
112 // global variables
113 byte serial_mode = spi_mode; // current serial mode
114 byte recording_mode = off; // recording mode off
115 char id_string[51]="USBSPI,PIC,01,01,DC,DC590,----------------------\n\0"; // id string
117 {
118  '0', 'x', '0', '0', '\0'
119 }; // buffer for ASCII hex to byte conversion
121 {
122  '\0','\0','\0'
123 }; // buffer for byte to ASCII hex conversion
125 {
126  '\0'
127 }; // buffer for saving recording loop
128 byte recording_index = 0; // index to the recording buffer
129 
130 char get_char();
131 
132 void byte_to_hex(byte value)
133 // convert a byte to two hex characters
134 {
135  byte_to_hex_buffer[0]=hex_digits[value>>4]; // get upper nibble
136  byte_to_hex_buffer[1]=hex_digits[(value & 0x0F)]; // get lower nibble
137  byte_to_hex_buffer[2]='\0'; // add NULL at end
138 }
139 
140 byte read_hex()
141 // read 2 hex characters from the serial buffer and convert
142 // them to a byte
143 {
144  byte data;
147  data = strtol(hex_to_byte_buffer, NULL, 0);
148  return(data);
149 }
150 
151 char get_char()
152 // get the next character either from the serial port
153 // or the recording buffer
154 {
155  char command='\0';
156  if (recording_mode != playback)
157  {
158  // read a command from the serial port
159  while (Serial.available() <= 0);
160  return(Serial.read());
161  }
162  else
163  {
164  // read a command from the recording buffer
166  {
167  command = recording_buffer[recording_index++];
168  // disregard loop commands during playback
169  if (command == 'w') command='\1';
170  if (command == 't') command='\1';
171  if (command == 'v') command='\1';
172  if (command == 'u') command='\1';
173  }
174  else
175  command = '\0';
176  if (command == '\0')
177  {
178  recording_index = 0;
180  }
181  return(command);
182  }
183 }
184 int i = 0;
185 unsigned char pseudo_reset = 0;
186 
187 //! Initialize Linduino
188 //! @return void
189 void setup()
190 // Setup the program
191 {
192  digitalWrite(QUIKEVAL_GPIO, LOW);
193  digitalWrite(QUIKEVAL_CS, HIGH);
194  digitalWrite(2, LOW);
195  digitalWrite(3, LOW);
196  digitalWrite(4, LOW);
197  digitalWrite(5, LOW);
198  digitalWrite(6, LOW);
199  digitalWrite(7, LOW);
200  pinMode(QUIKEVAL_GPIO, OUTPUT);
201  pinMode(QUIKEVAL_CS, OUTPUT);
202  pinMode(2, OUTPUT);
203  pinMode(3, OUTPUT);
204  pinMode(4, OUTPUT);
205  pinMode(5, OUTPUT);
206  pinMode(6, OUTPUT);
207  pinMode(7, OUTPUT);
208 
209  Serial.begin(115200); // enable the serial port for 115200 baud
210 
212  quikeval_SPI_connect(); // Connect SPI to main data port
213 
214  quikeval_I2C_init(); // Configure the EEPROM I2C port for 100kHz SCK
215  Serial.print("hello - DC2430 prog\n");
216  Serial.flush();
217 }
218 
219 //! Repeats Linduino loop
220 //! @return void
221 void loop()
222 {
223  byte tx_data;
224  byte rx_data;
225  byte pin_value;
226  int delay_value;
227  int pin;
228  char command;
229  int byte_count;
230  long delay_count;
231 
232 
233  command = get_char();
234 
235 
236  switch (command)
237  {
238  case 'A':
239  DC2430_testprog();
240  break;
241  case 'B':
243  break;
244  case 'D':
245  // delay milliseconds
246  delay_value = read_hex();
247  delay_value<<=8;
248  delay_value|=read_hex();
249  delay(delay_value);
250  break;
251  case 'g':
252  // IO pin low
254  break;
255  case 'G':
256  // IO pin high
258  break;
259  case 'H': // wait for MISO to go high with a timeout
260  delay_count = 0;
261  while (1)
262  {
263  if (input(MISO)==1) break; // MISO is high so quit
264  if (delay_count++>MISO_TIMEOUT)
265  {
266  //Serial.print('T'); // timeout occurred. Print 'T'
267  break;
268  }
269  else delay(1);
270  }
271  break;
272  case 'i':
273  // send controller id string
274  pseudo_reset = 0;
275  Serial.print(id_string);
276  Serial.print('\0');
277  Serial.flush();
278  break;
279  case 'I':
280 #ifdef spoof_board_id
281  Serial.print(spoof_board_id);
282  Serial.print('\0');
283  Serial.print('\0');
284 #else
285  // get controller id string
286  quikeval_SPI_connect(); // Connect SPI to main data port
287  pseudo_reset = 0;
288  byte_count = read_quikeval_id_string(&ui_buffer[0]);
289  if (byte_count!=0)
290  {
291  Serial.print(ui_buffer);
292  Serial.print("\n\0");
293  Serial.flush();
294  }
295 #endif
296  break;
297  case 'K':
298  // Bang pin. The pin assignments are :
299  // 0: PIND2, Arduino 2
300  // 1: PIND3, Arduino 3
301  // 2: PIND4, Arduino 4
302  // 3: PIND5, Arduino 5
303  // 4: PIND6, Arduino 6
304  // 5: PIND6, Arduino 7
305 
306  pin_value = get_char(); // read the value
307 // pin = get_char()-0x30; // read the pin
308  pin = get_char(); // read the pin
309 // if (pin_value == '0') digitalWrite(pin+2, LOW);
310 // else digitalWrite(pin+2, HIGH);
311 
312  digitalWrite(pin-0x30+2, pin_value == '0' ? LOW : HIGH);
313  break;
314  case 'k':
315  // Get pin state. The digial pin assignments are the same as for 'K',
316  // Analog pin mappings as follows:
317  // 6: Analog A0 (read only)
318  // 7: Analog A1 (read only)
319  // 8: Analog A2 (read only)
320  // 9: Analog A3 (read only)
321  pin = get_char(); // read the pin
322  if (pin <= '5')
323  {
324  Serial.print(digitalRead(pin-0x30+2));
325  }
326  else
327  {
328  int val = analogRead(pin - '6');
329  if (val < 10)
330  {
331  Serial.print("000");
332  }
333  else if (val < 100)
334  {
335  Serial.print("00");
336  }
337  else if (val < 1000)
338  {
339  Serial.print("0");
340  }
341  Serial.print(val);
342  break;
343  }
344  break;
345  case 'j':
346  // Set pin mode. The pin assignments are the same as for 'K':
347  pin_value = get_char(); // read the value
348  pin = get_char(); // read the pin
349  pinMode(pin-0x30+2, pin_value == '0' ? INPUT : OUTPUT);
350  break;
351  case 'L':
352  // wait for MISO to go low with a timeout
353  delay_count = 0;
354  while (1)
355  {
356  if (input(MISO)==0) break; // MISO is low so quit
357  if (delay_count++>MISO_TIMEOUT)
358  {
359  //Serial.print('T'); // timeout occurred. Print 'T'
360  break;
361  }
362  else delay(1);
363  }
364  break;
365  case 'M':
366  // change the serial mode
367  command = get_char();
368  switch (command)
369  {
370  case 'I':
371  // I2C mode
373  // enable_main_I2C();
375  break;
376  case 'S':
377  // spi mode
379  // Need to send command to disable LTC4302
380  // enable_main_SPI();
382  break;
383  case 'X': // axillary I2C mode - no hardware action necessary, always available.
386  break;
387  case '0': // New for Enhanced version - set SPI mode on the fly. (Mainly for Altera SPI-Avalon MM bridge)
388  SPI.setDataMode(SPI_MODE0);
389  break;
390  case '1':
391  SPI.setDataMode(SPI_MODE1);
392  break;
393  case '2':
394  SPI.setDataMode(SPI_MODE2);
395  break;
396  case '3':
397  SPI.setDataMode(SPI_MODE3);
398  break;
399  case 'a':
400  SPI.setClockDivider(SPI_CLOCK_DIV2);
401  break;
402  case 'b':
403  SPI.setClockDivider(SPI_CLOCK_DIV4);
404  break;
405  case 'c':
406  SPI.setClockDivider(SPI_CLOCK_DIV8);
407  break;
408  case 'd':
409  SPI.setClockDivider(SPI_CLOCK_DIV16);
410  break;
411  case 'e':
412  SPI.setClockDivider(SPI_CLOCK_DIV32);
413  break;
414  case 'f':
415  SPI.setClockDivider(SPI_CLOCK_DIV64);
416  break;
417  case 'g':
418  SPI.setClockDivider(SPI_CLOCK_DIV128);
419  break;
420  }
421  //delay(1);
422  break;
423  case 'p':
424  // I2C stop
425  // Switching BACK to the i2c_stop() function call. See Rev 1405, LT_i2c.cpp, Linduino One branch
426  if (serial_mode!=spi_mode) i2c_stop(); // TWCR=(1<<TWINT) | (1<<TWEN) | (1<<TWSTO); // I2C stop //i2c_stop();
427  // if(serial_mode == i2c_auxiliary_mode) i2c_stop();
428  break;
429  case 'P':
430  // ping
431  Serial.print('P');
432  delay(5);
433  break;
434  case 'Q':
435  // Read byte in I2C mode only. Add ACK
436  switch (serial_mode)
437  {
438  case i2c_mode:
439  rx_data = i2c_read(WITH_ACK);
440  byte_to_hex(rx_data);
441  Serial.print(byte_to_hex_buffer);
442  break;
443  case i2c_auxiliary_mode:
444  rx_data = i2c_read(WITH_ACK);
445  byte_to_hex(rx_data);
446  Serial.print(byte_to_hex_buffer);
447  break;
448  }
449  break;
450 
451  case 'r':
452  rx_data = spi_read(0);
453  byte_to_hex(rx_data);
454  Serial.print(byte_to_hex_buffer);
455  break;
456 
457  case 'R':
458  // Read byte, add NACK in I2C mode
459  switch (serial_mode)
460  {
461  case spi_mode:
462  rx_data = spi_read(0);
463  byte_to_hex(rx_data);
464  Serial.print(byte_to_hex_buffer);
465  break;
466  case i2c_mode:
467  rx_data = i2c_read(WITH_NACK);
468  byte_to_hex(rx_data);
469  Serial.print(byte_to_hex_buffer);
470  break;
471  case i2c_auxiliary_mode:
472  rx_data = i2c_read(WITH_NACK);
473  byte_to_hex(rx_data);
474  Serial.print(byte_to_hex_buffer);
475  break;
476  }
477  break;
478  case 's': // I2C start
479  if (serial_mode == i2c_mode) i2c_start();
481  break;
482  case 'S': // send byte
483  tx_data = read_hex();
484  switch (serial_mode)
485  {
486  case spi_mode:
487  spi_write(tx_data);
488  break;
489  case i2c_mode:
490  if (i2c_write(tx_data)==1) Serial.print('N');
491  break;
492  case i2c_auxiliary_mode:
493  if (i2c_write(tx_data)==1) Serial.print('N');
494  break;
495  }
496  break;
497  case 't': // recording loop
498  recording_index = 0;
499  do
500  {
501  command = get_char();
502  if (command == 'u') // stop recording
503  {
505  recording_index = 0;
506  break;
507  }
508  else // add character to recording buffer
509  {
511  }
512  }
513  while (1);
514  break;
515  case 'T': // transceive byte
516  tx_data = read_hex();
517  if (serial_mode == spi_mode)
518  {
519  rx_data = spi_read(tx_data);
520  byte_to_hex(rx_data);
521  Serial.print(byte_to_hex_buffer);
522  }
523  break;
524  case 'v': // echo recording loop
525  Serial.print(recording_buffer);
526  break;
527  case 'w':
529  break;
530  case 'x':
532  break;
533  case 'X':
535  break;
536  case 'Z': // line feed
537  Serial.print('\n');
538  Serial.flush();
539  break;
540  case 0x80: // Reset
541  if (pseudo_reset == 0)
542  {
543  delay(500); // The delay is needed for older GUI's
544  Serial.print("hello\n");
545  pseudo_reset = 1;
546  }
547  break;
548  }
549 }
550 
551 /* ******************************************************************************************* */
552 //! DC2430 PARALLELSYNC EXAMPLE: SOFTWARE SITE SELECTION MODE
553 //! - ENABLED BY SELECTING 'B'
554 //! - this software example assumes the following
555 //! * DC1954 J12 connected to DC2430 J5
556 //! * DC2248 J12 connected to DC2430 J6
557 //! * DC2248 J12 connected to DC2430 J7
558 //! * all SMA connections described in DC2430 Demo Manual
559 //! * DC2430 JP3 SYNC shorted to DC2430 GPIO7 (default state)
560 //! * All demo boards are powered up
561 //! (refer to the DC2430 demo manual)
562 //!
563 //! - This function performs the following
564 //! * confirms DC2430 & DC2026 using correct settings
565 //! * selects DC2430 J5 site
566 //! * programs the LTC6954
567 //! * selects DC2430 J6 site
568 //! * programs the LTC6951 #1
569 //! * selects DC2430 J7 site
570 //! * programs the LTC6951 #2
571 //! * Performs ParallelSync, by toggling GPIO7
572 //! @return void
574 {
575  char demo_name1[] = "DC1954"; // LTC6954 Demo Board Name stored in QuikEval EEPROM
576  char demo_name2[] = "DC2248"; // LTC6951 Demo Board Name stored in QuikEval EEPROM
577 
578  DC2430_Bin = 1;
579 
580  /* confirms DC2430 & DC2026 using correct settings */
582 
583  if (DC2430_Bin == 1)
584  {
585  /* selects DC2430 J5 site */
586  Serial.println("1. Setting DC2430 to J5 site");
587  changeDC2430site(5);
588  // delay(5);
590  if (demo_board_connected == 0) Serial.println("\n\n ***** LTC6954 Demo board not attached to J5, fix this and try again *****\n\n ");
591 
592  /* programs the LTC6954 */
593  Serial.println("\n2. Programming LTC6954");
595 
596  /* selects DC2430 J6 site */
597  Serial.println("\n3. Setting DC2430 to J6 site");
598  changeDC2430site(6);
599  // delay(5);
601  if (demo_board_connected == 0) Serial.println("\n\n **** LTC6951 Demo board not attached to J6, fix this and try again ***** \n\n");
602 
603  /* programs the LTC6951 #1 */
604  Serial.println("\n4. Programming LTC6951 #1");
606 
607  /* selects DC2430 J7 site */
608  Serial.println("\n5. Setting DC2430 to J7 site");
609  changeDC2430site(7);
610  // delay(5);
612  if (demo_board_connected == 0) Serial.println("\n\n **** LTC6951 Demo board not attached to J7, fix this and try again ****\n\n");
613 
614  /* programs the LTC6951 #2 */
615  Serial.println("\n6. Programming LTC6951 #2");
617 
618  /* Performs ParallelSync, by toggling GPIO7 */
619  Serial.println("\n7. Performing ParallelSync");
620  digitalWrite(7, HIGH); /* forces SYNC1 and SYNC2 high when REFIN is clocked */
621  delay(1); /* LTC6951 parallelsync must be > 1ms */
622  digitalWrite(7, LOW); /* forces SYNC1 and SYNC2 high when REFIN is clocked */
623 
624  Serial.println("\n7. Done!");
625  changeDC2430site(8); /* return to Manual Mode */
626 
627  } /* end of if (DC2430_Bin == 1) */
628 } /* end of DC2430_parallelsync_example */
629 
630 //! This function programs LTC6954-2 SPI registers.
631 //! such that all 3 channels of the LTC6954-2 are set to /1.
632 //! The LTC6954-2 frequency plan in this example matches that of the LTC6951
633 //! ParallelSYNC datasheet application.
634 //! @return void
636 {
637  uint8_t *rx;
638  uint8_t val_addr, val_reg;
639  uint8_t tx_input_array[7];
640 
641  /* Load initial register settings */
642  tx_input_array[0] = 0x00; //! addr 1, shift 1 bit to account for RW bit (W=0)
643  tx_input_array[1] = 0x80;
644  tx_input_array[2] = 0x00;
645  tx_input_array[3] = 0x80;
646  tx_input_array[4] = 0x00;
647  tx_input_array[5] = 0x80;
648  tx_input_array[6] = 0x00;
649 
650  digitalWrite(QUIKEVAL_CS, LOW);
651  val_addr = 0<<1; //! addr 0, shift 1 bit to account for RW bit (W=0)
652  *rx = SPI.transfer(val_addr); //! send ADDR2 byte
653 
654  for (i=0; i<7; i++)
655  {
656  *rx = SPI.transfer(tx_input_array[i]); //! send byte
657  }
658  digitalWrite(QUIKEVAL_CS, HIGH);
659 }
660 
661 //! Prog_LTC6951_parallelsync_example()
662 //! This function programs the LTC6951 registers for ParallelSYNC mode.
663 //! In ParallelSYNC mode:
664 //! step 1) program all LTC6951 registers
665 //! step 2) calibrate LTC6951 VCO
666 //! The LTC6951 frequency plan in this example matches that of the LTC6951
667 //! ParallelSYNC datasheet application.
668 //! Register settings in this function are identical to the LTC6951Wizard's set file,
669 //! "Datasheet Typical Applications/6951_ParallelSyncw6954.6951set”
670 //! @return void
672 {
673  uint8_t *rx;
674  uint8_t val_addr, val_reg;
675  uint8_t tx_input_array[19];
676 
677  /* Load initial register settings */
678  tx_input_array[0] = 1<<1; //! addr 1, shift 1 bit to account for RW bit (W=0)
679  tx_input_array[1] = 0xba;
680  tx_input_array[2] = 0x00;
681  tx_input_array[3] = 0x74;
682  tx_input_array[4] = 0xb3;
683  tx_input_array[5] = 0x04;
684  tx_input_array[6] = 0x02;
685  tx_input_array[7] = 0x07;
686  tx_input_array[8] = 0x00;
687  tx_input_array[9] = 0x14;
688  tx_input_array[10] = 0xc0;
689  tx_input_array[11] = 0x96;
690  tx_input_array[12] = 0x06;
691  tx_input_array[13] = 0x96;
692  tx_input_array[14] = 0x0c;
693  tx_input_array[15] = 0x96;
694  tx_input_array[16] = 0x06;
695  tx_input_array[17] = 0x30;
696  tx_input_array[18] = 0x00;
697 
698  digitalWrite(QUIKEVAL_CS, LOW);
699  for (i=0; i<19; i++)
700  {
701  *rx = SPI.transfer(tx_input_array[i]); //! send byte
702  }
703  digitalWrite(QUIKEVAL_CS, HIGH);
704  delay(1); /*wait just in case device hasn't let VCO settle - can decrease */
705 
706  /* toggle VCO cal bit */
707  digitalWrite(QUIKEVAL_CS, LOW);
708  val_addr = 2<<1; //! addr 2, shift 1 bit to account for RW bit (W=0)
709  *rx = SPI.transfer(val_addr); //! send ADDR2 byte
710  val_reg = 0x01; //! set cal bit high
711  *rx = SPI.transfer(val_reg); //! send ADDR2 REG byte
712  digitalWrite(QUIKEVAL_CS, HIGH);
713 
714 }
715 
716 /* ******************************************************************************************* */
717 //! DC2430 TEST SECTION
718 //! - ENABLED BY SELECTING 'A'
719 //! @return void
721 {
722  DC2430_Bin = 1;
723 
724  Serial.println(F("***************************"));
725  Serial.println(F("* START OF TEST *"));
726  Serial.println(F("***************************"));
727  if (DC2430_Bin==1)
729  if (DC2430_Bin==1)
731  if (DC2430_Bin==1)
733 
735  {
736  if (DC2430_Bin==1)
738  }
740  changeDC2430site(DC2430_testmode_ctr); // returns DC2430 to manual mode
741  Serial.print(F("Bin = "));
742  Serial.println(DC2430_Bin);
743 }
744 
745 //! Function to check DC2430 voltages generated from the EEVCC
746 //! and VCCIO Linduion supply voltages
747 //! @return void
749 {
750  int dc2430_Aval;
751  float dc2430_Aval_V0;
752  float dc2430_Aval_V1;
753  float dc2430_Aval_V2;
754 
755  Serial.println(F("\n *** Testing Linduino Supplies on DC2430A board ***"));
756 
757  // For DC2430 shield, when mated with a linduino boards:
758  // checks if DC2430 connected
759  // returns
760  // -9.99, if DC2430 not connected
761  // Measured VCCIO voltage, if DC2430 connected and Linduino's VCCIO (see Linduino JP3 jumper)
762  dc2430_Aval = analogRead(0); // measures DC2430 resistor divider, should be 3.33V
763  dc2430_Aval_V0 = (5.0*dc2430_Aval)/1023;
764 
765  dc2430_Aval = analogRead(1); // measures DC2430 resistor divider, should be 1.66V
766  dc2430_Aval_V1 = (5.0*dc2430_Aval)/1023;
767 
768  dc2430_Aval_V2=-9.99; // initialized to -9.99V, only reported if DC2430 not connected
769  if ((dc2430_Aval_V0>3.0) && (dc2430_Aval_V0<3.6) && (dc2430_Aval_V1>1.5) && (dc2430_Aval_V1<1.8))
770  {
771  Serial.println(F("PASS: EEVCC voltage = 5V"));
772  }
773  else
774  {
775  DC2430_Bin=2;
776  Serial.print(F("\n**** FAIL: EVCC voltage test "));
777  Serial.println(dc2430_Aval_V0);
778  Serial.println(dc2430_Aval_V1);
779  }
780 
781  if (DC2430_Bin == 1)
782  {
783  dc2430_Aval = analogRead(2); // measures VCCIO voltage (see Linduino JP3 jumper)
784  dc2430_Aval_V2 = (5.0*dc2430_Aval)/1023;
785  if ((dc2430_Aval_V2>3.0) && (dc2430_Aval_V2<3.6))
786  {
787  Serial.print(F("PASS: VCCIO voltage = "));
788  }
789  else
790  {
791  DC2430_Bin=3;
792  Serial.println(F("\nIs the DC2026C JP3 jumper set to the 3.3V location?"));
793  Serial.print(F("**** FAIL: VCCIO voltage = "));
794  }
795  Serial.println(dc2430_Aval_V2);
796  }
797  Serial.print(F("\n\0"));
798  Serial.flush();
799 }
800 
801 //! Function to verify that the DC2430 ref to sync circtuiry is functional
802 //! @return void
804 {
805  char command1, command2;
806  Serial.println(F("\n\n *** Testing DC2430 SYNC circuitry ***"));
807 
808  digitalWrite(7, LOW); /* forces SYNC1 and SYNC2 low when REFIN is clocked */
809  Serial.println(F("Measure output voltages at J21 (SYNC1) & J22 (SYNC2)"));
810  Serial.println(F("Are both voltages < 0.2V? [Y/N]"));
811  get_char();
812  command1 = get_char();
813  if (command1=='Y')
814  command1 = 'y';
815 
816  digitalWrite(7, HIGH); /* forces SYNC1 and SYNC2 high when REFIN is clocked */
817  Serial.println(F("Measure output voltages at J21 (SYNC1) & J22 (SYNC2)"));
818  Serial.println(F("Are both voltages > 3.1V and < 3.5V? [Y/N]"));
819  get_char();
820  command2 = get_char();
821  if (command2=='Y')
822  command2 = 'y';
823  digitalWrite(7, LOW); /* return to default state */
824 
825  if ((command1=='y') && (command2=='y'))
826  {
827  Serial.print(F("PASS: SYNC Test "));
828  }
829  else
830  {
831  DC2430_Bin=8;
832  Serial.print(F("**** FAIL: SYNC Test "));
833  }
834 }
835 
836 
837 
838 //! DC2430_test_swmode() - verified
839 //! - each site can be selected via softward
840 //! - EEPROM and SPI pins on the quick eval connectors work properly
841 //! @return void
843 {
844  char demo_name[] = "DC2248"; // Demo Board Name stored in QuikEval EEPROM
845  byte tx_data, rx_data;
846  uint8_t *rx;
847  uint8_t val_addr, val_reg;
848  uint8_t rx_data_array[5];
849  uint8_t tx_input_array[5];
850 
851  if (DC2430_testmode_ctr==0) Serial.println(F("\n\n *** Testing QuickEval Connectors ***"));
852 
853  /* set DC2430 to a site based on the DC2430_testmode_ctr number */
855 
856  Serial.print(F("\n>>>>>>>> Move Quickeval Connector to DC2430 connector J"));
857  Serial.println(DC2430_testmode_ctr);
858  Serial.println(F("Press Enter when complete"));
859  get_char();
860 
861  /* ***** THIS TEST THE EEPROM & EVCC CONNECTIONS OF THE DC2430 to the DC2248 ******** */
863  if (demo_board_connected==0)
864  {
865  DC2430_Bin=4;
866  Serial.print(F("\nEnsure a DC2248 is connected to DC2430 Connector J"));
867  Serial.println(DC2430_testmode_ctr);
868  Serial.print(F("**** FAIL: EEPROM I2C pins connector J"));
869  Serial.println(DC2430_testmode_ctr);
870  }
871  else
872  {
873  Serial.print(F("PASS: EEPROM I2C pins connecter J"));
874  Serial.println(DC2430_testmode_ctr);
875  } /* end of if(demo_board_connected==0) */
876 
877  /* ***** THIS TEST THE SPI & VCCIO CONNECTIONS OF THE DC2430 to the DC2248 ******** */
878  if (DC2430_Bin==1)
879  {
880  /* initially - select POR bit - gets LTC6951 to known state */
881  digitalWrite(QUIKEVAL_CS, LOW);
882  val_addr = 2<<1; //! addr 2, shift 1 bit to account for RW bit (W=0)
883  *rx = SPI.transfer(val_addr); //! send ADDR2 byte
884  val_reg= 0x02; //! send 0x02 - POR=1
885  *rx = SPI.transfer(val_reg); //! send ADDR2 reg - POR reset
886  digitalWrite(QUIKEVAL_CS, HIGH);
887  delay(50);
888 
889  /* force some values that ensure the read and write pins work appropriately */
890  tx_input_array[0] = 0x49;
891  tx_input_array[1] = 0x80; /* turns on LED - visual test in is in progress */
892  tx_input_array[2] = 0x00; /* power down register - all 0's */
893  tx_input_array[3] = 0xaa; /* alternate 1-0-1-0... */
894  tx_input_array[4] = 0x55; /* alternate 0-1-0-1... */
895 
896  digitalWrite(QUIKEVAL_CS, LOW);
897  val_addr = 1<<1; //! addr 1, shift 1 bit to account for RW bit (W=0)
898  *rx = SPI.transfer(val_addr); //! send ADDR1 byte
899  for (i=1; i<5; i++)
900  {
901  *rx = SPI.transfer(tx_input_array[i]); //! send byte
902  }
903  digitalWrite(QUIKEVAL_CS, HIGH);
904  delay(200);
905 
906  digitalWrite(QUIKEVAL_CS, LOW);
907  val_addr = 1 ; //! addr 3, shift 1 bit to account for RW bit (R=1)
908  *rx = SPI.transfer(val_addr); //! send ADDR3 byte
909  for (i=0; i<5; i++)
910  {
911  rx_data_array[i] = spi_read(0);
912  byte_to_hex(rx_data_array[i]);
913  /* this line compares the input values to the readback values */
914  if (tx_input_array[i]!=rx_data_array[i]) DC2430_Bin=5;
915  }
916  digitalWrite(QUIKEVAL_CS, HIGH);
917 
918  /* lastly - select POR bit - gets LTC6951 to known state - turns off LED */
919  digitalWrite(QUIKEVAL_CS, LOW);
920  val_addr = 2<<1; //! addr 2, shift 1 bit to account for RW bit (W=0)
921  *rx = SPI.transfer(val_addr); //! send ADDR2 byte
922  val_reg= 0x02; //! send 0x02 - POR=1
923  *rx = SPI.transfer(val_reg); //! send ADDR2 reg - POR reset
924  digitalWrite(QUIKEVAL_CS, HIGH);
925 
926  if (DC2430_Bin==5)
927  {
928  Serial.print(F("**** FAIL: SPI pins connector J"));
929  Serial.println(DC2430_testmode_ctr);
930  }
931  else
932  {
933  Serial.print(F("PASS: SPI pins connecter J"));
934  Serial.println(DC2430_testmode_ctr);
935  } /* end of if(DC2430_Bin==5) */
936  } /* end of if (DC2430_Bin==5) */
937 
938 } /* end of function */
939 
940 
941 //! DC2430_test_manualmode() - verified
942 //! - test site 2 (b010) and site 5 (b101)
943 //! - EEPROM and SPI pins on the quick eval connectors work properly
944 //! @return void
946 {
947  char demo_name[] = "DC2248"; // Demo Board Name stored in QuikEval EEPROM
948  int manual_site_selection;
949  int jj;
950  int did_not_follow_instructions;
951 
952  Serial.println(F("\n\n *** Testing Manual Switch (SW1) ***"));
953 
954  for (i=0; i<2; i++)
955  {
956  if (i==0) manual_site_selection=5; /* code 101 */
957  if (i==1) manual_site_selection=2; /* code 010 */
958 
959  did_not_follow_instructions=0;
960  jj=0;
961  do
962  {
963  if (jj>0) Serial.println("\n\n OOPS!!!!! - please read instructions");
964  Serial.print(F(">> STEP 1: Move Quickeval Connector to DC2430 connector J"));
965  Serial.println(manual_site_selection);
966  Serial.print(F(">> STEP 2: Turn SW1 so that LED by J"));
967  Serial.print(manual_site_selection);
968  Serial.println(F(" turns on"));
969  Serial.println(F("Press Enter when complete"));
970  if ((jj==0) && (i== 0)) get_char();
971  get_char();
972 
973  /* ***** THIS TEST THE EEPROM & EVCC CONNECTIONS OF THE DC2430 to the DC2248 ******** */
975 
976  /* this confirms the connector is at site 5 */
977  changeDC2430site(manual_site_selection); /* software site select */
979  changeDC2430site(9); /* disables software site select */
980  jj++;
981 
983  did_not_follow_instructions=1;
984 
985  }
986  while ((did_not_follow_instructions== 1) && (jj<2)); /* giving tester a couple chances to move quick eval connector */
987 
989  {
990  DC2430_Bin=6;
991  Serial.print(F("**** FAIL: Manual Switch Test - J"));
992  Serial.println(manual_site_selection);
993  }
994  else
995  {
996  Serial.print(F("PASS: Manual Switch Test - J"));
997  Serial.println(manual_site_selection);
998  } /* end of if(demo_board_connected==0) */
999  Serial.print("\n");
1000  } /* end of for loop */
1001 } /* end of function */
1002 
1003 
1004 
1005 //! Read the ID string from the EEPROM and determine if the correct board is connected.
1006 //! @return Returns 1 if successful, 0 if not successful
1008 {
1009  int8_t connected;
1010  connected = 1;
1011  // read the ID from the serial EEPROM on the board
1012  // reuse the buffer declared in UserInterface
1013  if (read_quikeval_id_string(&ui_buffer[0]) == 0) connected = 0;
1014 
1015  return(connected);
1016 }
1017 
1018 //! Function to set DC2430 to a site based on the DC2430_testmode_ctr number
1019 //! @return void
1020 void changeDC2430site(int site_select)
1021 {
1022  switch (site_select)
1023  {
1024  case 0:
1025  digitalWrite(5, HIGH); // EN
1026  digitalWrite(4, LOW); // DA2
1027  digitalWrite(3, LOW); // DA1
1028  digitalWrite(2, LOW); // DA0;
1029  break;
1030 
1031  case 1:
1032  digitalWrite(5, HIGH); // EN
1033  digitalWrite(4, LOW); // DA2
1034  digitalWrite(3, LOW); // DA1
1035  digitalWrite(2, HIGH); // DA0;
1036  break;
1037 
1038  case 2:
1039  digitalWrite(5, HIGH); // EN
1040  digitalWrite(4, LOW); // DA2
1041  digitalWrite(3, HIGH); // DA1
1042  digitalWrite(2, LOW); // DA0;
1043  break;
1044 
1045  case 3:
1046  digitalWrite(5, HIGH); // EN
1047  digitalWrite(4, LOW); // DA2
1048  digitalWrite(3, HIGH); // DA1
1049  digitalWrite(2, HIGH); // DA0;
1050  break;
1051 
1052  case 4:
1053  digitalWrite(5, HIGH); // EN
1054  digitalWrite(4, HIGH); // DA2
1055  digitalWrite(3, LOW); // DA1
1056  digitalWrite(2, LOW); // DA0;
1057  break;
1058 
1059  case 5:
1060  digitalWrite(5, HIGH); // EN
1061  digitalWrite(4, HIGH); // DA2
1062  digitalWrite(3, LOW); // DA1
1063  digitalWrite(2, HIGH); // DA0;
1064  break;
1065 
1066  case 6:
1067  digitalWrite(5, HIGH); // EN
1068  digitalWrite(4, HIGH); // DA2
1069  digitalWrite(3, HIGH); // DA1
1070  digitalWrite(2, LOW); // DA0;
1071  break;
1072 
1073  case 7:
1074  digitalWrite(5, HIGH); // EN
1075  digitalWrite(4, HIGH); // DA2
1076  digitalWrite(3, HIGH); // DA1
1077  digitalWrite(2, HIGH); // DA0;
1078  break;
1079 
1080  default:
1081  digitalWrite(5, LOW); // EN
1082  digitalWrite(4, LOW); // DA2
1083  digitalWrite(3, LOW); // DA1
1084  digitalWrite(2, LOW); // DA0;
1085  break;
1086  } /* end of case */
1087  delay(10);
1088 }
char id_string[51]
Definition: DC2430A.ino:115
char recording_buffer[RECORDING_SIZE]
Definition: DC2430A.ino:124
static int DC2430_testmode_ctr
Definition: DC2430A.ino:88
char hex_to_byte_buffer[5]
Definition: DC2430A.ino:116
const byte i2c_auxiliary_mode
Definition: DC2430A.ino:101
byte read_hex()
Definition: DC2430A.ino:140
static void DC2430_test_manualmode()
DC2430_test_manualmode() - verified.
Definition: DC2430A.ino:945
#define output_high(pin)
Set "pin" high.
Definition: Linduino.h:75
static int8_t demo_board_connected
Demo Board Name stored in QuikEval EEPROM.
Definition: DC2430A.ino:90
const byte spi_mode
Definition: DC2430A.ino:99
static void Prog_LTC6954_parallelsync_example()
This function programs LTC6954-2 SPI registers.
Definition: DC2430A.ino:635
char byte_to_hex_buffer[3]
Definition: DC2430A.ino:120
Header File for Linduino Libraries and Demo Code.
byte recording_mode
Definition: DC2430A.ino:114
void spi_write(int8_t data)
Write a data byte using the SPI hardware.
Definition: LT_SPI.cpp:176
static void byte_to_hex(byte value)
Definition: DC2430A.ino:132
static void changeDC2430site(int site_select)
Function to set DC2430 to a site based on the DC2430_testmode_ctr number.
Definition: DC2430A.ino:1020
const char spi_divider
Definition: DC2430A.ino:110
static int32_t connected
Definition: CN-0413.ino:69
void i2c_stop()
Write stop bit to the hardware I2C port.
Definition: LT_I2C.cpp:462
static void DC2430_testprog()
DC2430 TEST SECTION.
Definition: DC2430A.ino:720
byte recording_index
Definition: DC2430A.ino:128
const byte playback
Definition: DC2430A.ino:96
static void DC2430_test_supply()
Function to check DC2430 voltages generated from the EEVCC and VCCIO Linduion supply voltages...
Definition: DC2430A.ino:748
int8_t i2c_start()
Write start bit to the hardware I2C port.
Definition: LT_I2C.cpp:425
#define RECORDING_SIZE
Definition: DC2430A.ino:94
static void loop()
Repeats Linduino loop.
Definition: DC2430A.ino:221
union LT_union_int32_4bytes data
Definition: DC2094A.ino:138
#define WITH_NACK
Use with i2c_read(WITH_NACK) to read without an acknowledge.
Definition: LT_I2C.h:91
unsigned char pseudo_reset
Definition: DC2430A.ino:185
static void DC2430_test_swmode()
DC2430_test_swmode() - verified.
Definition: DC2430A.ino:842
static void setup()
Initialize Linduino.
Definition: DC2430A.ino:189
#define QUIKEVAL_GPIO
Linduino QuikEval GPIO pin (QuikEval connector pin 14) connects to Arduino pin 9. ...
Definition: Linduino.h:56
byte serial_mode
Definition: DC2430A.ino:113
int8_t i2c_write(uint8_t data)
Send a data byte to hardware I2C port.
Definition: LT_I2C.cpp:470
#define output_low(pin)
Set "pin" low.
Definition: Linduino.h:72
QuikEval EEPROM Library.
#define input(pin)
Return the state of pin "pin".
Definition: Linduino.h:79
char get_char()
Definition: DC2430A.ino:151
void quikeval_SPI_init(void)
Configure the SPI port for 4Mhz SCK.
Definition: LT_SPI.cpp:151
static int DC2430_Bin
Definition: DC2430A.ino:89
int8_t discover_demo_board(char *demo_name)
Read the ID string from the EEPROM and determine if the correct board is connected.
static int8_t discover_demo_board_local(char *demo_name)
Read the ID string from the EEPROM and determine if the correct board is connected.
Definition: DC2430A.ino:1007
LT_SPI: Routines to communicate with ATmega328P&#39;s hardware SPI port.
LT_I2C: Routines to communicate with ATmega328P&#39;s hardware I2C port.
char hex_digits[16]
Definition: DC2430A.ino:104
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
int8_t spi_read(int8_t data)
The data byte to be written.
Definition: LT_SPI.cpp:189
static void DC2430_parallelsync_example()
DC2430 PARALLELSYNC EXAMPLE: SOFTWARE SITE SELECTION MODE.
Definition: DC2430A.ino:573
uint8_t i2c_read(int8_t ack)
Read a data byte from the hardware I2C port.
Definition: LT_I2C.cpp:491
static void DC2430_test_SYNC()
Function to verify that the DC2430 ref to sync circtuiry is functional.
Definition: DC2430A.ino:803
void quikeval_I2C_init(void)
Initializes Linduino I2C port.
Definition: LT_I2C.cpp:394
static void Prog_LTC6951_parallelsync_example()
Prog_LTC6951_parallelsync_example() This function programs the LTC6951 registers for ParallelSYNC mod...
Definition: DC2430A.ino:671
void quikeval_I2C_connect(void)
Switch MUX to connect I2C pins to QuikEval connector.
Definition: LT_I2C.cpp:401
static int i
Definition: DC2430A.ino:184
#define WITH_ACK
Use with i2c_read(WITH_ACK) to read with an acknowledge.
Definition: LT_I2C.h:90
#define MISO_TIMEOUT
Definition: DC2430A.ino:85
#define QUIKEVAL_CS
QuikEval CS pin (SPI chip select on QuikEval connector pin 6) connects to Arduino SS pin...
Definition: Linduino.h:57
uint8_t read_quikeval_id_string(char *buffer)
Read the id string from the EEPROM, then parse the product name, demo board name, and demo board opti...
char ui_buffer[UI_BUFFER_SIZE]
const byte off
Definition: DC2430A.ino:95
const byte i2c_mode
Definition: DC2430A.ino:100
static int8_t demo_board_connected_man
Demo Board Name stored in QuikEval EEPROM.
Definition: DC2430A.ino:91