summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--firmware/SOURCES2
-rw-r--r--firmware/drivers/tsc200x.c64
-rw-r--r--firmware/export/tsc200x.h34
-rw-r--r--firmware/target/arm/tcc780x/cowond2/button-cowond2.c139
-rw-r--r--firmware/target/arm/tcc780x/cowond2/button-target.h1
-rw-r--r--firmware/target/arm/tcc780x/cowond2/power-cowond2.c3
-rw-r--r--firmware/target/arm/tcc780x/cowond2/touchscreen-cowond2.c233
-rw-r--r--firmware/target/arm/tcc780x/cowond2/touchscreen-target.h30
8 files changed, 369 insertions, 137 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES
index db468335f2..2cb97a241b 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -1256,12 +1256,14 @@ target/arm/tcc77x/iaudio7/audio-iaudio7.c
drivers/nand_id.c
drivers/pcf50606.c
drivers/pcf50635.c
+drivers/tsc200x.c
target/arm/lcd-as-memframe.S
target/arm/tcc780x/adc-tcc780x.c
target/arm/tcc780x/system-tcc780x.c
target/arm/tcc780x/kernel-tcc780x.c
target/arm/tcc780x/sd-tcc780x.c
target/arm/tcc780x/cowond2/button-cowond2.c
+target/arm/tcc780x/cowond2/touchscreen-cowond2.c
target/arm/tcc780x/cowond2/lcd-cowond2.c
target/arm/tcc780x/cowond2/power-cowond2.c
target/arm/tcc780x/cowond2/powermgmt-cowond2.c
diff --git a/firmware/drivers/tsc200x.c b/firmware/drivers/tsc200x.c
new file mode 100644
index 0000000000..4af8118d26
--- /dev/null
+++ b/firmware/drivers/tsc200x.c
@@ -0,0 +1,64 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2009 by Jonas Aaberg, Rob Purchase
+ *
+ * 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "tsc200x.h"
+#include "cpu.h"
+#include "i2c.h"
+
+#define TSC_SLAVE_ADDR 0x90
+#define TSC_REG_READ_X 0x80
+#define TSC_REG_READ_Y 0x90
+
+#ifdef COWON_D2
+#define TSCPRES_GPIO GPIOC
+#define TSCPRES_GPIO_DIR GPIOC_DIR
+#define TSCPRES_BIT (1<<26)
+#endif
+
+void tsc200x_init(void)
+{
+ /* Configure GPIOC 26 (TSC pressed) for input */
+ TSCPRES_GPIO_DIR &= ~TSCPRES_BIT;
+}
+
+bool tsc200x_is_pressed(void)
+{
+ return !(TSCPRES_GPIO & TSCPRES_BIT);
+}
+
+bool tsc200x_read_coords(short* x, short* y)
+{
+ int rc = 0;
+ unsigned char x_val[2], y_val[2];
+
+ rc |= i2c_readmem(TSC_SLAVE_ADDR, TSC_REG_READ_Y, y_val, 2);
+ rc |= i2c_readmem(TSC_SLAVE_ADDR, TSC_REG_READ_X, x_val, 2);
+
+ if (rc >= 0)
+ {
+ /* Keep the 10 most significant bits */
+ *x = ((((short)x_val[0]) << 8) | x_val[1]) >> 6;
+ *y = ((((short)y_val[0]) << 8) | y_val[1]) >> 6;
+ return true;
+ }
+
+ return false;
+}
diff --git a/firmware/export/tsc200x.h b/firmware/export/tsc200x.h
new file mode 100644
index 0000000000..a2705a0553
--- /dev/null
+++ b/firmware/export/tsc200x.h
@@ -0,0 +1,34 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2009 by Rob Purchase
+ *
+ * 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#ifndef _TSC200X_H
+#define _TSC200X_H
+
+#include <stdbool.h>
+
+/* The TI TSC2003 and TSC2007 touchscreen controllers are largely compatible,
+ except the TSC2007 filters coordinates using a "median windowed average". */
+
+void tsc200x_init(void);
+bool tsc200x_is_pressed(void);
+bool tsc200x_read_coords(short* x, short* y);
+
+#endif /* _TSC200X_H */
diff --git a/firmware/target/arm/tcc780x/cowond2/button-cowond2.c b/firmware/target/arm/tcc780x/cowond2/button-cowond2.c
index 30d81fa059..df2ea1f307 100644
--- a/firmware/target/arm/tcc780x/cowond2/button-cowond2.c
+++ b/firmware/target/arm/tcc780x/cowond2/button-cowond2.c
@@ -23,94 +23,9 @@
#include "cpu.h"
#include "button.h"
#include "adc.h"
-#include "pcf50606.h"
#include "backlight.h"
-#include "touchscreen.h"
-#include "stdlib.h"
-
-#define NO_OF_TOUCH_DATA 5
-
-static bool touch_available = false;
-static short x[NO_OF_TOUCH_DATA], y[NO_OF_TOUCH_DATA];
-
-/* comparator for qsort */
-static int short_cmp(const void *a, const void *b)
-{
- return *(short*)a - *(short*)b;
-}
-
-void button_read_touch()
-{
- static long last_touch_interrupt = 0;
- static int touch_data_index = 0;
-
- /* don't read the coordinates when hold is enabled */
- if (button_hold()) return;
-
- /* put the touchscreen into idle mode */
- pcf50606_write(PCF5060X_ADCC1, 0);
-
- if (TIME_AFTER(current_tick, last_touch_interrupt + 1))
- {
- /* resets the index if the last touch could not be read 5 times */
- touch_data_index = 0;
- }
-
- /* here the touch coordinates are read 5 times */
- /* they will be sorted and the middle one will be used */
- pcf50606_read_adc(PCF5060X_ADC_TSC_XY,
- &x[touch_data_index], &y[touch_data_index]);
-
- touch_data_index++;
-
- if (touch_data_index > NO_OF_TOUCH_DATA - 1)
- {
- /* coordinates 5 times read */
- touch_available = true;
- touch_data_index = 0;
- }
- else
- {
- /* put the touchscreen back into the interrupt mode */
- pcf50606_write(PCF5060X_ADCC1, 1);
- }
- last_touch_interrupt = current_tick;
-}
-
-struct touch_calibration_point {
- short px_x; /* known pixel value */
- short px_y;
- short val_x; /* touchscreen value at the known pixel */
- short val_y;
-};
-
-static struct touch_calibration_point topleft, bottomright;
-
-static int touch_to_pixels(short val_x, short val_y)
-{
- short x,y;
-
- x=val_x;
- y=val_y;
-
- x = (x-topleft.val_x)*(bottomright.px_x - topleft.px_x)
- / (bottomright.val_x - topleft.val_x) + topleft.px_x;
-
- y = (y-topleft.val_y)*(bottomright.px_y - topleft.px_y)
- / (bottomright.val_y - topleft.val_y) + topleft.px_y;
-
- if (x < 0)
- x = 0;
- else if (x>=LCD_WIDTH)
- x=LCD_WIDTH-1;
-
- if (y < 0)
- y = 0;
- else if (y>=LCD_HEIGHT)
- y=LCD_HEIGHT-1;
-
- return (x<<16)|y;
-}
+#include "touchscreen-target.h"
+#include <stdlib.h>
void button_init_device(void)
{
@@ -120,18 +35,7 @@ void button_init_device(void)
/* Configure GPIOB 4 (button pressed) for input */
GPIOB_DIR &= ~0x10;
- touch_available = false;
-
- /* Arbitrary touchscreen calibration */
- topleft.px_x = 0;
- topleft.px_y = 0;
- topleft.val_x = 50;
- topleft.val_y = 50;
-
- bottomright.px_x = LCD_WIDTH;
- bottomright.px_y = LCD_HEIGHT;
- bottomright.val_x = 980;
- bottomright.val_y = 980;
+ touchscreen_init_device();
}
bool button_hold(void)
@@ -147,8 +51,6 @@ int button_read_device(int *data)
static bool hold_button = false;
bool hold_button_old;
- static bool touch_hold = false;
- static long last_touch = 0;
*data = old_data;
@@ -185,40 +87,7 @@ int button_read_device(int *data)
}
}
- if (touch_available || touch_hold)
- {
- short x_touch, y_touch;
- static short last_x = 0, last_y = 0;
-
- if (touch_hold)
- {
- /* get rid of very fast unintended double touches */
- x_touch = last_x;
- y_touch = last_y;
- }
- else
- {
- /* sort the 5 data taken and use the median value */
- qsort(x, NO_OF_TOUCH_DATA, sizeof(short), short_cmp);
- qsort(y, NO_OF_TOUCH_DATA, sizeof(short), short_cmp);
- x_touch = last_x = x[(NO_OF_TOUCH_DATA - 1)/2];
- y_touch = last_y = y[(NO_OF_TOUCH_DATA - 1)/2];
- last_touch = current_tick;
- touch_hold = true;
- touch_available = false;
- }
- old_data = *data = touch_to_pixels(x_touch, y_touch);
- btn |= touchscreen_to_pixels((*data&0xffff0000)>>16,
- (*data&0x0000ffff),
- data);
- }
-
- if (TIME_AFTER(current_tick, last_touch + 10))
- {
- /* put the touchscreen back into interrupt mode */
- touch_hold = false;
- pcf50606_write(PCF5060X_ADCC1, 1);
- }
+ btn |= touchscreen_read_device(data, &old_data);
if (!(GPIOA & 0x4))
btn |= BUTTON_POWER;
diff --git a/firmware/target/arm/tcc780x/cowond2/button-target.h b/firmware/target/arm/tcc780x/cowond2/button-target.h
index ce6e2884a9..7d3736fe67 100644
--- a/firmware/target/arm/tcc780x/cowond2/button-target.h
+++ b/firmware/target/arm/tcc780x/cowond2/button-target.h
@@ -30,7 +30,6 @@
bool button_hold(void);
void button_init_device(void);
int button_read_device(int *data);
-void button_read_touch(void);
/* Main unit's buttons */
#define BUTTON_POWER 0x00000001
diff --git a/firmware/target/arm/tcc780x/cowond2/power-cowond2.c b/firmware/target/arm/tcc780x/cowond2/power-cowond2.c
index d5f4ec9768..dfd692ecab 100644
--- a/firmware/target/arm/tcc780x/cowond2/power-cowond2.c
+++ b/firmware/target/arm/tcc780x/cowond2/power-cowond2.c
@@ -25,6 +25,7 @@
#include "pcf50606.h"
#include "pcf50635.h"
#include "button-target.h"
+#include "touchscreen-target.h"
#include "tuner.h"
#include "backlight-target.h"
#include "powermgmt.h"
@@ -101,7 +102,7 @@ void EXT3(void)
if (data[2] & 0x08)
{
/* Touchscreen event, do something about it */
- button_read_touch();
+ touchscreen_handle_device_irq();
}
}
#endif
diff --git a/firmware/target/arm/tcc780x/cowond2/touchscreen-cowond2.c b/firmware/target/arm/tcc780x/cowond2/touchscreen-cowond2.c
new file mode 100644
index 0000000000..d6483886ad
--- /dev/null
+++ b/firmware/target/arm/tcc780x/cowond2/touchscreen-cowond2.c
@@ -0,0 +1,233 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2009 by Rob Purchase, Carsten Schreiter, Jonas Aaberg
+ *
+ * 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "config.h"
+#include "button.h"
+#include "pcf50606.h"
+#include "touchscreen.h"
+#include "stdlib.h"
+#include "power-target.h"
+#include "tsc200x.h"
+
+#define NO_OF_TOUCH_DATA 5
+
+static bool touch_available = false;
+
+static short x[NO_OF_TOUCH_DATA], y[NO_OF_TOUCH_DATA];
+
+/* comparator for qsort */
+static int short_cmp(const void *a, const void *b)
+{
+ return *(short*)a - *(short*)b;
+}
+
+struct touch_calibration_point {
+ short px_x; /* known pixel value */
+ short px_y;
+ short val_x; /* touchscreen value at the known pixel */
+ short val_y;
+};
+
+static struct touch_calibration_point topleft, bottomright;
+
+static int touch_to_pixels(short val_x, short val_y)
+{
+ short x, y;
+
+ x = val_x;
+ y = val_y;
+
+ x = (x - topleft.val_x) * (bottomright.px_x - topleft.px_x)
+ / (bottomright.val_x - topleft.val_x) + topleft.px_x;
+
+ y = (y - topleft.val_y) * (bottomright.px_y - topleft.px_y)
+ / (bottomright.val_y - topleft.val_y) + topleft.px_y;
+
+ if (x < 0)
+ x = 0;
+ else if (x >= LCD_WIDTH)
+ x = LCD_WIDTH - 1;
+
+ if (y < 0)
+ y = 0;
+ else if (y >= LCD_HEIGHT)
+ y = LCD_HEIGHT - 1;
+
+ return (x << 16) | y;
+}
+
+static int touchscreen_read_pcf50606(int *data, int *old_data)
+{
+ int btn = BUTTON_NONE;
+ static bool touch_hold = false;
+ static long last_touch = 0;
+
+ if (touch_available || touch_hold)
+ {
+ short x_touch, y_touch;
+ static short last_x = 0, last_y = 0;
+
+ if (touch_hold)
+ {
+ /* get rid of very fast unintended double touches */
+ x_touch = last_x;
+ y_touch = last_y;
+ }
+ else
+ {
+ /* sort the 5 data taken and use the median value */
+ qsort(x, NO_OF_TOUCH_DATA, sizeof(short), short_cmp);
+ qsort(y, NO_OF_TOUCH_DATA, sizeof(short), short_cmp);
+
+ x_touch = last_x = x[(NO_OF_TOUCH_DATA - 1)/2];
+ y_touch = last_y = y[(NO_OF_TOUCH_DATA - 1)/2];
+
+ last_touch = current_tick;
+
+ touch_hold = true;
+ touch_available = false;
+ }
+
+ *old_data = *data = touch_to_pixels(x_touch, y_touch);
+
+ btn |= touchscreen_to_pixels((*data&0xffff0000) >> 16,
+ (*data&0x0000ffff),
+ data);
+ }
+
+ if (TIME_AFTER(current_tick, last_touch + 10))
+ {
+ /* put the touchscreen back into interrupt mode */
+ touch_hold = false;
+ pcf50606_write(PCF5060X_ADCC1, 1);
+ }
+
+ return btn;
+}
+
+static int touchscreen_read_tsc200x(int *data, int *old_data)
+{
+ int btn = BUTTON_NONE;
+ short x_touch, y_touch;
+
+ static long last_read = 0;
+ static int last_btn = BUTTON_NONE;
+
+ /* Don't read hw every check button round. I2C is slow
+ * and man is even slower. */
+ if (TIME_BEFORE(current_tick, last_read + 10))
+ {
+ *data = *old_data;
+ return last_btn;
+ }
+
+ if (tsc200x_is_pressed())
+ {
+ if (tsc200x_read_coords(&x_touch, &y_touch))
+ {
+ *old_data = *data = touch_to_pixels(x_touch, y_touch);
+
+ btn = touchscreen_to_pixels((*data & 0xffff0000) >> 16,
+ (*data & 0x0000ffff),
+ data);
+
+ last_btn = btn;
+ }
+ }
+
+ last_read = current_tick;
+
+ return btn;
+}
+
+void touchscreen_init_device(void)
+{
+ touch_available = false;
+
+ /* Arbitrary touchscreen calibration */
+ topleft.px_x = 0;
+ topleft.px_y = 0;
+
+ bottomright.px_x = LCD_WIDTH;
+ bottomright.px_y = LCD_HEIGHT;
+
+ topleft.val_x = 50;
+ topleft.val_y = 50;
+
+ bottomright.val_x = 980;
+ bottomright.val_y = 980;
+
+ if (get_pmu_type() != PCF50606)
+ {
+ tsc200x_init();
+ }
+}
+
+void touchscreen_handle_device_irq(void)
+{
+ static long last_touch_interrupt = 0;
+ static int touch_data_index = 0;
+
+ /* don't read the coordinates when hold is enabled */
+ if (button_hold()) return;
+
+ /* put the touchscreen into idle mode */
+ pcf50606_write(PCF5060X_ADCC1, 0);
+
+ if (TIME_AFTER(current_tick, last_touch_interrupt + 1))
+ {
+ /* resets the index if the last touch could not be read 5 times */
+ touch_data_index = 0;
+ }
+
+ /* here the touch coordinates are read 5 times */
+ /* they will be sorted and the middle one will be used */
+ pcf50606_read_adc(PCF5060X_ADC_TSC_XY,
+ &x[touch_data_index], &y[touch_data_index]);
+
+ touch_data_index++;
+
+ if (touch_data_index > NO_OF_TOUCH_DATA - 1)
+ {
+ /* coordinates 5 times read */
+ touch_available = true;
+ touch_data_index = 0;
+ }
+ else
+ {
+ /* put the touchscreen back into the interrupt mode */
+ pcf50606_write(PCF5060X_ADCC1, 1);
+ }
+ last_touch_interrupt = current_tick;
+}
+
+
+int touchscreen_read_device(int *data, int *old_data)
+{
+ int btn;
+
+ if (get_pmu_type() == PCF50606)
+ btn = touchscreen_read_pcf50606(data, old_data);
+ else
+ btn = touchscreen_read_tsc200x(data, old_data);
+
+ return btn;
+}
diff --git a/firmware/target/arm/tcc780x/cowond2/touchscreen-target.h b/firmware/target/arm/tcc780x/cowond2/touchscreen-target.h
new file mode 100644
index 0000000000..be18aed723
--- /dev/null
+++ b/firmware/target/arm/tcc780x/cowond2/touchscreen-target.h
@@ -0,0 +1,30 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2009 by Jonas Aaberg
+ *
+ * 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#ifndef _TOUCHSCREEN_TARGET_H_
+#define _TOUCHSCREEN_TARGET_H_
+
+#include "config.h"
+
+void touchscreen_init_device(void);
+int touchscreen_read_device(int *data, int *old_data);
+void touchscreen_handle_device_irq(void);
+
+#endif