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,
33 * define, to wait for the touch to be pressed, before reading coordinates in
34 * command do_touch. If not defined, an error message is printed, when the
35 * command do_touch is invoked and the touch is not pressed within an specific
38 #undef CONFIG_TOUCH_WAIT_PRESSED 1
40 /* max time to wait for touch is pressed */
41 #ifndef CONFIG_TOUCH_WAIT_PRESSED
42 #define TOUCH_TIMEOUT 5
43 #endif /* !CONFIG_TOUCH_WAIT_PRESSED */
45 /* assignment of CPU internal ADC channels with TRAB hardware */
49 /* CPLD-Register for controlling TRAB hardware functions */
50 #define CPLD_BUTTONS ((volatile unsigned long *)0x04020000)
51 #define CPLD_FILL_LEVEL ((volatile unsigned long *)0x04008000)
52 #define CPLD_ROTARY_SWITCH ((volatile unsigned long *)0x04018000)
53 #define CPLD_RS485_RE ((volatile unsigned long *)0x04028000)
55 /* timer configuration bits for buzzer and PWM */
56 #define START2 (1 << 12)
57 #define UPDATE2 (1 << 13)
58 #define INVERT2 (1 << 14)
59 #define RELOAD2 (1 << 15)
60 #define START3 (1 << 16)
61 #define UPDATE3 (1 << 17)
62 #define INVERT3 (1 << 18)
63 #define RELOAD3 (1 << 19)
66 #define BUZZER_FREQ 1000 /* frequency in Hz */
70 /* definitions of I2C EEPROM device address */
71 #define I2C_EEPROM_DEV_ADDR 0x54
73 /* definition for touch panel calibration points */
74 #define CALIB_TL 0 /* calibration point in (T)op (L)eft corner */
75 #define CALIB_DR 1 /* calibration point in (D)own (R)ight corner */
77 /* EEPROM address map */
78 #define SERIAL_NUMBER 8
86 #define EEPROM_MAX_CRC_BUF 64
89 #define RS485_MAX_RECEIVE_BUF_LEN 100
91 /* Bit definitions for ADCCON */
92 #define ADC_ENABLE_START 0x1
93 #define ADC_READ_START 0x2
95 #define ADC_INP_AIN0 (0x0 << 3)
96 #define ADC_INP_AIN1 (0x1 << 3)
97 #define ADC_INP_AIN2 (0x2 << 3)
98 #define ADC_INP_AIN3 (0x3 << 3)
99 #define ADC_INP_AIN4 (0x4 << 3)
100 #define ADC_INP_AIN5 (0x5 << 3)
101 #define ADC_INP_AIN6 (0x6 << 3)
102 #define ADC_INP_AIN7 (0x7 << 3)
103 #define ADC_PRSCEN 0x4000
104 #define ADC_ECFLG 0x8000
106 /* function test functions */
110 int do_vcc12v (void);
111 int do_buttons (void);
112 int do_fill_level (void);
113 int do_rotary_switch (void);
114 int do_pressure (void);
116 int do_vfd_id (void);
117 int do_buzzer (char **);
118 int do_led (char **);
119 int do_full_bridge (char **);
120 int do_dac (char **);
121 int do_motor_contact (void);
122 int do_motor (char **);
123 int do_pwm (char **);
124 int do_thermo (char **);
125 int do_touch (char **);
126 int do_rs485 (char **);
127 int do_serial_number (char **);
129 int do_power_switch (void);
130 int do_gain (char **);
131 int do_eeprom (char **);
133 /* helper functions */
134 static void adc_init (void);
135 static int adc_read (unsigned int channel);
136 static void print_identifier (void);
138 #ifdef CONFIG_TOUCH_WAIT_PRESSED
139 static void touch_wait_pressed (void);
141 static int touch_check_pressed (void);
142 #endif /* CONFIG_TOUCH_WAIT_PRESSED */
144 static void touch_read_x_y (int *x, int *y);
145 static int touch_write_clibration_values (int calib_point, int x, int y);
146 static int rs485_send_line (const char *data);
147 static int rs485_receive_chars (char *data, int timeout);
148 static unsigned short updcrc(unsigned short icrc, unsigned char *icp,
151 #if (CONFIG_COMMANDS & CFG_CMD_I2C)
152 static int trab_eeprom_read (char **argv);
153 static int trab_eeprom_write (char **argv);
154 int i2c_write_multiple (uchar chip, uint addr, int alen, uchar *buffer,
156 int i2c_read_multiple ( uchar chip, uint addr, int alen, uchar *buffer,
158 #endif /* CFG_CMD_I2C */
161 * TRAB board specific commands. Especially commands for burn-in and function
165 int trab_fkt (int argc, char *argv[])
170 if (get_version () != XF_VERSION) {
171 printf ("Wrong XF_VERSION. Please re-compile with actual "
173 printf ("Example expects ABI version %d\n", XF_VERSION);
174 printf ("Actual U-Boot ABI version %d\n", (int)get_version());
178 debug ("argc = %d\n", argc);
180 for (i=0; i<=argc; ++i) {
181 debug ("argv[%d] = \"%s\"\n", i, argv[i] ? argv[i] : "<NULL>");
193 if (strcmp (argv[1], "info") == 0) {
196 if (strcmp (argv[1], "dip") == 0) {
199 if (strcmp (argv[1], "vcc5v") == 0) {
200 return (do_vcc5v ());
202 if (strcmp (argv[1], "vcc12v") == 0) {
203 return (do_vcc12v ());
205 if (strcmp (argv[1], "buttons") == 0) {
206 return (do_buttons ());
208 if (strcmp (argv[1], "fill_level") == 0) {
209 return (do_fill_level ());
211 if (strcmp (argv[1], "rotary_switch") == 0) {
212 return (do_rotary_switch ());
214 if (strcmp (argv[1], "pressure") == 0) {
215 return (do_pressure ());
217 if (strcmp (argv[1], "v_bat") == 0) {
218 return (do_v_bat ());
220 if (strcmp (argv[1], "vfd_id") == 0) {
221 return (do_vfd_id ());
223 if (strcmp (argv[1], "motor_contact") == 0) {
224 return (do_motor_contact ());
226 if (strcmp (argv[1], "crc16") == 0) {
227 return (do_crc16 ());
229 if (strcmp (argv[1], "power_switch") == 0) {
230 return (do_power_switch ());
235 if (strcmp (argv[1], "full_bridge") == 0) {
236 return (do_full_bridge (argv));
238 if (strcmp (argv[1], "dac") == 0) {
239 return (do_dac (argv));
241 if (strcmp (argv[1], "motor") == 0) {
242 return (do_motor (argv));
244 if (strcmp (argv[1], "pwm") == 0) {
245 return (do_pwm (argv));
247 if (strcmp (argv[1], "thermo") == 0) {
248 return (do_thermo (argv));
250 if (strcmp (argv[1], "touch") == 0) {
251 return (do_touch (argv));
253 if (strcmp (argv[1], "serial_number") == 0) {
254 return (do_serial_number (argv));
256 if (strcmp (argv[1], "buzzer") == 0) {
257 return (do_buzzer (argv));
259 if (strcmp (argv[1], "gain") == 0) {
260 return (do_gain (argv));
265 if (strcmp (argv[1], "led") == 0) {
266 return (do_led (argv));
268 if (strcmp (argv[1], "rs485") == 0) {
269 return (do_rs485 (argv));
271 if (strcmp (argv[1], "serial_number") == 0) {
272 return (do_serial_number (argv));
277 if (strcmp (argv[1], "eeprom") == 0) {
278 return (do_eeprom (argv));
283 if (strcmp (argv[1], "eeprom") == 0) {
284 return (do_eeprom (argv));
292 printf ("Usage:\n<command> <parameter1> <parameter2> ...\n");
298 printf ("Stand-alone application for TRAB board function test\n");
299 printf ("Built: %s at %s\n", __DATE__ , __TIME__ );
306 unsigned int result = 0;
310 /***********************************************************
311 DIP switch connection (according to wa4-cpu.sp.301.pdf, page 3):
317 "On" DIP switch position short-circuits the voltage from
318 the input channel (i.e. '0' conversion result means "on").
319 *************************************************************/
321 for (i = 7; i > 3; i--) {
323 if ((adc_val = adc_read (i)) == -1) {
324 printf ("Channel %d could not be read\n", i);
329 * Input voltage (switch open) is 1.8 V.
330 * (Vin_High/VRef)*adc_res = (1,8V/2,5V)*1023) = 736
331 * Set trigger at halve that value.
334 result |= (1 << (i-4));
337 /* print result to console */
339 for (i = 0; i < 4; i++) {
340 if ((result & (1 << i)) == 0)
355 /* VCC5V is connected to channel 2 */
357 if ((result = adc_read (VCC5V)) == -1) {
358 printf ("VCC5V could not be read\n");
363 * Calculate voltage value. Split in two parts because there is no
364 * floating point support. VCC5V is connected over an resistor divider:
365 * VCC5V=ADCval*2,5V/1023*(10K+30K)/10K.
368 printf ("%d", (result & 0x3FF)* 10 / 1023);
369 printf (".%d", ((result & 0x3FF)* 10 % 1023)* 10 / 1023);
370 printf ("%d V\n", (((result & 0x3FF) * 10 % 1023 ) * 10 % 1023)
381 if ((result = adc_read (VCC12V)) == -1) {
382 printf ("VCC12V could not be read\n");
387 * Calculate voltage value. Split in two parts because there is no
388 * floating point support. VCC5V is connected over an resistor divider:
389 * VCC12V=ADCval*2,5V/1023*(30K+270K)/30K.
392 printf ("%d", (result & 0x3FF)* 25 / 1023);
393 printf (".%d V\n", ((result & 0x3FF)* 25 % 1023) * 10 / 1023);
398 static int adc_read (unsigned int channel)
400 int j = 1000; /* timeout value for wait loop in us */
404 padc = S3C2400_GetBase_ADC();
407 padc->ADCCON &= ~ADC_STDBM; /* select normal mode */
408 padc->ADCCON &= ~(0x7 << 3); /* clear the channel bits */
409 padc->ADCCON |= ((channel << 3) | ADC_ENABLE_START);
412 if ((padc->ADCCON & ADC_ENABLE_START) == 0)
418 printf("%s: ADC timeout\n", __FUNCTION__);
419 padc->ADCCON |= ADC_STDBM; /* select standby mode */
423 result = padc->ADCDAT & 0x3FF;
425 padc->ADCCON |= ADC_STDBM; /* select standby mode */
427 debug ("%s: channel %d, result[DIGIT]=%d\n", __FUNCTION__,
428 (padc->ADCCON >> 3) & 0x7, result);
431 * Wait for ADC to be ready for next conversion. This delay value was
432 * estimated, because the datasheet does not specify a value.
440 static void adc_init (void)
444 padc = S3C2400_GetBase_ADC();
446 padc->ADCCON &= ~(0xff << 6); /* clear prescaler bits */
447 padc->ADCCON |= ((65 << 6) | ADC_PRSCEN); /* set prescaler */
450 * Wait some time to avoid problem with very first call of
451 * adc_read(). Without * this delay, sometimes the first read adc
452 * value is 0. Perhaps because the * adjustment of prescaler takes
461 int do_buttons (void)
466 result = *CPLD_BUTTONS; /* read CPLD */
467 debug ("%s: cpld_taster (32 bit) %#x\n", __FUNCTION__, result);
469 /* print result to console */
471 for (i = 16; i <= 19; i++) {
472 if ((result & (1 << i)) == 0)
482 int do_power_switch (void)
486 S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
488 /* configure GPE7 as input */
489 gpio->PECON &= ~(0x3 << (2 * 7));
491 /* signal GPE7 from power switch is low active: 0=on , 1=off */
492 result = ((gpio->PEDAT & (1 << 7)) == (1 << 7)) ? 0 : 1;
495 printf("%d\n", result);
500 int do_fill_level (void)
504 result = *CPLD_FILL_LEVEL; /* read CPLD */
505 debug ("%s: cpld_fuellstand (32 bit) %#x\n", __FUNCTION__, result);
507 /* print result to console */
509 if ((result & (1 << 16)) == 0)
517 int do_rotary_switch (void)
521 * Please note, that the default values of the direction bits are
522 * undefined after reset. So it is a good idea, to make first a dummy
523 * call to this function, to clear the direction bits and set so to
527 result = *CPLD_ROTARY_SWITCH; /* read CPLD */
528 debug ("%s: cpld_inc (32 bit) %#x\n", __FUNCTION__, result);
530 *CPLD_ROTARY_SWITCH |= (3 << 16); /* clear direction bits in CPLD */
532 /* print result to console */
534 if ((result & (1 << 16)) == (1 << 16))
536 if ((result & (1 << 17)) == (1 << 17))
538 if (((result & (1 << 16)) == 0) && ((result & (1 << 17)) == 0))
540 if ((result & (1 << 18)) == 0)
551 long int pcup_old, pccon_old;
553 S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
555 /* try to red vfd board id from the value defined by pull-ups */
557 pcup_old = gpio->PCUP;
558 pccon_old = gpio->PCCON;
560 gpio->PCUP = (gpio->PCUP & 0xFFF0); /* activate GPC0...GPC3 pull-ups */
561 gpio->PCCON = (gpio->PCCON & 0xFFFFFF00); /* configure GPC0...GPC3 as
563 udelay (10); /* allow signals to settle */
564 vfd_board_id = (~gpio->PCDAT) & 0x000F; /* read GPC0...GPC3 port pins */
566 gpio->PCCON = pccon_old;
567 gpio->PCUP = pcup_old;
569 /* print vfd_board_id to console */
571 for (i = 0; i < 4; i++) {
572 if ((vfd_board_id & (1 << i)) == 0)
581 int do_buzzer (char **argv)
585 S3C24X0_TIMERS * const timers = S3C24X0_GetBase_TIMERS();
586 S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
588 /* set prescaler for timer 2, 3 and 4 */
589 timers->TCFG0 &= ~0xFF00;
590 timers->TCFG0 |= 0x0F00;
592 /* set divider for timer 2 */
593 timers->TCFG1 &= ~0xF00;
594 timers->TCFG1 |= 0x300;
597 counter = (PCLK / BUZZER_FREQ) >> 9;
598 timers->ch[2].TCNTB = counter;
599 timers->ch[2].TCMPB = counter / 2;
601 if (strcmp (argv[2], "on") == 0) {
602 debug ("%s: frequency: %d\n", __FUNCTION__,
605 /* configure pin GPD7 as TOUT2 */
606 gpio->PDCON &= ~0xC000;
607 gpio->PDCON |= 0x8000;
610 timers->TCON = (timers->TCON | UPDATE2 | RELOAD2) &
612 timers->TCON = (timers->TCON | START2) & ~UPDATE2;
615 else if (strcmp (argv[2], "off") == 0) {
617 timers->TCON &= ~(START2 | RELOAD2);
619 /* configure GPD7 as output and set to low */
620 gpio->PDCON &= ~0xC000;
621 gpio->PDCON |= 0x4000;
622 gpio->PDDAT &= ~0x80;
626 printf ("%s: invalid parameter %s\n", __FUNCTION__, argv[2]);
631 int do_led (char **argv)
633 S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
635 /* configure PC14 and PC15 as output */
636 gpio->PCCON &= ~(0xF << 28);
637 gpio->PCCON |= (0x5 << 28);
639 /* configure PD0 and PD4 as output */
640 gpio->PDCON &= ~((0x3 << 8) | 0x3);
641 gpio->PDCON |= ((0x1 << 8) | 0x1);
643 switch (simple_strtoul(argv[2], NULL, 10)) {
650 if (strcmp (argv[3], "on") == 0)
651 gpio->PCDAT |= (1 << 14);
653 gpio->PCDAT &= ~(1 << 14);
657 if (strcmp (argv[3], "on") == 0)
658 gpio->PCDAT |= (1 << 15);
660 gpio->PCDAT &= ~(1 << 15);
664 if (strcmp (argv[3], "on") == 0)
665 gpio->PDDAT |= (1 << 0);
667 gpio->PDDAT &= ~(1 << 0);
671 if (strcmp (argv[3], "on") == 0)
672 gpio->PDDAT |= (1 << 4);
674 gpio->PDDAT &= ~(1 << 4);
681 printf ("%s: invalid parameter %s\n", __FUNCTION__, argv[2]);
686 int do_full_bridge (char **argv)
688 S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
690 /* configure PD5 and PD6 as output */
691 gpio->PDCON &= ~((0x3 << 5*2) | (0x3 << 6*2));
692 gpio->PDCON |= ((0x1 << 5*2) | (0x1 << 6*2));
694 if (strcmp (argv[2], "+") == 0) {
695 gpio->PDDAT |= (1 << 5);
696 gpio->PDDAT |= (1 << 6);
699 else if (strcmp (argv[2], "-") == 0) {
700 gpio->PDDAT &= ~(1 << 5);
701 gpio->PDDAT |= (1 << 6);
704 else if (strcmp (argv[2], "off") == 0) {
705 gpio->PDDAT &= ~(1 << 5);
706 gpio->PDDAT &= ~(1 << 6);
709 printf ("%s: invalid parameter %s\n", __FUNCTION__, argv[2]);
713 /* val must be in [0, 4095] */
714 static inline unsigned long tsc2000_to_uv (u16 val)
716 return ((250000 * val) / 4096) * 10;
720 int do_dac (char **argv)
727 if (((brightness = simple_strtoul (argv[2], NULL, 10)) < 0) ||
728 (brightness > 255)) {
729 printf ("%s: invalid parameter %s\n", __FUNCTION__, argv[2]);
732 tsc2000_write(TSC2000_REG_DACCTL, 0x0); /* Power up DAC */
733 tsc2000_write(TSC2000_REG_DAC, brightness & 0xff);
741 unsigned long ret, res;
746 tsc2000_write(TSC2000_REG_ADC, 0x1836);
748 /* now wait for data available */
749 adc_wait_conversion_done();
751 ret = tsc2000_read(TSC2000_REG_BAT1);
752 res = (tsc2000_to_uv(ret) + 1250) / 2500;
753 res += (ERROR_BATTERY * res) / 1000;
756 printf ("%ld", (res / 100));
757 printf (".%ld", ((res % 100) / 10));
758 printf ("%ld V\n", (res % 10));
763 int do_pressure (void)
768 tsc2000_write(TSC2000_REG_ADC, 0x2436);
770 /* now wait for data available */
771 adc_wait_conversion_done();
774 printf ("%d\n", tsc2000_read(TSC2000_REG_AUX2));
779 int do_motor_contact (void)
783 result = *CPLD_FILL_LEVEL; /* read CPLD */
784 debug ("%s: cpld_fuellstand (32 bit) %#x\n", __FUNCTION__, result);
786 /* print result to console */
788 if ((result & (1 << 17)) == 0)
795 int do_motor (char **argv)
797 S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
799 /* Configure I/O port */
800 gpio->PGCON &= ~(0x3 << 0);
801 gpio->PGCON |= (0x1 << 0);
803 if (strcmp (argv[2], "on") == 0) {
804 gpio->PGDAT &= ~(1 << 0);
807 if (strcmp (argv[2], "off") == 0) {
808 gpio->PGDAT |= (1 << 0);
811 printf ("%s: invalid parameter %s\n", __FUNCTION__, argv[2]);
815 static void print_identifier (void)
820 int do_pwm (char **argv)
823 S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
824 S3C24X0_TIMERS * const timers = S3C24X0_GetBase_TIMERS();
826 if (strcmp (argv[2], "on") == 0) {
827 /* configure pin GPD8 as TOUT3 */
828 gpio->PDCON &= ~(0x3 << 8*2);
829 gpio->PDCON |= (0x2 << 8*2);
831 /* set prescaler for timer 2, 3 and 4 */
832 timers->TCFG0 &= ~0xFF00;
833 timers->TCFG0 |= 0x0F00;
835 /* set divider for timer 3 */
836 timers->TCFG1 &= ~(0xf << 12);
837 timers->TCFG1 |= (0x3 << 12);
840 counter = (PCLK / PWM_FREQ) >> 9;
841 timers->ch[3].TCNTB = counter;
842 timers->ch[3].TCMPB = counter / 2;
845 timers->TCON = (timers->TCON | UPDATE3 | RELOAD3) & ~INVERT3;
846 timers->TCON = (timers->TCON | START3) & ~UPDATE3;
849 if (strcmp (argv[2], "off") == 0) {
852 timers->TCON &= ~(START2 | RELOAD2);
854 /* configure pin GPD8 as output and set to 0 */
855 gpio->PDCON &= ~(0x3 << 8*2);
856 gpio->PDCON |= (0x1 << 8*2);
857 gpio->PDDAT &= ~(1 << 8);
860 printf ("%s: invalid parameter %s\n", __FUNCTION__, argv[2]);
865 int do_thermo (char **argv)
871 if (strcmp (argv[2], "all") == 0) {
873 for (i=0; i <= 15; i++) {
874 res = tsc2000_read_channel(i);
876 printf ("c%d: %d\n", i, res);
880 channel = simple_strtoul (argv[2], NULL, 10);
881 res = tsc2000_read_channel(channel);
883 printf ("%d\n", res);
884 return 0; /* return OK */
888 int do_touch (char **argv)
892 if (strcmp (argv[2], "tl") == 0) {
893 #ifdef CONFIG_TOUCH_WAIT_PRESSED
894 touch_wait_pressed();
898 for (i = 0; i < (TOUCH_TIMEOUT * 1000); i++) {
899 if (touch_check_pressed ()) {
902 udelay (1000); /* pause 1 ms */
905 if (!touch_check_pressed()) {
907 printf ("error: touch not pressed\n");
910 #endif /* CONFIG_TOUCH_WAIT_PRESSED */
911 touch_read_x_y (&x, &y);
914 printf ("x=%d y=%d\n", x, y);
915 return touch_write_clibration_values (CALIB_TL, x, y);
917 else if (strcmp (argv[2], "dr") == 0) {
918 #ifdef CONFIG_TOUCH_WAIT_PRESSED
919 touch_wait_pressed();
923 for (i = 0; i < (TOUCH_TIMEOUT * 1000); i++) {
924 if (touch_check_pressed ()) {
927 udelay (1000); /* pause 1 ms */
930 if (!touch_check_pressed()) {
932 printf ("error: touch not pressed\n");
935 #endif /* CONFIG_TOUCH_WAIT_PRESSED */
936 touch_read_x_y (&x, &y);
939 printf ("x=%d y=%d\n", x, y);
941 return touch_write_clibration_values (CALIB_DR, x, y);
943 return 1; /* not "tl", nor "dr", so return error */
947 #ifdef CONFIG_TOUCH_WAIT_PRESSED
948 static void touch_wait_pressed (void)
950 while (!(tsc2000_read(TSC2000_REG_ADC) & TC_PSM));
954 static int touch_check_pressed (void)
956 return (tsc2000_read(TSC2000_REG_ADC) & TC_PSM);
958 #endif /* CONFIG_TOUCH_WAIT_PRESSED */
960 static int touch_write_clibration_values (int calib_point, int x, int y)
962 #if (CONFIG_COMMANDS & CFG_CMD_I2C)
968 if (calib_point == CALIB_TL) {
969 if (i2c_write_multiple (I2C_EEPROM_DEV_ADDR, TOUCH_X0, 1,
973 if (i2c_write_multiple (I2C_EEPROM_DEV_ADDR, TOUCH_Y0, 1,
978 /* verify written values */
979 if (i2c_read_multiple (I2C_EEPROM_DEV_ADDR, TOUCH_X0, 1,
980 (char *)&x_verify, 2)) {
983 if (i2c_read_multiple (I2C_EEPROM_DEV_ADDR, TOUCH_Y0, 1,
984 (char *)&y_verify, 2)) {
987 if ((y != y_verify) || (x != x_verify)) {
989 printf ("error: verify error\n");
992 return 0; /* no error */
994 else if (calib_point == CALIB_DR) {
995 if (i2c_write_multiple (I2C_EEPROM_DEV_ADDR, TOUCH_X1, 1,
999 if (i2c_write_multiple (I2C_EEPROM_DEV_ADDR, TOUCH_Y1, 1,
1004 /* verify written values */
1005 if (i2c_read_multiple (I2C_EEPROM_DEV_ADDR, TOUCH_X1, 1,
1006 (char *)&x_verify, 2)) {
1009 if (i2c_read_multiple (I2C_EEPROM_DEV_ADDR, TOUCH_Y1, 1,
1010 (char *)&y_verify, 2)) {
1013 if ((y != y_verify) || (x != x_verify)) {
1014 print_identifier ();
1015 printf ("error: verify error\n");
1022 printf ("No I2C support enabled (CFG_CMD_I2C), could not write "
1025 #endif /* CFG_CMD_I2C */
1029 static void touch_read_x_y (int *px, int *py)
1031 tsc2000_write(TSC2000_REG_ADC, DEFAULT_ADC | TC_AD0 | TC_AD1);
1032 adc_wait_conversion_done();
1033 *px = tsc2000_read(TSC2000_REG_X);
1035 tsc2000_write(TSC2000_REG_ADC, DEFAULT_ADC | TC_AD2);
1036 adc_wait_conversion_done();
1037 *py = tsc2000_read(TSC2000_REG_Y);
1041 int do_rs485 (char **argv)
1044 char data[RS485_MAX_RECEIVE_BUF_LEN];
1046 if (strcmp (argv[2], "send") == 0) {
1047 return (rs485_send_line (argv[3]));
1049 else if (strcmp (argv[2], "receive") == 0) {
1050 timeout = simple_strtoul(argv[3], NULL, 10);
1051 if (rs485_receive_chars (data, timeout) != 0) {
1052 print_identifier ();
1053 printf ("## nothing received\n");
1057 print_identifier ();
1058 printf ("%s\n", data);
1062 printf ("%s: unknown command %s\n", __FUNCTION__, argv[2]);
1063 return (1); /* unknown command, return error */
1067 static int rs485_send_line (const char *data)
1070 trab_rs485_enable_tx ();
1078 static int rs485_receive_chars (char *data, int timeout)
1081 int receive_count = 0;
1084 trab_rs485_enable_rx ();
1086 /* test every 1 ms for received characters to avoid a receive FIFO
1087 * overrun (@ 38.400 Baud) */
1088 for (i = 0; i < (timeout * 1000); i++) {
1089 while (rs485_tstc ()) {
1090 if (receive_count >= RS485_MAX_RECEIVE_BUF_LEN-1)
1092 *data++ = rs485_getc ();
1095 udelay (1000); /* pause 1 ms */
1097 *data = '\0'; /* terminate string */
1099 if (receive_count == 0)
1106 int do_serial_number (char **argv)
1108 #if (CONFIG_COMMANDS & CFG_CMD_I2C)
1109 unsigned int serial_number;
1111 if (strcmp (argv[2], "read") == 0) {
1112 if (i2c_read (I2C_EEPROM_DEV_ADDR, SERIAL_NUMBER, 1,
1113 (char *)&serial_number, 4)) {
1114 printf ("could not read from eeprom\n");
1117 print_identifier ();
1118 printf ("%08d\n", serial_number);
1121 else if (strcmp (argv[2], "write") == 0) {
1122 serial_number = simple_strtoul(argv[3], NULL, 10);
1123 if (i2c_write (I2C_EEPROM_DEV_ADDR, SERIAL_NUMBER, 1,
1124 (char *)&serial_number, 4)) {
1125 printf ("could not write to eeprom\n");
1130 printf ("%s: unknown command %s\n", __FUNCTION__, argv[2]);
1131 return (1); /* unknown command, return error */
1133 printf ("No I2C support enabled (CFG_CMD_I2C), could not write "
1136 #endif /* CFG_CMD_I2C */
1142 #if (CONFIG_COMMANDS & CFG_CMD_I2C)
1144 char buf[EEPROM_MAX_CRC_BUF];
1146 if (i2c_read (I2C_EEPROM_DEV_ADDR, 0, 1, buf, 60)) {
1147 printf ("could not read from eeprom\n");
1150 crc = 0; /* start value of crc calculation */
1151 crc = updcrc (crc, buf, 60);
1153 print_identifier ();
1154 printf ("crc16=%#04x\n", crc);
1156 if (i2c_write (I2C_EEPROM_DEV_ADDR, CRC16, 1, (char *)&crc,
1158 printf ("could not read from eeprom\n");
1163 printf ("No I2C support enabled (CFG_CMD_I2C), could not write "
1166 #endif /* CFG_CMD_I2C */
1171 * Calculate, intelligently, the CRC of a dataset incrementally given a
1172 * buffer full at a time.
1173 * Initialize crc to 0 for XMODEM, -1 for CCITT.
1176 * newcrc = updcrc( oldcrc, bufadr, buflen )
1177 * unsigned int oldcrc, buflen;
1180 * Compile with -DTEST to generate program that prints CRC of stdin to stdout.
1181 * Compile with -DMAKETAB to print values for crctab to stdout
1184 /* the CRC polynomial. This is used by XMODEM (almost CCITT).
1185 * If you change P, you must change crctab[]'s initial value to what is
1186 * printed by initcrctab()
1190 /* number of bits in CRC: don't change it. */
1193 /* this the number of bits per char: don't change it. */
1196 static unsigned short crctab[1<<B] = { /* as calculated by initcrctab() */
1197 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
1198 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
1199 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
1200 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
1201 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
1202 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
1203 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
1204 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
1205 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
1206 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
1207 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
1208 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
1209 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
1210 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
1211 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
1212 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
1213 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
1214 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
1215 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
1216 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
1217 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
1218 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
1219 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
1220 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
1221 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
1222 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
1223 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
1224 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
1225 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
1226 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
1227 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
1228 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
1231 static unsigned short updcrc(unsigned short icrc, unsigned char *icp,
1234 register unsigned short crc = icrc;
1235 register unsigned char *cp = icp;
1236 register unsigned int cnt = icnt;
1239 crc = (crc<<B) ^ crctab[(crc>>(W-B)) ^ *cp++];
1245 int do_gain (char **argv)
1249 range = simple_strtoul (argv[2], NULL, 10);
1250 if ((range < 1) || (range > 3))
1252 printf ("%s: invalid parameter %s\n", __FUNCTION__, argv[2]);
1256 tsc2000_set_range (range);
1261 int do_eeprom (char **argv)
1263 #if (CONFIG_COMMANDS & CFG_CMD_I2C)
1264 if (strcmp (argv[2], "read") == 0) {
1265 return (trab_eeprom_read (argv));
1268 else if (strcmp (argv[2], "write") == 0) {
1269 return (trab_eeprom_write (argv));
1272 printf ("%s: invalid parameter %s\n", __FUNCTION__, argv[2]);
1275 printf ("No I2C support enabled (CFG_CMD_I2C), could not write "
1278 #endif /* CFG_CMD_I2C */
1281 #if (CONFIG_COMMANDS & CFG_CMD_I2C)
1282 static int trab_eeprom_read (char **argv)
1290 buffer = (uchar *) &value;
1291 addr = simple_strtoul (argv[3], NULL, 10);
1293 len = simple_strtoul (argv[4], NULL, 10);
1294 if ((len < 1) || (len > 4)) {
1295 printf ("%s: invalid parameter %s\n", __FUNCTION__,
1299 for (i = 0; i < len; i++) {
1300 if (i2c_read (I2C_EEPROM_DEV_ADDR, addr+i, 1, buffer+i, 1)) {
1301 printf ("%s: could not read from i2c device %#x"
1302 ", addr %d\n", __FUNCTION__,
1303 I2C_EEPROM_DEV_ADDR, addr);
1307 print_identifier ();
1308 if (strcmp (argv[5], "-") == 0) {
1310 printf ("%d\n", (signed char) value);
1312 printf ("%d\n", (signed short int) value);
1314 printf ("%ld\n", value);
1318 printf ("%d\n", (unsigned char) value);
1320 printf ("%d\n", (unsigned short int) value);
1322 printf ("%ld\n", (unsigned long int) value);
1327 static int trab_eeprom_write (char **argv)
1335 buffer = (uchar *) &value;
1336 addr = simple_strtoul (argv[3], NULL, 10);
1338 len = simple_strtoul (argv[4], NULL, 10);
1339 if ((len < 1) || (len > 4)) {
1340 printf ("%s: invalid parameter %s\n", __FUNCTION__,
1344 value = simple_strtol (argv[5], NULL, 10);
1345 debug ("value=%ld\n", value);
1346 for (i = 0; i < len; i++) {
1347 if (i2c_write (I2C_EEPROM_DEV_ADDR, addr+i, 1, buffer+i, 1)) {
1348 printf ("%s: could not write to i2c device %d"
1349 ", addr %d\n", __FUNCTION__,
1350 I2C_EEPROM_DEV_ADDR, addr);
1354 printf ("chip=%#x, addr+i=%#x+%d=%p, alen=%d, *buffer+i="
1355 "%#x+%d=%p=%#x \n",I2C_EEPROM_DEV_ADDR_DEV_ADDR , addr,
1356 i, addr+i, 1, buffer, i, buffer+i, *(buffer+i));
1358 udelay (30000); /* wait for EEPROM ready */
1363 int i2c_write_multiple (uchar chip, uint addr, int alen,
1364 uchar *buffer, int len)
1369 printf ("%s: addr len other than 1 not supported\n",
1374 for (i = 0; i < len; i++) {
1375 if (i2c_write (chip, addr+i, alen, buffer+i, 1)) {
1376 printf ("%s: could not write to i2c device %d"
1377 ", addr %d\n", __FUNCTION__, chip, addr);
1381 printf ("chip=%#x, addr+i=%#x+%d=%p, alen=%d, *buffer+i="
1382 "%#x+%d=%p=\"%.1s\"\n", chip, addr, i, addr+i,
1383 alen, buffer, i, buffer+i, buffer+i);
1391 int i2c_read_multiple ( uchar chip, uint addr, int alen,
1392 uchar *buffer, int len)
1397 printf ("%s: addr len other than 1 not supported\n",
1402 for (i = 0; i < len; i++) {
1403 if (i2c_read (chip, addr+i, alen, buffer+i, 1)) {
1404 printf ("%s: could not read from i2c device %#x"
1405 ", addr %d\n", __FUNCTION__, chip, addr);
1411 #endif /* CFG_CMD_I2C */