diff options
Diffstat (limited to 'board/trab/tsc2000.c')
-rw-r--r-- | board/trab/tsc2000.c | 366 |
1 files changed, 0 insertions, 366 deletions
diff --git a/board/trab/tsc2000.c b/board/trab/tsc2000.c deleted file mode 100644 index 426ed9c..0000000 --- a/board/trab/tsc2000.c +++ /dev/null @@ -1,366 +0,0 @@ -/* - * Functions to access the TSC2000 controller on TRAB board (used for scanning - * thermo sensors) - * - * Copyright (C) 2003 Martin Krause, TQ-Systems GmbH, martin.krause@tqs.de - * - * Copyright (C) 2002 DENX Software Engineering, Wolfgang Denk, wd@denx.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 - */ - -#include <common.h> -#include <asm/arch/s3c24x0_cpu.h> -#include <asm/io.h> -#include <div64.h> -#include "tsc2000.h" - -#include "Pt1000_temp_data.h" - -/* helper function */ -#define abs(value) (((value) < 0) ? ((value)*-1) : (value)) - -/* - * Maximal allowed deviation between two immediate meassurments of an analog - * thermo channel. 1 DIGIT = 0.0276 °C. This is used to filter sporadic - * "jumps" in measurment. - */ -#define MAX_DEVIATION 18 /* unit: DIGITs of adc; 18 DIGIT = 0.5 °C */ - -void tsc2000_spi_init(void) -{ - struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio(); - struct s3c24x0_spi * const spi = s3c24x0_get_base_spi(); - int i; - - /* Configure I/O ports. */ - gpio->pdcon = (gpio->pdcon & 0xF3FFFF) | 0x040000; - gpio->pgcon = (gpio->pgcon & 0x0F3FFF) | 0x008000; - gpio->pgcon = (gpio->pgcon & 0x0CFFFF) | 0x020000; - gpio->pgcon = (gpio->pgcon & 0x03FFFF) | 0x080000; - - CLR_CS_TOUCH(); - - spi->ch[0].sppre = 0x1F; /* Baud-rate ca. 514kHz */ - spi->ch[0].sppin = 0x01; /* SPI-MOSI holds Level after last bit */ - spi->ch[0].spcon = 0x1A; /* Polling, Prescaler, Master, CPOL=0, - CPHA=1 */ - - /* Dummy byte ensures clock to be low. */ - for (i = 0; i < 10; i++) { - spi->ch[0].sptdat = 0xFF; - } - spi_wait_transmit_done(); -} - - -void spi_wait_transmit_done(void) -{ - struct s3c24x0_spi * const spi = s3c24x0_get_base_spi(); - - while (!(spi->ch[0].spsta & 0x01)) /* wait until transfer is done */ - ; -} - - -void tsc2000_write(unsigned short reg, unsigned short data) -{ - struct s3c24x0_spi * const spi = s3c24x0_get_base_spi(); - unsigned int command; - - SET_CS_TOUCH(); - command = reg; - spi->ch[0].sptdat = (command & 0xFF00) >> 8; - spi_wait_transmit_done(); - spi->ch[0].sptdat = (command & 0x00FF); - spi_wait_transmit_done(); - spi->ch[0].sptdat = (data & 0xFF00) >> 8; - spi_wait_transmit_done(); - spi->ch[0].sptdat = (data & 0x00FF); - spi_wait_transmit_done(); - - CLR_CS_TOUCH(); -} - - -unsigned short tsc2000_read (unsigned short reg) -{ - unsigned short command, data; - struct s3c24x0_spi * const spi = s3c24x0_get_base_spi(); - - SET_CS_TOUCH(); - command = 0x8000 | reg; - - spi->ch[0].sptdat = (command & 0xFF00) >> 8; - spi_wait_transmit_done(); - spi->ch[0].sptdat = (command & 0x00FF); - spi_wait_transmit_done(); - - spi->ch[0].sptdat = 0xFF; - spi_wait_transmit_done(); - data = spi->ch[0].sprdat; - spi->ch[0].sptdat = 0xFF; - spi_wait_transmit_done(); - - CLR_CS_TOUCH(); - return (spi->ch[0].sprdat & 0x0FF) | (data << 8); -} - - -void tsc2000_set_mux (unsigned int channel) -{ - struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio(); - - CLR_MUX1_ENABLE; CLR_MUX2_ENABLE; - CLR_MUX3_ENABLE; CLR_MUX4_ENABLE; - switch (channel) { - case 0: - CLR_MUX0; CLR_MUX1; - SET_MUX1_ENABLE; - break; - case 1: - SET_MUX0; CLR_MUX1; - SET_MUX1_ENABLE; - break; - case 2: - CLR_MUX0; SET_MUX1; - SET_MUX1_ENABLE; - break; - case 3: - SET_MUX0; SET_MUX1; - SET_MUX1_ENABLE; - break; - case 4: - CLR_MUX0; CLR_MUX1; - SET_MUX2_ENABLE; - break; - case 5: - SET_MUX0; CLR_MUX1; - SET_MUX2_ENABLE; - break; - case 6: - CLR_MUX0; SET_MUX1; - SET_MUX2_ENABLE; - break; - case 7: - SET_MUX0; SET_MUX1; - SET_MUX2_ENABLE; - break; - case 8: - CLR_MUX0; CLR_MUX1; - SET_MUX3_ENABLE; - break; - case 9: - SET_MUX0; CLR_MUX1; - SET_MUX3_ENABLE; - break; - case 10: - CLR_MUX0; SET_MUX1; - SET_MUX3_ENABLE; - break; - case 11: - SET_MUX0; SET_MUX1; - SET_MUX3_ENABLE; - break; - case 12: - CLR_MUX0; CLR_MUX1; - SET_MUX4_ENABLE; - break; - case 13: - SET_MUX0; CLR_MUX1; - SET_MUX4_ENABLE; - break; - case 14: - CLR_MUX0; SET_MUX1; - SET_MUX4_ENABLE; - break; - case 15: - SET_MUX0; SET_MUX1; - SET_MUX4_ENABLE; - break; - default: - CLR_MUX0; CLR_MUX1; - } -} - - -void tsc2000_set_range (unsigned int range) -{ - struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio(); - - switch (range) { - case 1: - CLR_SEL_TEMP_V_0; SET_SEL_TEMP_V_1; - CLR_SEL_TEMP_V_2; CLR_SEL_TEMP_V_3; - break; - case 2: - CLR_SEL_TEMP_V_0; CLR_SEL_TEMP_V_1; - CLR_SEL_TEMP_V_2; SET_SEL_TEMP_V_3; - break; - case 3: - SET_SEL_TEMP_V_0; CLR_SEL_TEMP_V_1; - SET_SEL_TEMP_V_2; CLR_SEL_TEMP_V_3; - break; - } -} - - -u16 tsc2000_read_channel (unsigned int channel) -{ - u16 res; - - tsc2000_set_mux(channel); - udelay(20 * TSC2000_DELAY_BASE); - - tsc2000_write(TSC2000_REG_ADC, 0x2036); - adc_wait_conversion_done (); - res = tsc2000_read(TSC2000_REG_AUX1); - return res; -} - - -s32 tsc2000_contact_temp (void) -{ - long adc_pt1000, offset; - long u_pt1000; - long contact_temp; - long temp1, temp2; - - tsc2000_reg_init (); - tsc2000_set_range (3); - - /* - * Because of sporadic "jumps" in the measured adc values every - * channel is read two times. If there is a significant difference - * between the two measurements, then print an error and do a third - * measurement, because it is very unlikely that a successive third - * measurement goes also wrong. - */ - temp1 = tsc2000_read_channel (14); - temp2 = tsc2000_read_channel (14); - if (abs(temp2 - temp1) < MAX_DEVIATION) - adc_pt1000 = temp2; - else { - printf ("%s: read adc value (channel 14) exceeded max allowed " - "deviation: %d * 0.0276 °C\n", - __FUNCTION__, MAX_DEVIATION); - printf ("adc value 1: %ld DIGITs\nadc value 2: %ld DIGITs\n", - temp1, temp2); - adc_pt1000 = tsc2000_read_channel (14); - printf ("use (third read) adc value: adc_pt1000 = " - "%ld DIGITs\n", adc_pt1000); - } - debug ("read channel 14 (pt1000 adc value): %ld\n", adc_pt1000); - - temp1 = tsc2000_read_channel (15); - temp2 = tsc2000_read_channel (15); - if (abs(temp2 - temp1) < MAX_DEVIATION) - offset = temp2; - else { - printf ("%s: read adc value (channel 15) exceeded max allowed " - "deviation: %d * 0.0276 °C\n", - __FUNCTION__, MAX_DEVIATION); - printf ("adc value 1: %ld DIGITs\nadc value 2: %ld DIGITs\n", - temp1, temp2); - offset = tsc2000_read_channel (15); - printf ("use (third read) adc value: offset = %ld DIGITs\n", - offset); - } - debug ("read channel 15 (offset): %ld\n", offset); - - /* - * Formula for calculating voltage drop on PT1000 resistor: u_pt1000 = - * x_range3 * (adc_raw - offset) / 10. Formula to calculate x_range3: - * x_range3 = (2500 * (1000000 + err_vref + err_amp3)) / (4095*6). The - * error correction Values err_vref and err_amp3 are assumed as 0 in - * u-boot, because this could cause only a very small error (< 1%). - */ - u_pt1000 = (101750 * (adc_pt1000 - offset)) / 10; - debug ("u_pt1000: %ld\n", u_pt1000); - - if (tsc2000_interpolate(u_pt1000, Pt1000_temp_table, - &contact_temp) == -1) { - printf ("%s: error interpolating PT1000 vlaue\n", - __FUNCTION__); - return (-1000); - } - debug ("contact_temp: %ld\n", contact_temp); - - return contact_temp; -} - - -void tsc2000_reg_init (void) -{ - struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio(); - - tsc2000_write(TSC2000_REG_ADC, 0x2036); - tsc2000_write(TSC2000_REG_REF, 0x0011); - tsc2000_write(TSC2000_REG_DACCTL, 0x0000); - - CON_MUX0; - CON_MUX1; - - CON_MUX1_ENABLE; - CON_MUX2_ENABLE; - CON_MUX3_ENABLE; - CON_MUX4_ENABLE; - - CON_SEL_TEMP_V_0; - CON_SEL_TEMP_V_1; - CON_SEL_TEMP_V_2; - CON_SEL_TEMP_V_3; - - tsc2000_set_mux(0); - tsc2000_set_range(0); -} - - -int tsc2000_interpolate(long value, long data[][2], long *result) -{ - int i; - unsigned long long val; - - /* the data is sorted and the first element is upper - * limit so we can easily check for out-of-band values - */ - if (data[0][0] < value || data[1][0] > value) - return -1; - - i = 1; - while (data[i][0] < value) - i++; - - /* To prevent overflow we have to store the intermediate - result in 'long long'. - */ - - val = ((unsigned long long)(data[i][1] - data[i-1][1]) - * (unsigned long long)(value - data[i-1][0])); - do_div(val, (data[i][0] - data[i-1][0])); - *result = data[i-1][1] + val; - - return 0; -} - - -void adc_wait_conversion_done(void) -{ - while (!(tsc2000_read(TSC2000_REG_ADC) & (1 << 14))); -} |