*/
#include <common.h>
-#include <s3c2400.h>
+#include <asm/arch/s3c24x0_cpu.h>
+#include <asm/io.h>
+#include <div64.h>
#include "tsc2000.h"
#include "Pt1000_temp_data.h"
-void spi_init(void)
+/* 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)
{
- S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
- S3C24X0_SPI * const spi = S3C24X0_GetBase_SPI();
+ struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio();
+ struct s3c24x0_spi * const spi = s3c24x0_get_base_spi();
int i;
/* Configure I/O ports. */
void spi_wait_transmit_done(void)
{
- S3C24X0_SPI * const spi = S3C24X0_GetBase_SPI();
+ 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)
{
- S3C24X0_SPI * const spi = S3C24X0_GetBase_SPI();
+ struct s3c24x0_spi * const spi = s3c24x0_get_base_spi();
unsigned int command;
SET_CS_TOUCH();
unsigned short tsc2000_read (unsigned short reg)
{
unsigned short command, data;
- S3C24X0_SPI * const spi = S3C24X0_GetBase_SPI();
+ struct s3c24x0_spi * const spi = s3c24x0_get_base_spi();
SET_CS_TOUCH();
command = 0x8000 | reg;
void tsc2000_set_mux (unsigned int channel)
{
- S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
+ struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio();
CLR_MUX1_ENABLE; CLR_MUX2_ENABLE;
CLR_MUX3_ENABLE; CLR_MUX4_ENABLE;
void tsc2000_set_range (unsigned int range)
{
- S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
+ struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio();
switch (range) {
case 1:
u16 res;
tsc2000_set_mux(channel);
- udelay(3 * TSC2000_DELAY_BASE);
+ udelay(20 * TSC2000_DELAY_BASE);
tsc2000_write(TSC2000_REG_ADC, 0x2036);
adc_wait_conversion_done ();
long adc_pt1000, offset;
long u_pt1000;
long contact_temp;
-
+ long temp1, temp2;
tsc2000_reg_init ();
tsc2000_set_range (3);
- adc_pt1000 = tsc2000_read_channel (14);
+ /*
+ * 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);
- offset = tsc2000_read_channel (15);
+ 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);
/*
void tsc2000_reg_init (void)
{
- S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
+ struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio();
tsc2000_write(TSC2000_REG_ADC, 0x2036);
tsc2000_write(TSC2000_REG_REF, 0x0011);
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
result in 'long long'.
*/
- *result = data[i-1][1] +
- ((unsigned long long)(data[i][1] - data[i-1][1])
- * (unsigned long long)(value - data[i-1][0]))
- / (data[i][0] - data[i-1][0]);
+ 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;
}