diff --git a/apps/keymaps/keymap-mini2440.c b/apps/keymaps/keymap-mini2440.c index 4291bdfb68..c53b9ae1c9 100644 --- a/apps/keymaps/keymap-mini2440.c +++ b/apps/keymaps/keymap-mini2440.c @@ -337,7 +337,7 @@ static const struct button_mapping* get_context_mapping_remote( int context ) } #endif -const struct button_mapping* get_context_mapping(int context) +const struct button_mapping* target_get_context_mapping(int context) { #ifdef HAVE_MINI2440_REMOTE if (context&CONTEXT_REMOTE) diff --git a/firmware/SOURCES b/firmware/SOURCES index 2c666cb27c..adb54c7a35 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -1411,6 +1411,7 @@ target/arm/s3c2440/mini2440/backlight-mini2440.c target/arm/s3c2440/mini2440/button-mini2440.c target/arm/s3c2440/mini2440/led-mini2440.c target/arm/s3c2440/mini2440/power-mini2440.c +target/arm/s3c2440/mini2440/touchscreen-mini2440.c #ifndef BOOTLOADER target/arm/s3c2440/mini2440/powermgmt-mini2440.c target/arm/s3c2440/mini2440/pcm-mini2440.c diff --git a/firmware/export/config-cowond2.h b/firmware/export/config-cowond2.h index 45bf90bbd0..f31c0a81c3 100644 --- a/firmware/export/config-cowond2.h +++ b/firmware/export/config-cowond2.h @@ -89,7 +89,7 @@ #define CONFIG_KEYPAD COWOND2_PAD #define HAVE_TOUCHSCREEN #define HAVE_BUTTON_DATA - + /* The D2 has either a PCF50606 or PCF50635, RTC_D2 handles both */ #define CONFIG_RTC RTC_D2 diff --git a/firmware/export/config-mini2440.h b/firmware/export/config-mini2440.h index b9d5dadf9c..83505d8994 100644 --- a/firmware/export/config-mini2440.h +++ b/firmware/export/config-mini2440.h @@ -71,6 +71,8 @@ /* Keypad */ #define CONFIG_KEYPAD MINI2440_PAD +#define HAVE_TOUCHSCREEN +#define HAVE_BUTTON_DATA /* I2C */ /* We do not use currently use hardware I2C, but does not build without */ @@ -108,6 +110,9 @@ /* RMC TODO: what is this for?? */ /* define this if you have access to the pitchscreen */ #define HAVE_PITCHSCREEN +#define HAVE_QUICKSCREEN + + /* Define this if you do software codec */ #define CONFIG_CODEC SWCODEC diff --git a/firmware/target/arm/s3c2440/adc-s3c2440.c b/firmware/target/arm/s3c2440/adc-s3c2440.c index fd5151a3bf..f42a3d2b6a 100644 --- a/firmware/target/arm/s3c2440/adc-s3c2440.c +++ b/firmware/target/arm/s3c2440/adc-s3c2440.c @@ -24,6 +24,10 @@ #include "adc-target.h" #include "kernel.h" +#ifdef MINI2440 +#include "touchscreen-target.h" +#endif + static unsigned short adc_readings[NUM_ADC_CHANNELS]; /* prototypes */ @@ -122,7 +126,7 @@ static unsigned short __adc_read(int channel) /* add this to the tick so that the ADC converts are done in the background */ static void adc_tick(void) { - static unsigned channel; + static unsigned channel=0; /* Check if the End Of Conversion is set */ if (ADCCON & (1<<15)) @@ -132,7 +136,10 @@ static void adc_tick(void) { channel = 0; } - +#ifdef MINI2440 + /* interleave a touchscreen read if neccessary */ + touchscreen_scan_device(); +#endif /* setup the next conversion and start it*/ ADCCON = (ADCCON & ~(0x7<<3)) | (channel<<3) | 0x01; } diff --git a/firmware/target/arm/s3c2440/mini2440/adc-target.h b/firmware/target/arm/s3c2440/mini2440/adc-target.h index 24e878e735..5abf0d06c5 100644 --- a/firmware/target/arm/s3c2440/mini2440/adc-target.h +++ b/firmware/target/arm/s3c2440/mini2440/adc-target.h @@ -26,16 +26,12 @@ Channels 4-7 are routed to LCD connector for touchscreen operation if supported by display panel. */ -#define NUM_ADC_CHANNELS 8 +#define NUM_ADC_CHANNELS 4 #define ADC_ONBOARD 0 #define ADC_SPARE_1 1 #define ADC_SPARE_2 2 #define ADC_SPARE_3 3 -#define ADC_TSYM 4 -#define ADC_TSYP 5 -#define ADC_TSXM 6 -#define ADC_TSXP 7 #define ADC_READ_ERROR 0xFFFF diff --git a/firmware/target/arm/s3c2440/mini2440/button-mini2440.c b/firmware/target/arm/s3c2440/mini2440/button-mini2440.c index 787c04d1ef..0435f47559 100644 --- a/firmware/target/arm/s3c2440/mini2440/button-mini2440.c +++ b/firmware/target/arm/s3c2440/mini2440/button-mini2440.c @@ -24,6 +24,7 @@ #include "system.h" #include "button.h" #include "kernel.h" +#include "touchscreen-target.h" void button_init_device(void) { @@ -50,6 +51,8 @@ void button_init_device(void) S3C2440_GPIO_PULLUP (GPGUP, 9, GPIO_PULLUP_ENABLE); S3C2440_GPIO_PULLUP (GPGUP, 10, GPIO_PULLUP_ENABLE); + /* init touchscreen */ + touchscreen_init_device(); } inline bool button_hold(void) @@ -57,12 +60,18 @@ inline bool button_hold(void) return 0; } -int button_read_device(void) +int button_read_device(int* data) { int btn = BUTTON_NONE; + static int old_data = 0; + + *data = old_data; /* Read the buttons - active low */ btn = (GPGDAT & BUTTON_MAIN) ^ BUTTON_MAIN; + + /* read touchscreen */ + btn |= touchscreen_read_device(data, &old_data); return btn; } diff --git a/firmware/target/arm/s3c2440/mini2440/button-target.h b/firmware/target/arm/s3c2440/mini2440/button-target.h index 4a84014462..66419b464a 100644 --- a/firmware/target/arm/s3c2440/mini2440/button-target.h +++ b/firmware/target/arm/s3c2440/mini2440/button-target.h @@ -27,7 +27,7 @@ bool button_hold(void); void button_init_device(void); -int button_read_device(void); +int button_read_device(int*); void touchpad_set_sensitivity(int level); /* Mini2440 specific button codes */ @@ -43,6 +43,20 @@ void touchpad_set_sensitivity(int level); #define BUTTON_SEVEN 0x0200 #define BUTTON_EIGHT 0x0400 +/* Touch Screen Area Buttons */ +#define BUTTON_TOPLEFT 0x010000 +#define BUTTON_TOPMIDDLE 0x020000 +#define BUTTON_TOPRIGHT 0x040000 +#define BUTTON_MIDLEFT 0x080000 +#define BUTTON_CENTER 0x100000 +#define BUTTON_MIDRIGHT 0x200000 +#define BUTTON_BOTTOMLEFT 0x400000 +#define BUTTON_BOTTOMMIDDLE 0x800000 +#define BUTTON_BOTTOMRIGHT 0x100000 + +#define BUTTON_TOUCH 0x200000 + + #define BUTTON_MENU BUTTON_ONE #define BUTTON_UP BUTTON_TWO #define BUTTON_SELECT BUTTON_THREE diff --git a/firmware/target/arm/s3c2440/mini2440/touchscreen-mini2440.c b/firmware/target/arm/s3c2440/mini2440/touchscreen-mini2440.c new file mode 100644 index 0000000000..ce7c8d5dd7 --- /dev/null +++ b/firmware/target/arm/s3c2440/mini2440/touchscreen-mini2440.c @@ -0,0 +1,190 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___void + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2008 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. + * + ****************************************************************************/ + +#include "config.h" +#include "touchscreen-target.h" +#include "adc-target.h" +#include "system.h" +#include "stdlib.h" +#include "button.h" +#include "touchscreen.h" + +#define NO_OF_TOUCH_DATA 5 + +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 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; +} + +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; +} + +void touchscreen_init_device() +{ + /* set touchscreen adc controller into wait for interrupt mode */ + ADCTSC = 0xd3; /* Wfait,XP-PU,XP_DIS,XM_DIS,YP_dis,YM_end */ + + /* Arbitrary touchscreen calibration */ + topleft.px_x = 0; + topleft.px_y = 0; + topleft.val_x = 105; + topleft.val_y = 925; + + bottomright.px_x = LCD_WIDTH; + bottomright.px_y = LCD_HEIGHT; + bottomright.val_x = 890; + bottomright.val_y = 105; + + touch_available = false; +} + +void touchscreen_scan_device() +{ + static long last_touch_read = 0; + static int touch_data_index = 0; + + int saveADCDLY; + + /* check touch state */ + if(ADCDAT1 & (1<<15)) + { + return; + } + + if (TIME_AFTER(current_tick, last_touch_read + 1)) + { + /* resets the index if the last touch could not be read 5 times */ + touch_data_index = 0; + } + + /* read touch data */ + saveADCDLY = ADCDLY; + ADCDLY = 40000; /*delay ~0.8ms (1/50M)*4000 */ + ADCTSC = (1<<3)|(1<<2); /* pullup disable, seq x,y pos measure */ + /* start adc */ + ADCCON|= 0x1; + /* wait for start and end */ + while(ADCCON & 0x1); + while(!(ADCCON & 0x8000)); + + x[touch_data_index] = ADCDAT0&0x3ff; + y[touch_data_index] = ADCDAT1&0x3ff; + + ADCTSC = 0xd3; /* back to interrupt mode */ + ADCDLY = saveADCDLY; + + touch_data_index++; + + if (touch_data_index > NO_OF_TOUCH_DATA - 1) + { + /* coordinates 5 times read */ + touch_available = true; + touch_data_index = 0; + } + last_touch_read = current_tick; +} + +int touchscreen_read_device(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; + } + + return btn; +} + + diff --git a/firmware/target/arm/s3c2440/mini2440/touchscreen-target.h b/firmware/target/arm/s3c2440/mini2440/touchscreen-target.h new file mode 100644 index 0000000000..1019a98330 --- /dev/null +++ b/firmware/target/arm/s3c2440/mini2440/touchscreen-target.h @@ -0,0 +1,33 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2009 by Dominik Wenger + * + * 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 + +/* try to get a touchscreen reading from adc */ +void touchscreen_scan_device(void); +/* init touchscreen driver */ +void touchscreen_init_device(void); + +int touchscreen_read_device(int *data, int *old_data); + +#endif +