Index: apps/touchscreen.c =================================================================== --- apps/touchscreen.c (revision 0) +++ apps/touchscreen.c (revision 0) @@ -0,0 +1,103 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2009 by Maurus Cuelenaere + * + * 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 "action.h" +#include "font.h" +#include "lcd.h" +#include "screen_access.h" +#include "system.h" +#include "touchscreen.h" + +static int get_sample(struct touchscreen_calibration *cal, int x, int y, int i, + struct screen* screen) +{ + int action; + short ts_x, ts_y; + + /* Draw a cross */ + screen->drawline(x - 10, y, x - 2, y); + screen->drawline(x + 2, y, x + 10, y); + screen->drawline(x, y - 10, x, y - 2); + screen->drawline(x, y + 2, x, y + 10); + screen->update(); + + while(true) + { + action = get_action(CONTEXT_STD, TIMEOUT_BLOCK); + if(action == ACTION_TOUCHSCREEN) + { + if(action_get_touchscreen_press(&ts_x, &ts_y) == BUTTON_REL) + break; + } + else if(action == ACTION_STD_CANCEL) + return -1; + } + + cal->x[i][0] = ts_x; + cal->y[i][0] = ts_y; + cal->x[i][1] = x; + cal->y[i][1] = y; + + return 0; +} + + +int calibrate(void) +{ + short points[3][2] = { + {LCD_WIDTH/10, LCD_HEIGHT/10}, + {7*LCD_WIDTH/8, LCD_HEIGHT/2}, + {LCD_WIDTH/2, 7*LCD_HEIGHT/8} + }; + const char* str = "Calibration mode"; + struct screen* screen = &screens[SCREEN_MAIN]; + enum touchscreen_mode old_mode = touchscreen_get_mode(); + struct touchscreen_calibration cal; + int i, btn, strw; + + screen->getstringsize(str, &strw, NULL); + touchscreen_disable_mapping(); + touchscreen_set_mode(TOUCHSCREEN_POINT); + for(i=0; i<3; i++) + { + screen->clear_display(); + screen->putsxy((LCD_WIDTH-strw)/2, 0, str); + + if(get_sample(&cal, points[i][0], points[i][1], i, screen)) + goto err; + } + touchscreen_calibrate(&cal); + touchscreen_set_mode(old_mode); + + return 0; + +err: + touchscreen_reset_mapping(); + touchscreen_set_mode(old_mode); + return -1; +} + +int reset_mapping(void) +{ + touchscreen_reset_mapping(); + return 0; +} Property changes on: apps/touchscreen.c ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Index: firmware/drivers/touchscreen.c =================================================================== --- firmware/drivers/touchscreen.c (revision 21215) +++ firmware/drivers/touchscreen.c (working copy) @@ -34,57 +34,24 @@ {BUTTON_BOTTOMLEFT, BUTTON_BOTTOMMIDDLE, BUTTON_BOTTOMRIGHT} }; -/* Based on ftp://ftp.embedded.com/pub/2002/06vidales/calibrate.c - * - * Copyright (c) 2001, Carlos E. Vidales. All rights reserved. - * - * This sample program was written and put in the public domain - * by Carlos E. Vidales. The program is provided "as is" - * without warranty of any kind, either expressed or implied. - * If you choose to use the program within your own products - * you do so at your own risk, and assume the responsibility - * for servicing, repairing or correcting the program should - * it prove defective in any manner. - * You may copy and distribute the program's source code in any - * medium, provided that you also include in each copy an - * appropriate copyright notice and disclaimer of warranty. - * You may also modify this program and distribute copies of - * it provided that you include prominent notices stating - * that you changed the file(s) and the date of any change, - * and that you do not charge any royalties or licenses for - * its use. - */ -struct touchscreen_parameter -{ - long A; - long B; - long C; - long D; - long E; - long F; - long divider; -}; - #ifndef DEFAULT_TOUCHSCREEN_CALIBRATION -#define DEFAULT_TOUCHSCREEN_CALIBRATION {.A=1, .B=0, .C=0, \ - .D=0, .E=1, .F=0, \ - .divider=1} +#define DEFAULT_TOUCHSCREEN_CALIBRATION { .A=1, .B=0, .C=0, \ + .D=0, .E=1, .F=0, \ + .divider=1 } #endif -static struct touchscreen_parameter calibration_parameters +struct touchscreen_parameter calibration_parameters = DEFAULT_TOUCHSCREEN_CALIBRATION; static const struct touchscreen_parameter default_parameters = DEFAULT_TOUCHSCREEN_CALIBRATION; void touchscreen_disable_mapping(void) { - calibration_parameters.A = 1; - calibration_parameters.B = 0; - calibration_parameters.C = 0; - calibration_parameters.D = 0; - calibration_parameters.E = 1; - calibration_parameters.F = 0; - calibration_parameters.divider = 1; +#define C(x) calibration_parameters.x + C(A) = C(E) = 1; + C(B) = C(C) = C(D) = C(F) = 0; + C(divider) = 1; +#undef C } void touchscreen_reset_mapping(void) @@ -95,58 +62,65 @@ int touchscreen_calibrate(struct touchscreen_calibration *cal) { - calibration_parameters.divider = ((cal->x[0] - cal->x[2]) * (cal->y[1] - cal->y[2])) - - ((cal->x[1] - cal->x[2]) * (cal->y[0] - cal->y[2])) ; +#define C(x) calibration_parameters.x /* Calibration */ +#define S(i,j) cal->i[j][0] /* Screen */ +#define D(i,j) cal->i[j][1] /* Display */ + long divider = (S(x,0) - S(x,2)) * (S(y,1) - S(y,2)) - + (S(x,1) - S(x,2)) * (S(y,0) - S(y,2)); - if(calibration_parameters.divider == 0) + if(divider == 0) return -1; - - calibration_parameters.A = ((cal->xfb[0] - cal->xfb[2]) * (cal->y[1] - cal->y[2])) - - ((cal->xfb[1] - cal->xfb[2]) * (cal->y[0] - cal->y[2])) ; + else + C(divider) = divider; - calibration_parameters.B = ((cal->x[0] - cal->x[2]) * (cal->xfb[1] - cal->xfb[2])) - - ((cal->xfb[0] - cal->xfb[2]) * (cal->x[1] - cal->x[2])) ; + C(A) = (D(x,0) - D(x,2)) * (S(y,1) - S(y,2)) - + (D(x,1) - D(x,2)) * (S(y,0) - S(y,2)); - calibration_parameters.C = (cal->x[2] * cal->xfb[1] - cal->x[1] * cal->xfb[2]) * cal->y[0] + - (cal->x[0] * cal->xfb[2] - cal->x[2] * cal->xfb[0]) * cal->y[1] + - (cal->x[1] * cal->xfb[0] - cal->x[0] * cal->xfb[1]) * cal->y[2] ; + C(B) = (S(x,0) - S(x,2)) * (D(x,1) - D(x,2)) - + (D(x,0) - D(x,2)) * (S(x,1) - S(x,2)); - calibration_parameters.D = ((cal->yfb[0] - cal->yfb[2]) * (cal->y[1] - cal->y[2])) - - ((cal->yfb[1] - cal->yfb[2]) * (cal->y[0] - cal->y[2])) ; + C(C) = S(y,0) * (S(x,2) * D(x,1) - S(x,1) * D(x,2)) + + S(y,1) * (S(x,0) * D(x,2) - S(x,2) * D(x,0)) + + S(y,2) * (S(x,1) * D(x,0) - S(x,0) * D(x,1)); - calibration_parameters.E = ((cal->x[0] - cal->x[2]) * (cal->yfb[1] - cal->yfb[2])) - - ((cal->yfb[0] - cal->yfb[2]) * (cal->x[1] - cal->x[2])) ; + C(D) = (D(y,0) - D(y,2)) * (S(y,1) - S(y,2)) - + (D(y,1) - D(y,2)) * (S(y,0) - S(y,2)); - calibration_parameters.F = (cal->x[2] * cal->yfb[1] - cal->x[1] * cal->yfb[2]) * cal->y[0] + - (cal->x[0] * cal->yfb[2] - cal->x[2] * cal->yfb[0]) * cal->y[1] + - (cal->x[1] * cal->yfb[0] - cal->x[0] * cal->yfb[1]) * cal->y[2] ; + C(E) = (S(x,0) - S(x,2)) * (D(y,1) - D(y,2)) - + (D(y,0) - D(y,2)) * (S(x,1) - S(x,2)); - logf("A: %lX B: %lX C: %lX", calibration_parameters.A, - calibration_parameters.B, calibration_parameters.C); - logf("D: %lX E: %lX F: %lX", calibration_parameters.D, - calibration_parameters.E, calibration_parameters.F); - logf("divider: %lX", calibration_parameters.divider); - + C(F) = S(y,0) * (S(x,2) * D(y,1) - S(x,1) * D(y,2)) + + S(y,1) * (S(x,0) * D(y,2) - S(x,2) * D(y,0)) + + S(y,2) * (S(x,1) * D(y,0) - S(x,0) * D(y,1)); + + logf("A: %lX B: %lX C: %lX", C(A), C(B), C(C)); + logf("D: %lX E: %lX F: %lX", C(D), C(E), C(F)); + logf("divider: %lX", C(divider)); + return 0; +#undef C +#undef S +#undef D } static void map_pixels(int *x, int *y) { +#define C(x) calibration_parameters.x int _x = *x, _y = *y; - - *x = (calibration_parameters.A*_x + calibration_parameters.B*_y + - calibration_parameters.C) / calibration_parameters.divider; - *y = (calibration_parameters.D*_x + calibration_parameters.E*_y + - calibration_parameters.F) / calibration_parameters.divider; + + *x = (C(A) * _x + C(B) * _y + C(C)) / C(divider); + *y = (C(D) * _x + C(E) * _y + C(F)) / C(divider); +#undef C } +/* TODO: add jitter (and others) filter */ int touchscreen_to_pixels(int x, int y, int *data) { x &= 0xFFFF; y &= 0xFFFF; - + map_pixels(&x, &y); - + if(current_mode == TOUCHSCREEN_BUTTON) return touchscreen_buttons[y / (LCD_HEIGHT/3)] [x / (LCD_WIDTH/3) ]; Index: firmware/export/touchscreen.h =================================================================== --- firmware/export/touchscreen.h (revision 21215) +++ firmware/export/touchscreen.h (working copy) @@ -24,12 +24,16 @@ struct touchscreen_calibration { - int x[3]; - int xfb[3]; - int y[3]; - int yfb[3]; + short x[3][2]; + short y[3][2]; }; +struct touchscreen_parameter +{ + long A, B, C, D, E, F; + long divider; +}; + enum touchscreen_mode { TOUCHSCREEN_POINT = 0, /* touchscreen returns pixel co-ords */ @@ -38,6 +42,7 @@ from button_get_data */ }; +extern struct touchscreen_parameter calibration_parameters; int touchscreen_calibrate(struct touchscreen_calibration *cal); int touchscreen_to_pixels(int x, int y, int *data); void touchscreen_set_mode(enum touchscreen_mode mode); Index: apps/menus/settings_menu.c =================================================================== --- apps/menus/settings_menu.c (revision 21215) +++ apps/menus/settings_menu.c (working copy) @@ -265,21 +265,6 @@ MENUITEM_SETTING(touchpad_sensitivity, &global_settings.touchpad_sensitivity, NULL); #endif -#ifdef HAVE_TOUCHSCREEN -static int touch_mode_callback(int action,const struct menu_item_ex *this_item) -{ - (void)this_item; - switch (action) - { - case ACTION_EXIT_MENUITEM: /* on exit */ - touchscreen_set_mode(global_settings.touch_mode); - break; - } - return action; -} -MENUITEM_SETTING(touch_mode, &global_settings.touch_mode, touch_mode_callback); -#endif - MAKE_MENU(system_menu, ID2P(LANG_SYSTEM), 0, Icon_System_menu, &start_screen, @@ -315,9 +300,6 @@ #ifdef HAVE_TOUCHPAD_SENSITIVITY_SETTING &touchpad_sensitivity, #endif -#ifdef HAVE_TOUCHSCREEN - &touch_mode, -#endif ); /* SYSTEM MENU */ Index: apps/menus/display_menu.c =================================================================== --- apps/menus/display_menu.c (revision 21215) +++ apps/menus/display_menu.c (working copy) @@ -496,7 +496,33 @@ /***********************************/ +#ifdef HAVE_TOUCHSCREEN +static int touch_mode_callback(int action,const struct menu_item_ex *this_item) +{ + (void)this_item; + switch (action) + { + case ACTION_EXIT_MENUITEM: /* on exit */ + touchscreen_set_mode(global_settings.touch_mode); + break; + } + return action; +} +MENUITEM_SETTING(touch_mode, &global_settings.touch_mode, touch_mode_callback); +extern int calibrate(void); +extern int reset_mapping(void); + +MENUITEM_FUNCTION(touchscreen_menu_calibrate, 0, "Calibrate", calibrate, + NULL, NULL, Icon_NOICON); +MENUITEM_FUNCTION(touchscreen_menu_reset_calibration, 0, "Reset calibration", reset_mapping, + NULL, NULL, Icon_NOICON); + +MAKE_MENU(touchscreen_menu, "Touchscreen Settings", NULL, Icon_NOICON, &touch_mode, + &touchscreen_menu_calibrate, &touchscreen_menu_reset_calibration); +#endif + + MENUITEM_SETTING(codepage_setting, &global_settings.default_codepage, NULL); @@ -511,4 +537,7 @@ &bars_menu, &peak_meter_menu, #endif &codepage_setting, +#ifdef HAVE_TOUCHSCREEN + &touchscreen_menu, +#endif ); Index: apps/SOURCES =================================================================== --- apps/SOURCES (revision 21215) +++ apps/SOURCES (working copy) @@ -167,6 +167,7 @@ tagcache.c #endif #ifdef HAVE_TOUCHSCREEN +touchscreen.c keymaps/keymap-touchscreen.c #endif #if (CONFIG_KEYPAD == IRIVER_H100_PAD) \