⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 trab_fkt.c

📁 嵌入式试验箱S3C2410的bootloader源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * (C) Copyright 2003 * Martin Krause, TQ-Systems GmbH, martin.krause@tqs.de * * See file CREDITS for list of people who contributed to this * project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */#define	DEBUG#include <common.h>#include <exports.h>#include <s3c2400.h>#include "tsc2000.h"#include "rs485.h"/* * define, to wait for the touch to be pressed, before reading coordinates in * command do_touch. If not defined, an error message is printed, when the * command do_touch is invoked and the touch is not pressed within an specific * interval. */#undef	CONFIG_TOUCH_WAIT_PRESSED/* max time to wait for touch is pressed */#ifndef CONFIG_TOUCH_WAIT_PRESSED#define TOUCH_TIMEOUT   5#endif /* !CONFIG_TOUCH_WAIT_PRESSED *//* assignment of CPU internal ADC channels with TRAB hardware */#define VCC5V   2#define VCC12V  3/* CPLD-Register for controlling TRAB hardware functions */#define CPLD_BUTTONS            ((volatile unsigned long *)0x04020000)#define CPLD_FILL_LEVEL         ((volatile unsigned long *)0x04008000)#define CPLD_ROTARY_SWITCH      ((volatile unsigned long *)0x04018000)#define CPLD_RS485_RE           ((volatile unsigned long *)0x04028000)/* timer configuration bits for buzzer and PWM */#define START2		(1 << 12)#define UPDATE2         (1 << 13)#define INVERT2         (1 << 14)#define RELOAD2         (1 << 15)#define START3		(1 << 16)#define UPDATE3         (1 << 17)#define INVERT3         (1 << 18)#define RELOAD3         (1 << 19)#define PCLK		66000000#define BUZZER_FREQ     1000    /* frequency in Hz */#define PWM_FREQ        500/* definitions of I2C EEPROM device address */#define I2C_EEPROM_DEV_ADDR     0x54/* definition for touch panel calibration points */#define CALIB_TL 0              /* calibration point in (T)op (L)eft corner */#define CALIB_DR 1              /* calibration point in (D)own (R)ight corner *//* EEPROM address map */#define SERIAL_NUMBER           8#define TOUCH_X0                52#define TOUCH_Y0                54#define TOUCH_X1                56#define TOUCH_Y1                58#define CRC16                   60/* EEPROM stuff */#define EEPROM_MAX_CRC_BUF      64/* RS485 stuff */#define RS485_MAX_RECEIVE_BUF_LEN  100/* Bit definitions for ADCCON */#define ADC_ENABLE_START     0x1#define ADC_READ_START       0x2#define ADC_STDBM            0x4#define ADC_INP_AIN0         (0x0 << 3)#define ADC_INP_AIN1         (0x1 << 3)#define ADC_INP_AIN2         (0x2 << 3)#define ADC_INP_AIN3         (0x3 << 3)#define ADC_INP_AIN4         (0x4 << 3)#define ADC_INP_AIN5         (0x5 << 3)#define ADC_INP_AIN6         (0x6 << 3)#define ADC_INP_AIN7         (0x7 << 3)#define ADC_PRSCEN           0x4000#define ADC_ECFLG            0x8000/* function test functions */int do_dip (void);int do_info (void);int do_vcc5v (void);int do_vcc12v (void);int do_buttons (void);int do_fill_level (void);int do_rotary_switch (void);int do_pressure (void);int do_v_bat (void);int do_vfd_id (void);int do_buzzer (char **);int do_led (char **);int do_full_bridge (char **);int do_dac (char **);int do_motor_contact (void);int do_motor (char **);int do_pwm (char **);int do_thermo (char **);int do_touch (char **);int do_rs485 (char **);int do_serial_number (char **);int do_crc16 (void);int do_power_switch (void);int do_gain (char **);int do_eeprom (char **);/* helper functions */static void adc_init (void);static int adc_read (unsigned int channel);static void print_identifier (void);#ifdef CONFIG_TOUCH_WAIT_PRESSEDstatic void touch_wait_pressed (void);#elsestatic int touch_check_pressed (void);#endif /* CONFIG_TOUCH_WAIT_PRESSED */static void touch_read_x_y (int *x, int *y);static int touch_write_clibration_values (int calib_point, int x, int y);static int rs485_send_line (const char *data);static int rs485_receive_chars (char *data, int timeout);static unsigned short updcrc(unsigned short icrc, unsigned char *icp,			     unsigned int icnt);#if (CONFIG_COMMANDS & CFG_CMD_I2C)static int trab_eeprom_read (char **argv);static int trab_eeprom_write (char **argv);int i2c_write_multiple (uchar chip, uint addr, int alen, uchar *buffer,			int len);int i2c_read_multiple ( uchar chip, uint addr, int alen, uchar *buffer,			int len);#endif /* CFG_CMD_I2C *//* * TRAB board specific commands. Especially commands for burn-in and function * test. */int trab_fkt (int argc, char *argv[]){	int i;	app_startup(argv);	if (get_version () != XF_VERSION) {		printf ("Wrong XF_VERSION. Please re-compile with actual "			"u-boot sources\n");		printf ("Example expects ABI version %d\n", XF_VERSION);		printf ("Actual U-Boot ABI version %d\n", (int)get_version());		return 1;	}	debug ("argc = %d\n", argc);	for (i=0; i<=argc; ++i) {		debug ("argv[%d] = \"%s\"\n", i, argv[i] ? argv[i] : "<NULL>");	}	adc_init ();	switch (argc) {	case 0:	case 1:		break;	case 2:		if (strcmp (argv[1], "info") == 0) {			return (do_info ());		}		if (strcmp (argv[1], "dip") == 0) {			return (do_dip ());		}		if (strcmp (argv[1], "vcc5v") == 0) {			return (do_vcc5v ());		}		if (strcmp (argv[1], "vcc12v") == 0) {			return (do_vcc12v ());		}		if (strcmp (argv[1], "buttons") == 0) {			return (do_buttons ());		}		if (strcmp (argv[1], "fill_level") == 0) {			return (do_fill_level ());		}		if (strcmp (argv[1], "rotary_switch") == 0) {			return (do_rotary_switch ());		}		if (strcmp (argv[1], "pressure") == 0) {			return (do_pressure ());		}		if (strcmp (argv[1], "v_bat") == 0) {			return (do_v_bat ());		}		if (strcmp (argv[1], "vfd_id") == 0) {			return (do_vfd_id ());		}		if (strcmp (argv[1], "motor_contact") == 0) {			return (do_motor_contact ());		}		if (strcmp (argv[1], "crc16") == 0) {			return (do_crc16 ());		}		if (strcmp (argv[1], "power_switch") == 0) {			return (do_power_switch ());		}		break;	case 3:		if (strcmp (argv[1], "full_bridge") == 0) {			return (do_full_bridge (argv));		}		if (strcmp (argv[1], "dac") == 0) {			return (do_dac (argv));		}		if (strcmp (argv[1], "motor") == 0) {			return (do_motor (argv));		}		if (strcmp (argv[1], "pwm") == 0) {			return (do_pwm (argv));		}		if (strcmp (argv[1], "thermo") == 0) {			return (do_thermo (argv));		}		if (strcmp (argv[1], "touch") == 0) {			return (do_touch (argv));		}		if (strcmp (argv[1], "serial_number") == 0) {			return (do_serial_number (argv));		}		if (strcmp (argv[1], "buzzer") == 0) {			return (do_buzzer (argv));		}		if (strcmp (argv[1], "gain") == 0) {			return (do_gain (argv));		}		break;	case 4:		if (strcmp (argv[1], "led") == 0) {			return (do_led (argv));		}		if (strcmp (argv[1], "rs485") == 0) {			return (do_rs485 (argv));		}		if (strcmp (argv[1], "serial_number") == 0) {			return (do_serial_number (argv));		}		break;	case 5:		if (strcmp (argv[1], "eeprom") == 0) {			return (do_eeprom (argv));		}		break;	case 6:		if (strcmp (argv[1], "eeprom") == 0) {			return (do_eeprom (argv));		}		break;	default:		break;	}	printf ("Usage:\n<command> <parameter1> <parameter2> ...\n");	return 1;}int do_info (void){	printf ("Stand-alone application for TRAB board function test\n");	printf ("Built: %s at %s\n", __DATE__ , __TIME__ );	return 0;}int do_dip (void){	unsigned int result = 0;	int adc_val;	int i;	/***********************************************************	 DIP switch connection (according to wa4-cpu.sp.301.pdf, page 3):	   SW1 - AIN4	   SW2 - AIN5	   SW3 - AIN6	   SW4 - AIN7	   "On" DIP switch position short-circuits the voltage from	   the input channel (i.e. '0' conversion result means "on").	*************************************************************/	for (i = 7; i > 3; i--) {		if ((adc_val = adc_read (i)) == -1) {			printf ("Channel %d could not be read\n", i);			return 1;		}		/*		 * Input voltage (switch open) is 1.8 V.		 * (Vin_High/VRef)*adc_res = (1,8V/2,5V)*1023) = 736		 * Set trigger at halve that value.		 */		if (adc_val < 368)			result |= (1 << (i-4));	}	/* print result to console */	print_identifier ();	for (i = 0; i < 4; i++) {		if ((result & (1 << i)) == 0)			printf("0");		else			printf("1");	}	printf("\n");	return 0;}int do_vcc5v (void){	int result;	/* VCC5V is connected to channel 2 */	if ((result = adc_read (VCC5V)) == -1) {		printf ("VCC5V could not be read\n");		return 1;	}	/*	 * Calculate voltage value. Split in two parts because there is no	 * floating point support.  VCC5V is connected over an resistor divider:	 * VCC5V=ADCval*2,5V/1023*(10K+30K)/10K.	 */	print_identifier ();	printf ("%d", (result & 0x3FF)* 10 / 1023);	printf (".%d", ((result & 0x3FF)* 10 % 1023)* 10 / 1023);	printf ("%d V\n", (((result & 0x3FF) * 10 % 1023 ) * 10 % 1023)		* 10 / 1024);	return 0;}int do_vcc12v (void){	int result;	if ((result = adc_read (VCC12V)) == -1) {		printf ("VCC12V could not be read\n");		return 1;	}	/*	 * Calculate voltage value. Split in two parts because there is no	 * floating point support.  VCC5V is connected over an resistor divider:	 * VCC12V=ADCval*2,5V/1023*(30K+270K)/30K.	 */	print_identifier ();	printf ("%d", (result & 0x3FF)* 25 / 1023);	printf (".%d V\n", ((result & 0x3FF)* 25 % 1023) * 10 / 1023);	return 0;}static int adc_read (unsigned int channel){	int j = 1000; /* timeout value for wait loop in us */	int result;	S3C2400_ADC *padc;	padc = S3C2400_GetBase_ADC();	channel &= 0x7;	padc->ADCCON &= ~ADC_STDBM; /* select normal mode */	padc->ADCCON &= ~(0x7 << 3); /* clear the channel bits */	padc->ADCCON |= ((channel << 3) | ADC_ENABLE_START);	while (j--) {		if ((padc->ADCCON & ADC_ENABLE_START) == 0)			break;		udelay (1);	}	if (j == 0) {		printf("%s: ADC timeout\n", __FUNCTION__);		padc->ADCCON |= ADC_STDBM; /* select standby mode */		return -1;	}	result = padc->ADCDAT & 0x3FF;	padc->ADCCON |= ADC_STDBM; /* select standby mode */	debug ("%s: channel %d, result[DIGIT]=%d\n", __FUNCTION__,	       (padc->ADCCON >> 3) & 0x7, result);	/*	 * Wait for ADC to be ready for next conversion. This delay value was	 * estimated, because the datasheet does not specify a value.	 */	udelay (1000);	return (result);}static void adc_init (void){	S3C2400_ADC *padc;	padc = S3C2400_GetBase_ADC();	padc->ADCCON &= ~(0xff << 6); /* clear prescaler bits */	padc->ADCCON |= ((65 << 6) | ADC_PRSCEN); /* set prescaler */	/*	 * Wait some time to avoid problem with very first call of	 * adc_read(). Without * this delay, sometimes the first read adc	 * value is 0. Perhaps because the * adjustment of prescaler takes	 * some clock cycles?	 */	udelay (1000);	return;}int do_buttons (void){	int result;	int i;	result = *CPLD_BUTTONS; /* read CPLD */	debug ("%s: cpld_taster (32 bit) %#x\n", __FUNCTION__, result);	/* print result to console */	print_identifier ();	for (i = 16; i <= 19; i++) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -