📄 trab_fkt.c
字号:
/* * (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 + -