| 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
88 int DC2430_testmode_ctr = 0;
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
116 char hex_to_byte_buffer[5]=
117 {
118 '0', 'x', '0', '0', '\0'
119 }; // buffer for ASCII hex to byte conversion
120 char byte_to_hex_buffer[3]=
121 {
122 '\0','\0','\0'
123 }; // buffer for byte to ASCII hex conversion
124 char recording_buffer[RECORDING_SIZE]=
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;
145 hex_to_byte_buffer[2]=get_char();
146 hex_to_byte_buffer[3]=get_char();
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
165 if (recording_index < RECORDING_SIZE)
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;
179 recording_mode = off;
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
211 quikeval_SPI_init();
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':
242 DC2430_parallelsync_example();
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
253 output_low(QUIKEVAL_GPIO);
254 break;
255 case 'G':
256 // IO pin high
257 output_high(QUIKEVAL_GPIO);
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
372 serial_mode = i2c_mode;
373 // enable_main_I2C();
374 quikeval_I2C_connect();
375 break;
376 case 'S':
377 // spi mode
378 serial_mode = spi_mode;
379 // Need to send command to disable LTC4302
380 // enable_main_SPI();
381 quikeval_SPI_connect();
382 break;
383 case 'X': // axillary I2C mode - no hardware action necessary, always available.
384 serial_mode = i2c_auxiliary_mode;
385 quikeval_SPI_connect();
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();
480 if (serial_mode == i2c_auxiliary_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 {
504 recording_buffer[recording_index]='\0';
505 recording_index = 0;
506 break;
507 }
508 else // add character to recording buffer
509 {
510 if (recording_index < RECORDING_SIZE) recording_buffer[recording_index++]=command;
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':
528 recording_mode = playback;
529 break;
530 case 'x':
531 output_low(QUIKEVAL_CS);
532 break;
533 case 'X':
534 output_high(QUIKEVAL_CS);
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
573 void DC2430_parallelsync_example()
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 */
581 DC2430_test_supply();
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);
589 demo_board_connected = discover_demo_board(demo_name1);
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");
594 Prog_LTC6954_parallelsync_example();
595
596 /* selects DC2430 J6 site */
597 Serial.println("\n3. Setting DC2430 to J6 site");
598 changeDC2430site(6);
599 // delay(5);
600 demo_board_connected = discover_demo_board(demo_name2);
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");
605 Prog_LTC6951_parallelsync_example();
606
607 /* selects DC2430 J7 site */
608 Serial.println("\n5. Setting DC2430 to J7 site");
609 changeDC2430site(7);
610 // delay(5);
611 demo_board_connected = discover_demo_board(demo_name2);
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");
616 Prog_LTC6951_parallelsync_example();
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
635 void Prog_LTC6954_parallelsync_example()
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
671 void Prog_LTC6951_parallelsync_example()
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
720 void DC2430_testprog()
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)
728 DC2430_test_supply();
729 if (DC2430_Bin==1)
730 DC2430_test_SYNC();
731 if (DC2430_Bin==1)
732 DC2430_test_manualmode();
733
734 for (DC2430_testmode_ctr=0; DC2430_testmode_ctr<8; DC2430_testmode_ctr++)
735 {
736 if (DC2430_Bin==1)
737 DC2430_test_swmode();
738 }
739 DC2430_testmode_ctr++;
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
748 void DC2430_test_supply()
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
803 void DC2430_test_SYNC()
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
842 void DC2430_test_swmode()
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 */
854 changeDC2430site(DC2430_testmode_ctr);
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 ******** */
862 demo_board_connected = discover_demo_board_local(demo_name);
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
945 void DC2430_test_manualmode()
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 ******** */
974 demo_board_connected_man = discover_demo_board_local(demo_name);
975
976 /* this confirms the connector is at site 5 */
977 changeDC2430site(manual_site_selection); /* software site select */
978 demo_board_connected = discover_demo_board_local(demo_name);
979 changeDC2430site(9); /* disables software site select */
980 jj++;
981
982 if ((demo_board_connected==0) || ((demo_board_connected_man==0) && (demo_board_connected==1)) )
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
988 if ((demo_board_connected_man==0) || (demo_board_connected==0))
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
1007 int8_t discover_demo_board_local(char *demo_name)
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 }
id_string
char id_string[51]
Definition: DC2430A.ino:115
recording_buffer
char recording_buffer[RECORDING_SIZE]
Definition: DC2430A.ino:124
DC2430_testmode_ctr
static int DC2430_testmode_ctr
Definition: DC2430A.ino:88
hex_to_byte_buffer
char hex_to_byte_buffer[5]
Definition: DC2430A.ino:116
i2c_auxiliary_mode
const byte i2c_auxiliary_mode
Definition: DC2430A.ino:101
read_hex
byte read_hex()
Definition: DC2430A.ino:140
DC2430_test_manualmode
static void DC2430_test_manualmode()
DC2430_test_manualmode() - verified.
Definition: DC2430A.ino:945
output_high
#define output_high(pin)
Set "pin" high.
Definition: Linduino.h:75
demo_board_connected
static int8_t demo_board_connected
Demo Board Name stored in QuikEval EEPROM.
Definition: DC2430A.ino:90
spi_mode
const byte spi_mode
Definition: DC2430A.ino:99
Prog_LTC6954_parallelsync_example
static void Prog_LTC6954_parallelsync_example()
This function programs LTC6954-2 SPI registers.
Definition: DC2430A.ino:635
byte_to_hex_buffer
char byte_to_hex_buffer[3]
Definition: DC2430A.ino:120
Linduino.h
Header File for Linduino Libraries and Demo Code.
recording_mode
byte recording_mode
Definition: DC2430A.ino:114
spi_write
void spi_write(int8_t data)
Write a data byte using the SPI hardware.
Definition: LT_SPI.cpp:176
byte_to_hex
static void byte_to_hex(byte value)
Definition: DC2430A.ino:132
changeDC2430site
static void changeDC2430site(int site_select)
Function to set DC2430 to a site based on the DC2430_testmode_ctr number.
Definition: DC2430A.ino:1020
spi_divider
const char spi_divider
Definition: DC2430A.ino:110
connected
static int32_t connected
Definition: CN-0413.ino:69
i2c_stop
void i2c_stop()
Write stop bit to the hardware I2C port.
Definition: LT_I2C.cpp:462
DC2430_testprog
static void DC2430_testprog()
DC2430 TEST SECTION.
Definition: DC2430A.ino:720
recording_index
byte recording_index
Definition: DC2430A.ino:128
playback
const byte playback
Definition: DC2430A.ino:96
DC2430_test_supply
static void DC2430_test_supply()
Function to check DC2430 voltages generated from the EEVCC and VCCIO Linduion supply voltages...
Definition: DC2430A.ino:748
i2c_start
int8_t i2c_start()
Write start bit to the hardware I2C port.
Definition: LT_I2C.cpp:425
RECORDING_SIZE
#define RECORDING_SIZE
Definition: DC2430A.ino:94
loop
static void loop()
Repeats Linduino loop.
Definition: DC2430A.ino:221
data
union LT_union_int32_4bytes data
Definition: DC2094A.ino:138
WITH_NACK
#define WITH_NACK
Use with i2c_read(WITH_NACK) to read without an acknowledge.
Definition: LT_I2C.h:91
pseudo_reset
unsigned char pseudo_reset
Definition: DC2430A.ino:185
DC2430_test_swmode
static void DC2430_test_swmode()
DC2430_test_swmode() - verified.
Definition: DC2430A.ino:842
setup
static void setup()
Initialize Linduino.
Definition: DC2430A.ino:189
QUIKEVAL_GPIO
#define QUIKEVAL_GPIO
Linduino QuikEval GPIO pin (QuikEval connector pin 14) connects to Arduino pin 9. ...
Definition: Linduino.h:56
serial_mode
byte serial_mode
Definition: DC2430A.ino:113
i2c_write
int8_t i2c_write(uint8_t data)
Send a data byte to hardware I2C port.
Definition: LT_I2C.cpp:470
output_low
#define output_low(pin)
Set "pin" low.
Definition: Linduino.h:72
QuikEval_EEPROM.h
QuikEval EEPROM Library.
input
#define input(pin)
Return the state of pin "pin".
Definition: Linduino.h:79
get_char
char get_char()
Definition: DC2430A.ino:151
quikeval_SPI_init
void quikeval_SPI_init(void)
Configure the SPI port for 4Mhz SCK.
Definition: LT_SPI.cpp:151
DC2430_Bin
static int DC2430_Bin
Definition: DC2430A.ino:89
discover_demo_board
int8_t discover_demo_board(char *demo_name)
Read the ID string from the EEPROM and determine if the correct board is connected.
Definition: QuikEval_EEPROM.cpp:141
discover_demo_board_local
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.h
LT_SPI: Routines to communicate with ATmega328P&#39;s hardware SPI port.
LT_I2C.h
LT_I2C: Routines to communicate with ATmega328P&#39;s hardware I2C port.
hex_digits
char hex_digits[16]
Definition: DC2430A.ino:104
demo_name
char demo_name[]
Demo Board Name stored in QuikEval EEPROM.
Definition: DC1880A.ino:97
quikeval_SPI_connect
void quikeval_SPI_connect()
Connect SPI pins to QuikEval connector through the Linduino MUX. This will disconnect I2C...
Definition: LT_SPI.cpp:138
UserInterface.h
spi_read
int8_t spi_read(int8_t data)
The data byte to be written.
Definition: LT_SPI.cpp:189
DC2430_parallelsync_example
static void DC2430_parallelsync_example()
DC2430 PARALLELSYNC EXAMPLE: SOFTWARE SITE SELECTION MODE.
Definition: DC2430A.ino:573
i2c_read
uint8_t i2c_read(int8_t ack)
Read a data byte from the hardware I2C port.
Definition: LT_I2C.cpp:491
DC2430_test_SYNC
static void DC2430_test_SYNC()
Function to verify that the DC2430 ref to sync circtuiry is functional.
Definition: DC2430A.ino:803
quikeval_I2C_init
void quikeval_I2C_init(void)
Initializes Linduino I2C port.
Definition: LT_I2C.cpp:394
Prog_LTC6951_parallelsync_example
static void Prog_LTC6951_parallelsync_example()
Prog_LTC6951_parallelsync_example() This function programs the LTC6951 registers for ParallelSYNC mod...
Definition: DC2430A.ino:671
quikeval_I2C_connect
void quikeval_I2C_connect(void)
Switch MUX to connect I2C pins to QuikEval connector.
Definition: LT_I2C.cpp:401
i
static int i
Definition: DC2430A.ino:184
WITH_ACK
#define WITH_ACK
Use with i2c_read(WITH_ACK) to read with an acknowledge.
Definition: LT_I2C.h:90
MISO_TIMEOUT
#define MISO_TIMEOUT
Definition: DC2430A.ino:85
QUIKEVAL_CS
#define QUIKEVAL_CS
QuikEval CS pin (SPI chip select on QuikEval connector pin 6) connects to Arduino SS pin...
Definition: Linduino.h:57
read_quikeval_id_string
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...
Definition: QuikEval_EEPROM.cpp:77
ui_buffer
char ui_buffer[UI_BUFFER_SIZE]
Definition: UserInterface.cpp:46
off
const byte off
Definition: DC2430A.ino:95
i2c_mode
const byte i2c_mode
Definition: DC2430A.ino:100
demo_board_connected_man
static int8_t demo_board_connected_man
Demo Board Name stored in QuikEval EEPROM.
Definition: DC2430A.ino:91