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>
29 #include <asm/arch/s3c24x0_cpu.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 puts ("### ERROR ### Please RESET the board ###\n");
305 printf ("Stand-alone application for TRAB board function test\n");
306 printf ("Built: %s at %s\n", U_BOOT_DATE, U_BOOT_TIME);
313 unsigned int result = 0;
317 /***********************************************************
318 DIP switch connection (according to wa4-cpu.sp.301.pdf, page 3):
324 "On" DIP switch position short-circuits the voltage from
325 the input channel (i.e. '0' conversion result means "on").
326 *************************************************************/
328 for (i = 7; i > 3; i--) {
330 if ((adc_val = adc_read (i)) == -1) {
331 printf ("Channel %d could not be read\n", i);
336 * Input voltage (switch open) is 1.8 V.
337 * (Vin_High/VRef)*adc_res = (1,8V/2,5V)*1023) = 736
338 * Set trigger at halve that value.
341 result |= (1 << (i-4));
344 /* print result to console */
346 for (i = 0; i < 4; i++) {
347 if ((result & (1 << i)) == 0)
362 /* VCC5V is connected to channel 2 */
364 if ((result = adc_read (VCC5V)) == -1) {
365 printf ("VCC5V could not be read\n");
370 * Calculate voltage value. Split in two parts because there is no
371 * floating point support. VCC5V is connected over an resistor divider:
372 * VCC5V=ADCval*2,5V/1023*(10K+30K)/10K.
375 printf ("%d", (result & 0x3FF)* 10 / 1023);
376 printf (".%d", ((result & 0x3FF)* 10 % 1023)* 10 / 1023);
377 printf ("%d V\n", (((result & 0x3FF) * 10 % 1023 ) * 10 % 1023)
388 if ((result = adc_read (VCC12V)) == -1) {
389 printf ("VCC12V could not be read\n");
394 * Calculate voltage value. Split in two parts because there is no
395 * floating point support. VCC5V is connected over an resistor divider:
396 * VCC12V=ADCval*2,5V/1023*(30K+270K)/30K.
399 printf ("%d", (result & 0x3FF)* 25 / 1023);
400 printf (".%d V\n", ((result & 0x3FF)* 25 % 1023) * 10 / 1023);
405 static int adc_read (unsigned int channel)
407 int j = 1000; /* timeout value for wait loop in us */
409 struct s3c2400_adc *padc;
411 padc = s3c2400_get_base_adc();
414 padc->ADCCON &= ~ADC_STDBM; /* select normal mode */
415 padc->ADCCON &= ~(0x7 << 3); /* clear the channel bits */
416 padc->ADCCON |= ((channel << 3) | ADC_ENABLE_START);
419 if ((padc->ADCCON & ADC_ENABLE_START) == 0)
425 printf("%s: ADC timeout\n", __FUNCTION__);
426 padc->ADCCON |= ADC_STDBM; /* select standby mode */
430 result = padc->ADCDAT & 0x3FF;
432 padc->ADCCON |= ADC_STDBM; /* select standby mode */
434 debug ("%s: channel %d, result[DIGIT]=%d\n", __FUNCTION__,
435 (padc->ADCCON >> 3) & 0x7, result);
438 * Wait for ADC to be ready for next conversion. This delay value was
439 * estimated, because the datasheet does not specify a value.
447 static void adc_init (void)
449 struct s3c2400_adc *padc;
451 padc = s3c2400_get_base_adc();
453 padc->ADCCON &= ~(0xff << 6); /* clear prescaler bits */
454 padc->ADCCON |= ((65 << 6) | ADC_PRSCEN); /* set prescaler */
457 * Wait some time to avoid problem with very first call of
458 * adc_read(). Without * this delay, sometimes the first read adc
459 * value is 0. Perhaps because the * adjustment of prescaler takes
468 int do_buttons (void)
473 result = *CPLD_BUTTONS; /* read CPLD */
474 debug ("%s: cpld_taster (32 bit) %#x\n", __FUNCTION__, result);
476 /* print result to console */
478 for (i = 16; i <= 19; i++) {
479 if ((result & (1 << i)) == 0)
489 int do_power_switch (void)
493 struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio();
495 /* configure GPE7 as input */
496 gpio->PECON &= ~(0x3 << (2 * 7));
498 /* signal GPE7 from power switch is low active: 0=on , 1=off */
499 result = ((gpio->PEDAT & (1 << 7)) == (1 << 7)) ? 0 : 1;
502 printf("%d\n", result);
507 int do_fill_level (void)
511 result = *CPLD_FILL_LEVEL; /* read CPLD */
512 debug ("%s: cpld_fuellstand (32 bit) %#x\n", __FUNCTION__, result);
514 /* print result to console */
516 if ((result & (1 << 16)) == 0)
524 int do_rotary_switch (void)
528 * Please note, that the default values of the direction bits are
529 * undefined after reset. So it is a good idea, to make first a dummy
530 * call to this function, to clear the direction bits and set so to
534 result = *CPLD_ROTARY_SWITCH; /* read CPLD */
535 debug ("%s: cpld_inc (32 bit) %#x\n", __FUNCTION__, result);
537 *CPLD_ROTARY_SWITCH |= (3 << 16); /* clear direction bits in CPLD */
539 /* print result to console */
541 if ((result & (1 << 16)) == (1 << 16))
543 if ((result & (1 << 17)) == (1 << 17))
545 if (((result & (1 << 16)) == 0) && ((result & (1 << 17)) == 0))
547 if ((result & (1 << 18)) == 0)
558 long int pcup_old, pccon_old;
560 struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio();
562 /* try to red vfd board id from the value defined by pull-ups */
564 pcup_old = gpio->PCUP;
565 pccon_old = gpio->PCCON;
567 gpio->PCUP = (gpio->PCUP & 0xFFF0); /* activate GPC0...GPC3 pull-ups */
568 gpio->PCCON = (gpio->PCCON & 0xFFFFFF00); /* configure GPC0...GPC3 as
570 udelay (10); /* allow signals to settle */
571 vfd_board_id = (~gpio->PCDAT) & 0x000F; /* read GPC0...GPC3 port pins */
573 gpio->PCCON = pccon_old;
574 gpio->PCUP = pcup_old;
576 /* print vfd_board_id to console */
578 for (i = 0; i < 4; i++) {
579 if ((vfd_board_id & (1 << i)) == 0)
588 int do_buzzer (char **argv)
592 struct s3c24x0_timers * const timers = s3c24x0_get_base_timers();
593 struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio();
595 /* set prescaler for timer 2, 3 and 4 */
596 timers->TCFG0 &= ~0xFF00;
597 timers->TCFG0 |= 0x0F00;
599 /* set divider for timer 2 */
600 timers->TCFG1 &= ~0xF00;
601 timers->TCFG1 |= 0x300;
604 counter = (PCLK / BUZZER_FREQ) >> 9;
605 timers->ch[2].TCNTB = counter;
606 timers->ch[2].TCMPB = counter / 2;
608 if (strcmp (argv[2], "on") == 0) {
609 debug ("%s: frequency: %d\n", __FUNCTION__,
612 /* configure pin GPD7 as TOUT2 */
613 gpio->PDCON &= ~0xC000;
614 gpio->PDCON |= 0x8000;
617 timers->TCON = (timers->TCON | UPDATE2 | RELOAD2) &
619 timers->TCON = (timers->TCON | START2) & ~UPDATE2;
622 else if (strcmp (argv[2], "off") == 0) {
624 timers->TCON &= ~(START2 | RELOAD2);
626 /* configure GPD7 as output and set to low */
627 gpio->PDCON &= ~0xC000;
628 gpio->PDCON |= 0x4000;
629 gpio->PDDAT &= ~0x80;
633 printf ("%s: invalid parameter %s\n", __FUNCTION__, argv[2]);
638 int do_led (char **argv)
640 struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio();
642 /* configure PC14 and PC15 as output */
643 gpio->PCCON &= ~(0xF << 28);
644 gpio->PCCON |= (0x5 << 28);
646 /* configure PD0 and PD4 as output */
647 gpio->PDCON &= ~((0x3 << 8) | 0x3);
648 gpio->PDCON |= ((0x1 << 8) | 0x1);
650 switch (simple_strtoul(argv[2], NULL, 10)) {
657 if (strcmp (argv[3], "on") == 0)
658 gpio->PCDAT |= (1 << 14);
660 gpio->PCDAT &= ~(1 << 14);
664 if (strcmp (argv[3], "on") == 0)
665 gpio->PCDAT |= (1 << 15);
667 gpio->PCDAT &= ~(1 << 15);
671 if (strcmp (argv[3], "on") == 0)
672 gpio->PDDAT |= (1 << 0);
674 gpio->PDDAT &= ~(1 << 0);
678 if (strcmp (argv[3], "on") == 0)
679 gpio->PDDAT |= (1 << 4);
681 gpio->PDDAT &= ~(1 << 4);
688 printf ("%s: invalid parameter %s\n", __FUNCTION__, argv[2]);
693 int do_full_bridge (char **argv)
695 struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio();
697 /* configure PD5 and PD6 as output */
698 gpio->PDCON &= ~((0x3 << 5*2) | (0x3 << 6*2));
699 gpio->PDCON |= ((0x1 << 5*2) | (0x1 << 6*2));
701 if (strcmp (argv[2], "+") == 0) {
702 gpio->PDDAT |= (1 << 5);
703 gpio->PDDAT |= (1 << 6);
706 else if (strcmp (argv[2], "-") == 0) {
707 gpio->PDDAT &= ~(1 << 5);
708 gpio->PDDAT |= (1 << 6);
711 else if (strcmp (argv[2], "off") == 0) {
712 gpio->PDDAT &= ~(1 << 5);
713 gpio->PDDAT &= ~(1 << 6);
716 printf ("%s: invalid parameter %s\n", __FUNCTION__, argv[2]);
720 /* val must be in [0, 4095] */
721 static inline unsigned long tsc2000_to_uv (u16 val)
723 return ((250000 * val) / 4096) * 10;
727 int do_dac (char **argv)
734 if (((brightness = simple_strtoul (argv[2], NULL, 10)) < 0) ||
735 (brightness > 255)) {
736 printf ("%s: invalid parameter %s\n", __FUNCTION__, argv[2]);
739 tsc2000_write(TSC2000_REG_DACCTL, 0x0); /* Power up DAC */
740 tsc2000_write(TSC2000_REG_DAC, brightness & 0xff);
748 unsigned long ret, res;
753 tsc2000_write(TSC2000_REG_ADC, 0x1836);
755 /* now wait for data available */
756 adc_wait_conversion_done();
758 ret = tsc2000_read(TSC2000_REG_BAT1);
759 res = (tsc2000_to_uv(ret) + 1250) / 2500;
760 res += (ERROR_BATTERY * res) / 1000;
763 printf ("%ld", (res / 100));
764 printf (".%ld", ((res % 100) / 10));
765 printf ("%ld V\n", (res % 10));
770 int do_pressure (void)
775 tsc2000_write(TSC2000_REG_ADC, 0x2436);
777 /* now wait for data available */
778 adc_wait_conversion_done();
781 printf ("%d\n", tsc2000_read(TSC2000_REG_AUX2));
786 int do_motor_contact (void)
790 result = *CPLD_FILL_LEVEL; /* read CPLD */
791 debug ("%s: cpld_fuellstand (32 bit) %#x\n", __FUNCTION__, result);
793 /* print result to console */
795 if ((result & (1 << 17)) == 0)
802 int do_motor (char **argv)
804 struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio();
806 /* Configure I/O port */
807 gpio->PGCON &= ~(0x3 << 0);
808 gpio->PGCON |= (0x1 << 0);
810 if (strcmp (argv[2], "on") == 0) {
811 gpio->PGDAT &= ~(1 << 0);
814 if (strcmp (argv[2], "off") == 0) {
815 gpio->PGDAT |= (1 << 0);
818 printf ("%s: invalid parameter %s\n", __FUNCTION__, argv[2]);
822 static void print_identifier (void)
827 int do_pwm (char **argv)
830 struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio();
831 struct s3c24x0_timers * const timers = s3c24x0_get_base_timers();
833 if (strcmp (argv[2], "on") == 0) {
834 /* configure pin GPD8 as TOUT3 */
835 gpio->PDCON &= ~(0x3 << 8*2);
836 gpio->PDCON |= (0x2 << 8*2);
838 /* set prescaler for timer 2, 3 and 4 */
839 timers->TCFG0 &= ~0xFF00;
840 timers->TCFG0 |= 0x0F00;
842 /* set divider for timer 3 */
843 timers->TCFG1 &= ~(0xf << 12);
844 timers->TCFG1 |= (0x3 << 12);
847 counter = (PCLK / PWM_FREQ) >> 9;
848 timers->ch[3].TCNTB = counter;
849 timers->ch[3].TCMPB = counter / 2;
852 timers->TCON = (timers->TCON | UPDATE3 | RELOAD3) & ~INVERT3;
853 timers->TCON = (timers->TCON | START3) & ~UPDATE3;
856 if (strcmp (argv[2], "off") == 0) {
859 timers->TCON &= ~(START2 | RELOAD2);
861 /* configure pin GPD8 as output and set to 0 */
862 gpio->PDCON &= ~(0x3 << 8*2);
863 gpio->PDCON |= (0x1 << 8*2);
864 gpio->PDDAT &= ~(1 << 8);
867 printf ("%s: invalid parameter %s\n", __FUNCTION__, argv[2]);
872 int do_thermo (char **argv)
878 if (strcmp (argv[2], "all") == 0) {
880 for (i=0; i <= 15; i++) {
881 res = tsc2000_read_channel(i);
883 printf ("c%d: %d\n", i, res);
887 channel = simple_strtoul (argv[2], NULL, 10);
888 res = tsc2000_read_channel(channel);
890 printf ("%d\n", res);
891 return 0; /* return OK */
895 int do_touch (char **argv)
899 if (strcmp (argv[2], "tl") == 0) {
900 #ifdef CONFIG_TOUCH_WAIT_PRESSED
901 touch_wait_pressed();
905 for (i = 0; i < (TOUCH_TIMEOUT * 1000); i++) {
906 if (touch_check_pressed ()) {
909 udelay (1000); /* pause 1 ms */
912 if (!touch_check_pressed()) {
914 printf ("error: touch not pressed\n");
917 #endif /* CONFIG_TOUCH_WAIT_PRESSED */
918 touch_read_x_y (&x, &y);
921 printf ("x=%d y=%d\n", x, y);
922 return touch_write_clibration_values (CALIB_TL, x, y);
924 else if (strcmp (argv[2], "dr") == 0) {
925 #ifdef CONFIG_TOUCH_WAIT_PRESSED
926 touch_wait_pressed();
930 for (i = 0; i < (TOUCH_TIMEOUT * 1000); i++) {
931 if (touch_check_pressed ()) {
934 udelay (1000); /* pause 1 ms */
937 if (!touch_check_pressed()) {
939 printf ("error: touch not pressed\n");
942 #endif /* CONFIG_TOUCH_WAIT_PRESSED */
943 touch_read_x_y (&x, &y);
946 printf ("x=%d y=%d\n", x, y);
948 return touch_write_clibration_values (CALIB_DR, x, y);
950 return 1; /* not "tl", nor "dr", so return error */
954 #ifdef CONFIG_TOUCH_WAIT_PRESSED
955 static void touch_wait_pressed (void)
957 while (!(tsc2000_read(TSC2000_REG_ADC) & TC_PSM));
961 static int touch_check_pressed (void)
963 return (tsc2000_read(TSC2000_REG_ADC) & TC_PSM);
965 #endif /* CONFIG_TOUCH_WAIT_PRESSED */
967 static int touch_write_clibration_values (int calib_point, int x, int y)
969 #if defined(CONFIG_CMD_I2C)
975 if (calib_point == CALIB_TL) {
976 if (i2c_write_multiple (I2C_EEPROM_DEV_ADDR, TOUCH_X0, 1,
977 (unsigned char *)&x, 2)) {
980 if (i2c_write_multiple (I2C_EEPROM_DEV_ADDR, TOUCH_Y0, 1,
981 (unsigned char *)&y, 2)) {
985 /* verify written values */
986 if (i2c_read_multiple (I2C_EEPROM_DEV_ADDR, TOUCH_X0, 1,
987 (unsigned char *)&x_verify, 2)) {
990 if (i2c_read_multiple (I2C_EEPROM_DEV_ADDR, TOUCH_Y0, 1,
991 (unsigned char *)&y_verify, 2)) {
994 if ((y != y_verify) || (x != x_verify)) {
996 printf ("error: verify error\n");
999 return 0; /* no error */
1001 else if (calib_point == CALIB_DR) {
1002 if (i2c_write_multiple (I2C_EEPROM_DEV_ADDR, TOUCH_X1, 1,
1003 (unsigned char *)&x, 2)) {
1006 if (i2c_write_multiple (I2C_EEPROM_DEV_ADDR, TOUCH_Y1, 1,
1007 (unsigned char *)&y, 2)) {
1011 /* verify written values */
1012 if (i2c_read_multiple (I2C_EEPROM_DEV_ADDR, TOUCH_X1, 1,
1013 (unsigned char *)&x_verify, 2)) {
1016 if (i2c_read_multiple (I2C_EEPROM_DEV_ADDR, TOUCH_Y1, 1,
1017 (unsigned char *)&y_verify, 2)) {
1020 if ((y != y_verify) || (x != x_verify)) {
1021 print_identifier ();
1022 printf ("error: verify error\n");
1029 printf ("No I2C support enabled (CONFIG_CMD_I2C), could not write "
1036 static void touch_read_x_y (int *px, int *py)
1038 tsc2000_write(TSC2000_REG_ADC, DEFAULT_ADC | TC_AD0 | TC_AD1);
1039 adc_wait_conversion_done();
1040 *px = tsc2000_read(TSC2000_REG_X);
1042 tsc2000_write(TSC2000_REG_ADC, DEFAULT_ADC | TC_AD2);
1043 adc_wait_conversion_done();
1044 *py = tsc2000_read(TSC2000_REG_Y);
1048 int do_rs485 (char **argv)
1051 char data[RS485_MAX_RECEIVE_BUF_LEN];
1053 if (strcmp (argv[2], "send") == 0) {
1054 return (rs485_send_line (argv[3]));
1056 else if (strcmp (argv[2], "receive") == 0) {
1057 timeout = simple_strtoul(argv[3], NULL, 10);
1058 if (rs485_receive_chars (data, timeout) != 0) {
1059 print_identifier ();
1060 printf ("## nothing received\n");
1064 print_identifier ();
1065 printf ("%s\n", data);
1069 printf ("%s: unknown command %s\n", __FUNCTION__, argv[2]);
1070 return (1); /* unknown command, return error */
1074 static int rs485_send_line (const char *data)
1077 trab_rs485_enable_tx ();
1085 static int rs485_receive_chars (char *data, int timeout)
1088 int receive_count = 0;
1091 trab_rs485_enable_rx ();
1093 /* test every 1 ms for received characters to avoid a receive FIFO
1094 * overrun (@ 38.400 Baud) */
1095 for (i = 0; i < (timeout * 1000); i++) {
1096 while (rs485_tstc ()) {
1097 if (receive_count >= RS485_MAX_RECEIVE_BUF_LEN-1)
1099 *data++ = rs485_getc ();
1102 udelay (1000); /* pause 1 ms */
1104 *data = '\0'; /* terminate string */
1106 if (receive_count == 0)
1113 int do_serial_number (char **argv)
1115 #if defined(CONFIG_CMD_I2C)
1116 unsigned int serial_number;
1118 if (strcmp (argv[2], "read") == 0) {
1119 if (i2c_read (I2C_EEPROM_DEV_ADDR, SERIAL_NUMBER, 1,
1120 (unsigned char *)&serial_number, 4)) {
1121 printf ("could not read from eeprom\n");
1124 print_identifier ();
1125 printf ("%08d\n", serial_number);
1128 else if (strcmp (argv[2], "write") == 0) {
1129 serial_number = simple_strtoul(argv[3], NULL, 10);
1130 if (i2c_write (I2C_EEPROM_DEV_ADDR, SERIAL_NUMBER, 1,
1131 (unsigned char *)&serial_number, 4)) {
1132 printf ("could not write to eeprom\n");
1137 printf ("%s: unknown command %s\n", __FUNCTION__, argv[2]);
1138 return (1); /* unknown command, return error */
1140 printf ("No I2C support enabled (CONFIG_CMD_I2C), could not write "
1149 #if defined(CONFIG_CMD_I2C)
1151 unsigned char buf[EEPROM_MAX_CRC_BUF];
1153 if (i2c_read (I2C_EEPROM_DEV_ADDR, 0, 1, buf, 60)) {
1154 printf ("could not read from eeprom\n");
1157 crc = 0; /* start value of crc calculation */
1158 crc = updcrc (crc, buf, 60);
1160 print_identifier ();
1161 printf ("crc16=%#04x\n", crc);
1163 if (i2c_write (I2C_EEPROM_DEV_ADDR, CRC16, 1, (unsigned char *)&crc,
1165 printf ("could not read from eeprom\n");
1170 printf ("No I2C support enabled (CONFIG_CMD_I2C), could not write "
1178 * Calculate, intelligently, the CRC of a dataset incrementally given a
1179 * buffer full at a time.
1180 * Initialize crc to 0 for XMODEM, -1 for CCITT.
1183 * newcrc = updcrc( oldcrc, bufadr, buflen )
1184 * unsigned int oldcrc, buflen;
1187 * Compile with -DTEST to generate program that prints CRC of stdin to stdout.
1188 * Compile with -DMAKETAB to print values for crctab to stdout
1191 /* the CRC polynomial. This is used by XMODEM (almost CCITT).
1192 * If you change P, you must change crctab[]'s initial value to what is
1193 * printed by initcrctab()
1197 /* number of bits in CRC: don't change it. */
1200 /* this the number of bits per char: don't change it. */
1203 static unsigned short crctab[1<<B] = { /* as calculated by initcrctab() */
1204 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
1205 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
1206 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
1207 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
1208 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
1209 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
1210 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
1211 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
1212 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
1213 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
1214 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
1215 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
1216 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
1217 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
1218 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
1219 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
1220 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
1221 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
1222 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
1223 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
1224 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
1225 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
1226 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
1227 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
1228 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
1229 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
1230 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
1231 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
1232 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
1233 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
1234 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
1235 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
1238 static unsigned short updcrc(unsigned short icrc, unsigned char *icp,
1241 register unsigned short crc = icrc;
1242 register unsigned char *cp = icp;
1243 register unsigned int cnt = icnt;
1246 crc = (crc<<B) ^ crctab[(crc>>(W-B)) ^ *cp++];
1252 int do_gain (char **argv)
1256 range = simple_strtoul (argv[2], NULL, 10);
1257 if ((range < 1) || (range > 3))
1259 printf ("%s: invalid parameter %s\n", __FUNCTION__, argv[2]);
1263 tsc2000_set_range (range);
1268 int do_eeprom (char **argv)
1270 #if defined(CONFIG_CMD_I2C)
1271 if (strcmp (argv[2], "read") == 0) {
1272 return (trab_eeprom_read (argv));
1275 else if (strcmp (argv[2], "write") == 0) {
1276 return (trab_eeprom_write (argv));
1279 printf ("%s: invalid parameter %s\n", __FUNCTION__, argv[2]);
1282 printf ("No I2C support enabled (CONFIG_CMD_I2C), could not write "
1288 #if defined(CONFIG_CMD_I2C)
1289 static int trab_eeprom_read (char **argv)
1297 buffer = (uchar *) &value;
1298 addr = simple_strtoul (argv[3], NULL, 10);
1300 len = simple_strtoul (argv[4], NULL, 10);
1301 if ((len < 1) || (len > 4)) {
1302 printf ("%s: invalid parameter %s\n", __FUNCTION__,
1306 for (i = 0; i < len; i++) {
1307 if (i2c_read (I2C_EEPROM_DEV_ADDR, addr+i, 1, buffer+i, 1)) {
1308 printf ("%s: could not read from i2c device %#x"
1309 ", addr %d\n", __FUNCTION__,
1310 I2C_EEPROM_DEV_ADDR, addr);
1314 print_identifier ();
1315 if (strcmp (argv[5], "-") == 0) {
1317 printf ("%d\n", (signed char) value);
1319 printf ("%d\n", (signed short int) value);
1321 printf ("%ld\n", value);
1325 printf ("%d\n", (unsigned char) value);
1327 printf ("%d\n", (unsigned short int) value);
1329 printf ("%ld\n", (unsigned long int) value);
1334 static int trab_eeprom_write (char **argv)
1342 buffer = (uchar *) &value;
1343 addr = simple_strtoul (argv[3], NULL, 10);
1345 len = simple_strtoul (argv[4], NULL, 10);
1346 if ((len < 1) || (len > 4)) {
1347 printf ("%s: invalid parameter %s\n", __FUNCTION__,
1351 value = simple_strtol (argv[5], NULL, 10);
1352 debug ("value=%ld\n", value);
1353 for (i = 0; i < len; i++) {
1354 if (i2c_write (I2C_EEPROM_DEV_ADDR, addr+i, 1, buffer+i, 1)) {
1355 printf ("%s: could not write to i2c device %d"
1356 ", addr %d\n", __FUNCTION__,
1357 I2C_EEPROM_DEV_ADDR, addr);
1361 printf ("chip=%#x, addr+i=%#x+%d=%p, alen=%d, *buffer+i="
1362 "%#x+%d=%p=%#x \n",I2C_EEPROM_DEV_ADDR_DEV_ADDR , addr,
1363 i, addr+i, 1, buffer, i, buffer+i, *(buffer+i));
1365 udelay (30000); /* wait for EEPROM ready */
1370 int i2c_write_multiple (uchar chip, uint addr, int alen,
1371 uchar *buffer, int len)
1376 printf ("%s: addr len other than 1 not supported\n",
1381 for (i = 0; i < len; i++) {
1382 if (i2c_write (chip, addr+i, alen, buffer+i, 1)) {
1383 printf ("%s: could not write to i2c device %d"
1384 ", addr %d\n", __FUNCTION__, chip, addr);
1388 printf ("chip=%#x, addr+i=%#x+%d=%p, alen=%d, *buffer+i="
1389 "%#x+%d=%p=\"%.1s\"\n", chip, addr, i, addr+i,
1390 alen, buffer, i, buffer+i, buffer+i);
1398 int i2c_read_multiple ( uchar chip, uint addr, int alen,
1399 uchar *buffer, int len)
1404 printf ("%s: addr len other than 1 not supported\n",
1409 for (i = 0; i < len; i++) {
1410 if (i2c_read (chip, addr+i, alen, buffer+i, 1)) {
1411 printf ("%s: could not read from i2c device %#x"
1412 ", addr %d\n", __FUNCTION__, chip, addr);