3 * Martin Krause, TQ-Systems GmbH, martin.krause@tqs.de
5 * See file CREDITS for list of people who contributed to this
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
28 #include <timestamp.h>
34 * define, to wait for the touch to be pressed, before reading coordinates in
35 * command do_touch. If not defined, an error message is printed, when the
36 * command do_touch is invoked and the touch is not pressed within an specific
39 #undef CONFIG_TOUCH_WAIT_PRESSED
41 /* max time to wait for touch is pressed */
42 #ifndef CONFIG_TOUCH_WAIT_PRESSED
43 #define TOUCH_TIMEOUT 5
44 #endif /* !CONFIG_TOUCH_WAIT_PRESSED */
46 /* assignment of CPU internal ADC channels with TRAB hardware */
50 /* CPLD-Register for controlling TRAB hardware functions */
51 #define CPLD_BUTTONS ((volatile unsigned long *)0x04020000)
52 #define CPLD_FILL_LEVEL ((volatile unsigned long *)0x04008000)
53 #define CPLD_ROTARY_SWITCH ((volatile unsigned long *)0x04018000)
54 #define CPLD_RS485_RE ((volatile unsigned long *)0x04028000)
56 /* timer configuration bits for buzzer and PWM */
57 #define START2 (1 << 12)
58 #define UPDATE2 (1 << 13)
59 #define INVERT2 (1 << 14)
60 #define RELOAD2 (1 << 15)
61 #define START3 (1 << 16)
62 #define UPDATE3 (1 << 17)
63 #define INVERT3 (1 << 18)
64 #define RELOAD3 (1 << 19)
67 #define BUZZER_FREQ 1000 /* frequency in Hz */
71 /* definitions of I2C EEPROM device address */
72 #define I2C_EEPROM_DEV_ADDR 0x54
74 /* definition for touch panel calibration points */
75 #define CALIB_TL 0 /* calibration point in (T)op (L)eft corner */
76 #define CALIB_DR 1 /* calibration point in (D)own (R)ight corner */
78 /* EEPROM address map */
79 #define SERIAL_NUMBER 8
87 #define EEPROM_MAX_CRC_BUF 64
90 #define RS485_MAX_RECEIVE_BUF_LEN 100
92 /* Bit definitions for ADCCON */
93 #define ADC_ENABLE_START 0x1
94 #define ADC_READ_START 0x2
96 #define ADC_INP_AIN0 (0x0 << 3)
97 #define ADC_INP_AIN1 (0x1 << 3)
98 #define ADC_INP_AIN2 (0x2 << 3)
99 #define ADC_INP_AIN3 (0x3 << 3)
100 #define ADC_INP_AIN4 (0x4 << 3)
101 #define ADC_INP_AIN5 (0x5 << 3)
102 #define ADC_INP_AIN6 (0x6 << 3)
103 #define ADC_INP_AIN7 (0x7 << 3)
104 #define ADC_PRSCEN 0x4000
105 #define ADC_ECFLG 0x8000
107 /* function test functions */
111 int do_vcc12v (void);
112 int do_buttons (void);
113 int do_fill_level (void);
114 int do_rotary_switch (void);
115 int do_pressure (void);
117 int do_vfd_id (void);
118 int do_buzzer (char **);
119 int do_led (char **);
120 int do_full_bridge (char **);
121 int do_dac (char **);
122 int do_motor_contact (void);
123 int do_motor (char **);
124 int do_pwm (char **);
125 int do_thermo (char **);
126 int do_touch (char **);
127 int do_rs485 (char **);
128 int do_serial_number (char **);
130 int do_power_switch (void);
131 int do_gain (char **);
132 int do_eeprom (char **);
134 /* helper functions */
135 static void adc_init (void);
136 static int adc_read (unsigned int channel);
137 static void print_identifier (void);
139 #ifdef CONFIG_TOUCH_WAIT_PRESSED
140 static void touch_wait_pressed (void);
142 static int touch_check_pressed (void);
143 #endif /* CONFIG_TOUCH_WAIT_PRESSED */
145 static void touch_read_x_y (int *x, int *y);
146 static int touch_write_clibration_values (int calib_point, int x, int y);
147 static int rs485_send_line (const char *data);
148 static int rs485_receive_chars (char *data, int timeout);
149 static unsigned short updcrc(unsigned short icrc, unsigned char *icp,
152 #if defined(CONFIG_CMD_I2C)
153 static int trab_eeprom_read (char **argv);
154 static int trab_eeprom_write (char **argv);
155 int i2c_write_multiple (uchar chip, uint addr, int alen, uchar *buffer,
157 int i2c_read_multiple ( uchar chip, uint addr, int alen, uchar *buffer,
162 * TRAB board specific commands. Especially commands for burn-in and function
166 int trab_fkt (int argc, char *argv[])
171 if (get_version () != XF_VERSION) {
172 printf ("Wrong XF_VERSION. Please re-compile with actual "
174 printf ("Example expects ABI version %d\n", XF_VERSION);
175 printf ("Actual U-Boot ABI version %d\n", (int)get_version());
179 debug ("argc = %d\n", argc);
181 for (i=0; i<=argc; ++i) {
182 debug ("argv[%d] = \"%s\"\n", i, argv[i] ? argv[i] : "<NULL>");
194 if (strcmp (argv[1], "info") == 0) {
197 if (strcmp (argv[1], "dip") == 0) {
200 if (strcmp (argv[1], "vcc5v") == 0) {
201 return (do_vcc5v ());
203 if (strcmp (argv[1], "vcc12v") == 0) {
204 return (do_vcc12v ());
206 if (strcmp (argv[1], "buttons") == 0) {
207 return (do_buttons ());
209 if (strcmp (argv[1], "fill_level") == 0) {
210 return (do_fill_level ());
212 if (strcmp (argv[1], "rotary_switch") == 0) {
213 return (do_rotary_switch ());
215 if (strcmp (argv[1], "pressure") == 0) {
216 return (do_pressure ());
218 if (strcmp (argv[1], "v_bat") == 0) {
219 return (do_v_bat ());
221 if (strcmp (argv[1], "vfd_id") == 0) {
222 return (do_vfd_id ());
224 if (strcmp (argv[1], "motor_contact") == 0) {
225 return (do_motor_contact ());
227 if (strcmp (argv[1], "crc16") == 0) {
228 return (do_crc16 ());
230 if (strcmp (argv[1], "power_switch") == 0) {
231 return (do_power_switch ());
236 if (strcmp (argv[1], "full_bridge") == 0) {
237 return (do_full_bridge (argv));
239 if (strcmp (argv[1], "dac") == 0) {
240 return (do_dac (argv));
242 if (strcmp (argv[1], "motor") == 0) {
243 return (do_motor (argv));
245 if (strcmp (argv[1], "pwm") == 0) {
246 return (do_pwm (argv));
248 if (strcmp (argv[1], "thermo") == 0) {
249 return (do_thermo (argv));
251 if (strcmp (argv[1], "touch") == 0) {
252 return (do_touch (argv));
254 if (strcmp (argv[1], "serial_number") == 0) {
255 return (do_serial_number (argv));
257 if (strcmp (argv[1], "buzzer") == 0) {
258 return (do_buzzer (argv));
260 if (strcmp (argv[1], "gain") == 0) {
261 return (do_gain (argv));
266 if (strcmp (argv[1], "led") == 0) {
267 return (do_led (argv));
269 if (strcmp (argv[1], "rs485") == 0) {
270 return (do_rs485 (argv));
272 if (strcmp (argv[1], "serial_number") == 0) {
273 return (do_serial_number (argv));
278 if (strcmp (argv[1], "eeprom") == 0) {
279 return (do_eeprom (argv));
284 if (strcmp (argv[1], "eeprom") == 0) {
285 return (do_eeprom (argv));
293 printf ("Usage:\n<command> <parameter1> <parameter2> ...\n");
299 printf ("Stand-alone application for TRAB board function test\n");
300 printf ("Built: %s at %s\n", U_BOOT_DATE, U_BOOT_TIME);
307 unsigned int result = 0;
311 /***********************************************************
312 DIP switch connection (according to wa4-cpu.sp.301.pdf, page 3):
318 "On" DIP switch position short-circuits the voltage from
319 the input channel (i.e. '0' conversion result means "on").
320 *************************************************************/
322 for (i = 7; i > 3; i--) {
324 if ((adc_val = adc_read (i)) == -1) {
325 printf ("Channel %d could not be read\n", i);
330 * Input voltage (switch open) is 1.8 V.
331 * (Vin_High/VRef)*adc_res = (1,8V/2,5V)*1023) = 736
332 * Set trigger at halve that value.
335 result |= (1 << (i-4));
338 /* print result to console */
340 for (i = 0; i < 4; i++) {
341 if ((result & (1 << i)) == 0)
356 /* VCC5V is connected to channel 2 */
358 if ((result = adc_read (VCC5V)) == -1) {
359 printf ("VCC5V could not be read\n");
364 * Calculate voltage value. Split in two parts because there is no
365 * floating point support. VCC5V is connected over an resistor divider:
366 * VCC5V=ADCval*2,5V/1023*(10K+30K)/10K.
369 printf ("%d", (result & 0x3FF)* 10 / 1023);
370 printf (".%d", ((result & 0x3FF)* 10 % 1023)* 10 / 1023);
371 printf ("%d V\n", (((result & 0x3FF) * 10 % 1023 ) * 10 % 1023)
382 if ((result = adc_read (VCC12V)) == -1) {
383 printf ("VCC12V could not be read\n");
388 * Calculate voltage value. Split in two parts because there is no
389 * floating point support. VCC5V is connected over an resistor divider:
390 * VCC12V=ADCval*2,5V/1023*(30K+270K)/30K.
393 printf ("%d", (result & 0x3FF)* 25 / 1023);
394 printf (".%d V\n", ((result & 0x3FF)* 25 % 1023) * 10 / 1023);
399 static int adc_read (unsigned int channel)
401 int j = 1000; /* timeout value for wait loop in us */
405 padc = S3C2400_GetBase_ADC();
408 padc->ADCCON &= ~ADC_STDBM; /* select normal mode */
409 padc->ADCCON &= ~(0x7 << 3); /* clear the channel bits */
410 padc->ADCCON |= ((channel << 3) | ADC_ENABLE_START);
413 if ((padc->ADCCON & ADC_ENABLE_START) == 0)
419 printf("%s: ADC timeout\n", __FUNCTION__);
420 padc->ADCCON |= ADC_STDBM; /* select standby mode */
424 result = padc->ADCDAT & 0x3FF;
426 padc->ADCCON |= ADC_STDBM; /* select standby mode */
428 debug ("%s: channel %d, result[DIGIT]=%d\n", __FUNCTION__,
429 (padc->ADCCON >> 3) & 0x7, result);
432 * Wait for ADC to be ready for next conversion. This delay value was
433 * estimated, because the datasheet does not specify a value.
441 static void adc_init (void)
445 padc = S3C2400_GetBase_ADC();
447 padc->ADCCON &= ~(0xff << 6); /* clear prescaler bits */
448 padc->ADCCON |= ((65 << 6) | ADC_PRSCEN); /* set prescaler */
451 * Wait some time to avoid problem with very first call of
452 * adc_read(). Without * this delay, sometimes the first read adc
453 * value is 0. Perhaps because the * adjustment of prescaler takes
462 int do_buttons (void)
467 result = *CPLD_BUTTONS; /* read CPLD */
468 debug ("%s: cpld_taster (32 bit) %#x\n", __FUNCTION__, result);
470 /* print result to console */
472 for (i = 16; i <= 19; i++) {
473 if ((result & (1 << i)) == 0)
483 int do_power_switch (void)
487 S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
489 /* configure GPE7 as input */
490 gpio->PECON &= ~(0x3 << (2 * 7));
492 /* signal GPE7 from power switch is low active: 0=on , 1=off */
493 result = ((gpio->PEDAT & (1 << 7)) == (1 << 7)) ? 0 : 1;
496 printf("%d\n", result);
501 int do_fill_level (void)
505 result = *CPLD_FILL_LEVEL; /* read CPLD */
506 debug ("%s: cpld_fuellstand (32 bit) %#x\n", __FUNCTION__, result);
508 /* print result to console */
510 if ((result & (1 << 16)) == 0)
518 int do_rotary_switch (void)
522 * Please note, that the default values of the direction bits are
523 * undefined after reset. So it is a good idea, to make first a dummy
524 * call to this function, to clear the direction bits and set so to
528 result = *CPLD_ROTARY_SWITCH; /* read CPLD */
529 debug ("%s: cpld_inc (32 bit) %#x\n", __FUNCTION__, result);
531 *CPLD_ROTARY_SWITCH |= (3 << 16); /* clear direction bits in CPLD */
533 /* print result to console */
535 if ((result & (1 << 16)) == (1 << 16))
537 if ((result & (1 << 17)) == (1 << 17))
539 if (((result & (1 << 16)) == 0) && ((result & (1 << 17)) == 0))
541 if ((result & (1 << 18)) == 0)
552 long int pcup_old, pccon_old;
554 S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
556 /* try to red vfd board id from the value defined by pull-ups */
558 pcup_old = gpio->PCUP;
559 pccon_old = gpio->PCCON;
561 gpio->PCUP = (gpio->PCUP & 0xFFF0); /* activate GPC0...GPC3 pull-ups */
562 gpio->PCCON = (gpio->PCCON & 0xFFFFFF00); /* configure GPC0...GPC3 as
564 udelay (10); /* allow signals to settle */
565 vfd_board_id = (~gpio->PCDAT) & 0x000F; /* read GPC0...GPC3 port pins */
567 gpio->PCCON = pccon_old;
568 gpio->PCUP = pcup_old;
570 /* print vfd_board_id to console */
572 for (i = 0; i < 4; i++) {
573 if ((vfd_board_id & (1 << i)) == 0)
582 int do_buzzer (char **argv)
586 S3C24X0_TIMERS * const timers = S3C24X0_GetBase_TIMERS();
587 S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
589 /* set prescaler for timer 2, 3 and 4 */
590 timers->TCFG0 &= ~0xFF00;
591 timers->TCFG0 |= 0x0F00;
593 /* set divider for timer 2 */
594 timers->TCFG1 &= ~0xF00;
595 timers->TCFG1 |= 0x300;
598 counter = (PCLK / BUZZER_FREQ) >> 9;
599 timers->ch[2].TCNTB = counter;
600 timers->ch[2].TCMPB = counter / 2;
602 if (strcmp (argv[2], "on") == 0) {
603 debug ("%s: frequency: %d\n", __FUNCTION__,
606 /* configure pin GPD7 as TOUT2 */
607 gpio->PDCON &= ~0xC000;
608 gpio->PDCON |= 0x8000;
611 timers->TCON = (timers->TCON | UPDATE2 | RELOAD2) &
613 timers->TCON = (timers->TCON | START2) & ~UPDATE2;
616 else if (strcmp (argv[2], "off") == 0) {
618 timers->TCON &= ~(START2 | RELOAD2);
620 /* configure GPD7 as output and set to low */
621 gpio->PDCON &= ~0xC000;
622 gpio->PDCON |= 0x4000;
623 gpio->PDDAT &= ~0x80;
627 printf ("%s: invalid parameter %s\n", __FUNCTION__, argv[2]);
632 int do_led (char **argv)
634 S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
636 /* configure PC14 and PC15 as output */
637 gpio->PCCON &= ~(0xF << 28);
638 gpio->PCCON |= (0x5 << 28);
640 /* configure PD0 and PD4 as output */
641 gpio->PDCON &= ~((0x3 << 8) | 0x3);
642 gpio->PDCON |= ((0x1 << 8) | 0x1);
644 switch (simple_strtoul(argv[2], NULL, 10)) {
651 if (strcmp (argv[3], "on") == 0)
652 gpio->PCDAT |= (1 << 14);
654 gpio->PCDAT &= ~(1 << 14);
658 if (strcmp (argv[3], "on") == 0)
659 gpio->PCDAT |= (1 << 15);
661 gpio->PCDAT &= ~(1 << 15);
665 if (strcmp (argv[3], "on") == 0)
666 gpio->PDDAT |= (1 << 0);
668 gpio->PDDAT &= ~(1 << 0);
672 if (strcmp (argv[3], "on") == 0)
673 gpio->PDDAT |= (1 << 4);
675 gpio->PDDAT &= ~(1 << 4);
682 printf ("%s: invalid parameter %s\n", __FUNCTION__, argv[2]);
687 int do_full_bridge (char **argv)
689 S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
691 /* configure PD5 and PD6 as output */
692 gpio->PDCON &= ~((0x3 << 5*2) | (0x3 << 6*2));
693 gpio->PDCON |= ((0x1 << 5*2) | (0x1 << 6*2));
695 if (strcmp (argv[2], "+") == 0) {
696 gpio->PDDAT |= (1 << 5);
697 gpio->PDDAT |= (1 << 6);
700 else if (strcmp (argv[2], "-") == 0) {
701 gpio->PDDAT &= ~(1 << 5);
702 gpio->PDDAT |= (1 << 6);
705 else if (strcmp (argv[2], "off") == 0) {
706 gpio->PDDAT &= ~(1 << 5);
707 gpio->PDDAT &= ~(1 << 6);
710 printf ("%s: invalid parameter %s\n", __FUNCTION__, argv[2]);
714 /* val must be in [0, 4095] */
715 static inline unsigned long tsc2000_to_uv (u16 val)
717 return ((250000 * val) / 4096) * 10;
721 int do_dac (char **argv)
728 if (((brightness = simple_strtoul (argv[2], NULL, 10)) < 0) ||
729 (brightness > 255)) {
730 printf ("%s: invalid parameter %s\n", __FUNCTION__, argv[2]);
733 tsc2000_write(TSC2000_REG_DACCTL, 0x0); /* Power up DAC */
734 tsc2000_write(TSC2000_REG_DAC, brightness & 0xff);
742 unsigned long ret, res;
747 tsc2000_write(TSC2000_REG_ADC, 0x1836);
749 /* now wait for data available */
750 adc_wait_conversion_done();
752 ret = tsc2000_read(TSC2000_REG_BAT1);
753 res = (tsc2000_to_uv(ret) + 1250) / 2500;
754 res += (ERROR_BATTERY * res) / 1000;
757 printf ("%ld", (res / 100));
758 printf (".%ld", ((res % 100) / 10));
759 printf ("%ld V\n", (res % 10));
764 int do_pressure (void)
769 tsc2000_write(TSC2000_REG_ADC, 0x2436);
771 /* now wait for data available */
772 adc_wait_conversion_done();
775 printf ("%d\n", tsc2000_read(TSC2000_REG_AUX2));
780 int do_motor_contact (void)
784 result = *CPLD_FILL_LEVEL; /* read CPLD */
785 debug ("%s: cpld_fuellstand (32 bit) %#x\n", __FUNCTION__, result);
787 /* print result to console */
789 if ((result & (1 << 17)) == 0)
796 int do_motor (char **argv)
798 S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
800 /* Configure I/O port */
801 gpio->PGCON &= ~(0x3 << 0);
802 gpio->PGCON |= (0x1 << 0);
804 if (strcmp (argv[2], "on") == 0) {
805 gpio->PGDAT &= ~(1 << 0);
808 if (strcmp (argv[2], "off") == 0) {
809 gpio->PGDAT |= (1 << 0);
812 printf ("%s: invalid parameter %s\n", __FUNCTION__, argv[2]);
816 static void print_identifier (void)
821 int do_pwm (char **argv)
824 S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
825 S3C24X0_TIMERS * const timers = S3C24X0_GetBase_TIMERS();
827 if (strcmp (argv[2], "on") == 0) {
828 /* configure pin GPD8 as TOUT3 */
829 gpio->PDCON &= ~(0x3 << 8*2);
830 gpio->PDCON |= (0x2 << 8*2);
832 /* set prescaler for timer 2, 3 and 4 */
833 timers->TCFG0 &= ~0xFF00;
834 timers->TCFG0 |= 0x0F00;
836 /* set divider for timer 3 */
837 timers->TCFG1 &= ~(0xf << 12);
838 timers->TCFG1 |= (0x3 << 12);
841 counter = (PCLK / PWM_FREQ) >> 9;
842 timers->ch[3].TCNTB = counter;
843 timers->ch[3].TCMPB = counter / 2;
846 timers->TCON = (timers->TCON | UPDATE3 | RELOAD3) & ~INVERT3;
847 timers->TCON = (timers->TCON | START3) & ~UPDATE3;
850 if (strcmp (argv[2], "off") == 0) {
853 timers->TCON &= ~(START2 | RELOAD2);
855 /* configure pin GPD8 as output and set to 0 */
856 gpio->PDCON &= ~(0x3 << 8*2);
857 gpio->PDCON |= (0x1 << 8*2);
858 gpio->PDDAT &= ~(1 << 8);
861 printf ("%s: invalid parameter %s\n", __FUNCTION__, argv[2]);
866 int do_thermo (char **argv)
872 if (strcmp (argv[2], "all") == 0) {
874 for (i=0; i <= 15; i++) {
875 res = tsc2000_read_channel(i);
877 printf ("c%d: %d\n", i, res);
881 channel = simple_strtoul (argv[2], NULL, 10);
882 res = tsc2000_read_channel(channel);
884 printf ("%d\n", res);
885 return 0; /* return OK */
889 int do_touch (char **argv)
893 if (strcmp (argv[2], "tl") == 0) {
894 #ifdef CONFIG_TOUCH_WAIT_PRESSED
895 touch_wait_pressed();
899 for (i = 0; i < (TOUCH_TIMEOUT * 1000); i++) {
900 if (touch_check_pressed ()) {
903 udelay (1000); /* pause 1 ms */
906 if (!touch_check_pressed()) {
908 printf ("error: touch not pressed\n");
911 #endif /* CONFIG_TOUCH_WAIT_PRESSED */
912 touch_read_x_y (&x, &y);
915 printf ("x=%d y=%d\n", x, y);
916 return touch_write_clibration_values (CALIB_TL, x, y);
918 else if (strcmp (argv[2], "dr") == 0) {
919 #ifdef CONFIG_TOUCH_WAIT_PRESSED
920 touch_wait_pressed();
924 for (i = 0; i < (TOUCH_TIMEOUT * 1000); i++) {
925 if (touch_check_pressed ()) {
928 udelay (1000); /* pause 1 ms */
931 if (!touch_check_pressed()) {
933 printf ("error: touch not pressed\n");
936 #endif /* CONFIG_TOUCH_WAIT_PRESSED */
937 touch_read_x_y (&x, &y);
940 printf ("x=%d y=%d\n", x, y);
942 return touch_write_clibration_values (CALIB_DR, x, y);
944 return 1; /* not "tl", nor "dr", so return error */
948 #ifdef CONFIG_TOUCH_WAIT_PRESSED
949 static void touch_wait_pressed (void)
951 while (!(tsc2000_read(TSC2000_REG_ADC) & TC_PSM));
955 static int touch_check_pressed (void)
957 return (tsc2000_read(TSC2000_REG_ADC) & TC_PSM);
959 #endif /* CONFIG_TOUCH_WAIT_PRESSED */
961 static int touch_write_clibration_values (int calib_point, int x, int y)
963 #if defined(CONFIG_CMD_I2C)
969 if (calib_point == CALIB_TL) {
970 if (i2c_write_multiple (I2C_EEPROM_DEV_ADDR, TOUCH_X0, 1,
971 (unsigned char *)&x, 2)) {
974 if (i2c_write_multiple (I2C_EEPROM_DEV_ADDR, TOUCH_Y0, 1,
975 (unsigned char *)&y, 2)) {
979 /* verify written values */
980 if (i2c_read_multiple (I2C_EEPROM_DEV_ADDR, TOUCH_X0, 1,
981 (unsigned char *)&x_verify, 2)) {
984 if (i2c_read_multiple (I2C_EEPROM_DEV_ADDR, TOUCH_Y0, 1,
985 (unsigned char *)&y_verify, 2)) {
988 if ((y != y_verify) || (x != x_verify)) {
990 printf ("error: verify error\n");
993 return 0; /* no error */
995 else if (calib_point == CALIB_DR) {
996 if (i2c_write_multiple (I2C_EEPROM_DEV_ADDR, TOUCH_X1, 1,
997 (unsigned char *)&x, 2)) {
1000 if (i2c_write_multiple (I2C_EEPROM_DEV_ADDR, TOUCH_Y1, 1,
1001 (unsigned char *)&y, 2)) {
1005 /* verify written values */
1006 if (i2c_read_multiple (I2C_EEPROM_DEV_ADDR, TOUCH_X1, 1,
1007 (unsigned char *)&x_verify, 2)) {
1010 if (i2c_read_multiple (I2C_EEPROM_DEV_ADDR, TOUCH_Y1, 1,
1011 (unsigned char *)&y_verify, 2)) {
1014 if ((y != y_verify) || (x != x_verify)) {
1015 print_identifier ();
1016 printf ("error: verify error\n");
1023 printf ("No I2C support enabled (CONFIG_CMD_I2C), could not write "
1030 static void touch_read_x_y (int *px, int *py)
1032 tsc2000_write(TSC2000_REG_ADC, DEFAULT_ADC | TC_AD0 | TC_AD1);
1033 adc_wait_conversion_done();
1034 *px = tsc2000_read(TSC2000_REG_X);
1036 tsc2000_write(TSC2000_REG_ADC, DEFAULT_ADC | TC_AD2);
1037 adc_wait_conversion_done();
1038 *py = tsc2000_read(TSC2000_REG_Y);
1042 int do_rs485 (char **argv)
1045 char data[RS485_MAX_RECEIVE_BUF_LEN];
1047 if (strcmp (argv[2], "send") == 0) {
1048 return (rs485_send_line (argv[3]));
1050 else if (strcmp (argv[2], "receive") == 0) {
1051 timeout = simple_strtoul(argv[3], NULL, 10);
1052 if (rs485_receive_chars (data, timeout) != 0) {
1053 print_identifier ();
1054 printf ("## nothing received\n");
1058 print_identifier ();
1059 printf ("%s\n", data);
1063 printf ("%s: unknown command %s\n", __FUNCTION__, argv[2]);
1064 return (1); /* unknown command, return error */
1068 static int rs485_send_line (const char *data)
1071 trab_rs485_enable_tx ();
1079 static int rs485_receive_chars (char *data, int timeout)
1082 int receive_count = 0;
1085 trab_rs485_enable_rx ();
1087 /* test every 1 ms for received characters to avoid a receive FIFO
1088 * overrun (@ 38.400 Baud) */
1089 for (i = 0; i < (timeout * 1000); i++) {
1090 while (rs485_tstc ()) {
1091 if (receive_count >= RS485_MAX_RECEIVE_BUF_LEN-1)
1093 *data++ = rs485_getc ();
1096 udelay (1000); /* pause 1 ms */
1098 *data = '\0'; /* terminate string */
1100 if (receive_count == 0)
1107 int do_serial_number (char **argv)
1109 #if defined(CONFIG_CMD_I2C)
1110 unsigned int serial_number;
1112 if (strcmp (argv[2], "read") == 0) {
1113 if (i2c_read (I2C_EEPROM_DEV_ADDR, SERIAL_NUMBER, 1,
1114 (unsigned char *)&serial_number, 4)) {
1115 printf ("could not read from eeprom\n");
1118 print_identifier ();
1119 printf ("%08d\n", serial_number);
1122 else if (strcmp (argv[2], "write") == 0) {
1123 serial_number = simple_strtoul(argv[3], NULL, 10);
1124 if (i2c_write (I2C_EEPROM_DEV_ADDR, SERIAL_NUMBER, 1,
1125 (unsigned char *)&serial_number, 4)) {
1126 printf ("could not write to eeprom\n");
1131 printf ("%s: unknown command %s\n", __FUNCTION__, argv[2]);
1132 return (1); /* unknown command, return error */
1134 printf ("No I2C support enabled (CONFIG_CMD_I2C), could not write "
1143 #if defined(CONFIG_CMD_I2C)
1145 unsigned char buf[EEPROM_MAX_CRC_BUF];
1147 if (i2c_read (I2C_EEPROM_DEV_ADDR, 0, 1, buf, 60)) {
1148 printf ("could not read from eeprom\n");
1151 crc = 0; /* start value of crc calculation */
1152 crc = updcrc (crc, buf, 60);
1154 print_identifier ();
1155 printf ("crc16=%#04x\n", crc);
1157 if (i2c_write (I2C_EEPROM_DEV_ADDR, CRC16, 1, (unsigned char *)&crc,
1159 printf ("could not read from eeprom\n");
1164 printf ("No I2C support enabled (CONFIG_CMD_I2C), could not write "
1172 * Calculate, intelligently, the CRC of a dataset incrementally given a
1173 * buffer full at a time.
1174 * Initialize crc to 0 for XMODEM, -1 for CCITT.
1177 * newcrc = updcrc( oldcrc, bufadr, buflen )
1178 * unsigned int oldcrc, buflen;
1181 * Compile with -DTEST to generate program that prints CRC of stdin to stdout.
1182 * Compile with -DMAKETAB to print values for crctab to stdout
1185 /* the CRC polynomial. This is used by XMODEM (almost CCITT).
1186 * If you change P, you must change crctab[]'s initial value to what is
1187 * printed by initcrctab()
1191 /* number of bits in CRC: don't change it. */
1194 /* this the number of bits per char: don't change it. */
1197 static unsigned short crctab[1<<B] = { /* as calculated by initcrctab() */
1198 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
1199 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
1200 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
1201 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
1202 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
1203 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
1204 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
1205 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
1206 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
1207 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
1208 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
1209 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
1210 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
1211 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
1212 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
1213 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
1214 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
1215 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
1216 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
1217 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
1218 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
1219 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
1220 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
1221 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
1222 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
1223 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
1224 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
1225 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
1226 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
1227 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
1228 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
1229 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
1232 static unsigned short updcrc(unsigned short icrc, unsigned char *icp,
1235 register unsigned short crc = icrc;
1236 register unsigned char *cp = icp;
1237 register unsigned int cnt = icnt;
1240 crc = (crc<<B) ^ crctab[(crc>>(W-B)) ^ *cp++];
1246 int do_gain (char **argv)
1250 range = simple_strtoul (argv[2], NULL, 10);
1251 if ((range < 1) || (range > 3))
1253 printf ("%s: invalid parameter %s\n", __FUNCTION__, argv[2]);
1257 tsc2000_set_range (range);
1262 int do_eeprom (char **argv)
1264 #if defined(CONFIG_CMD_I2C)
1265 if (strcmp (argv[2], "read") == 0) {
1266 return (trab_eeprom_read (argv));
1269 else if (strcmp (argv[2], "write") == 0) {
1270 return (trab_eeprom_write (argv));
1273 printf ("%s: invalid parameter %s\n", __FUNCTION__, argv[2]);
1276 printf ("No I2C support enabled (CONFIG_CMD_I2C), could not write "
1282 #if defined(CONFIG_CMD_I2C)
1283 static int trab_eeprom_read (char **argv)
1291 buffer = (uchar *) &value;
1292 addr = simple_strtoul (argv[3], NULL, 10);
1294 len = simple_strtoul (argv[4], NULL, 10);
1295 if ((len < 1) || (len > 4)) {
1296 printf ("%s: invalid parameter %s\n", __FUNCTION__,
1300 for (i = 0; i < len; i++) {
1301 if (i2c_read (I2C_EEPROM_DEV_ADDR, addr+i, 1, buffer+i, 1)) {
1302 printf ("%s: could not read from i2c device %#x"
1303 ", addr %d\n", __FUNCTION__,
1304 I2C_EEPROM_DEV_ADDR, addr);
1308 print_identifier ();
1309 if (strcmp (argv[5], "-") == 0) {
1311 printf ("%d\n", (signed char) value);
1313 printf ("%d\n", (signed short int) value);
1315 printf ("%ld\n", value);
1319 printf ("%d\n", (unsigned char) value);
1321 printf ("%d\n", (unsigned short int) value);
1323 printf ("%ld\n", (unsigned long int) value);
1328 static int trab_eeprom_write (char **argv)
1336 buffer = (uchar *) &value;
1337 addr = simple_strtoul (argv[3], NULL, 10);
1339 len = simple_strtoul (argv[4], NULL, 10);
1340 if ((len < 1) || (len > 4)) {
1341 printf ("%s: invalid parameter %s\n", __FUNCTION__,
1345 value = simple_strtol (argv[5], NULL, 10);
1346 debug ("value=%ld\n", value);
1347 for (i = 0; i < len; i++) {
1348 if (i2c_write (I2C_EEPROM_DEV_ADDR, addr+i, 1, buffer+i, 1)) {
1349 printf ("%s: could not write to i2c device %d"
1350 ", addr %d\n", __FUNCTION__,
1351 I2C_EEPROM_DEV_ADDR, addr);
1355 printf ("chip=%#x, addr+i=%#x+%d=%p, alen=%d, *buffer+i="
1356 "%#x+%d=%p=%#x \n",I2C_EEPROM_DEV_ADDR_DEV_ADDR , addr,
1357 i, addr+i, 1, buffer, i, buffer+i, *(buffer+i));
1359 udelay (30000); /* wait for EEPROM ready */
1364 int i2c_write_multiple (uchar chip, uint addr, int alen,
1365 uchar *buffer, int len)
1370 printf ("%s: addr len other than 1 not supported\n",
1375 for (i = 0; i < len; i++) {
1376 if (i2c_write (chip, addr+i, alen, buffer+i, 1)) {
1377 printf ("%s: could not write to i2c device %d"
1378 ", addr %d\n", __FUNCTION__, chip, addr);
1382 printf ("chip=%#x, addr+i=%#x+%d=%p, alen=%d, *buffer+i="
1383 "%#x+%d=%p=\"%.1s\"\n", chip, addr, i, addr+i,
1384 alen, buffer, i, buffer+i, buffer+i);
1392 int i2c_read_multiple ( uchar chip, uint addr, int alen,
1393 uchar *buffer, int len)
1398 printf ("%s: addr len other than 1 not supported\n",
1403 for (i = 0; i < len; i++) {
1404 if (i2c_read (chip, addr+i, alen, buffer+i, 1)) {
1405 printf ("%s: could not read from i2c device %#x"
1406 ", addr %d\n", __FUNCTION__, chip, addr);