From 18b004b330fe3009b840bfece3f1071395722cfb Mon Sep 17 00:00:00 2001 From: Rob Purchase Date: Sun, 27 Apr 2008 13:30:11 +0000 Subject: Enable 'touchscreen areas' on the D2, based on JdGordon's m:robe code. Disable the bootloader debug screen, as that stuff is all available from the Debug menu now. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@17257 a1c6a512-1295-4272-9138-f99709370657 --- bootloader/telechips.c | 57 ++------- firmware/export/config-cowond2.h | 1 + .../target/arm/tcc780x/cowond2/button-cowond2.c | 136 ++++++++++++++++++++- .../target/arm/tcc780x/cowond2/button-target.h | 8 +- .../target/arm/tcc780x/cowond2/power-cowond2.c | 10 +- 5 files changed, 155 insertions(+), 57 deletions(-) diff --git a/bootloader/telechips.c b/bootloader/telechips.c index da04101922..666657565d 100644 --- a/bootloader/telechips.c +++ b/bootloader/telechips.c @@ -59,12 +59,19 @@ void show_debug_screen(void) int power_count = 0; int count = 0; bool do_power_off = false; +#ifdef HAVE_BUTTON_DATA + unsigned int data; +#endif while(!do_power_off) { line = 0; printf("Hello World!"); +#ifdef HAVE_BUTTON_DATA + button = button_read_device(&data); +#else button = button_read_device(); +#endif /* Power-off if POWER button has been held for a long time This loop is currently running at about 100 iterations/second @@ -79,46 +86,6 @@ void show_debug_screen(void) printf("Btn: 0x%08x",button); -#if defined(COWON_D2) - int i; - - printf("GPIOA: 0x%08x",GPIOA); - printf("GPIOB: 0x%08x",GPIOB); - printf("GPIOC: 0x%08x",GPIOC); - printf("GPIOD: 0x%08x",GPIOD); - printf("GPIOE: 0x%08x",GPIOE); - - for (i = 0; i<4; i++) - { - printf("ADC%d: 0x%04x",i,adc_read(i)); - } - - /* TODO: Move this stuff out to a touchscreen driver and establish - how such a beast is going to work. Since it needs I2C read/write, - it can't easily go on an interrupt-based tick task. */ - { - int x,y; - unsigned char buf[5]; - - pcf50606_write(PCF5060X_ADCC2, (0xE<<1) | 1); /* ADC start X+Y */ - pcf50606_read_multiple(PCF5060X_ADCC1, buf, 5); - x = (buf[2] << 2) | (buf[3] & 3); - y = (buf[4] << 2) | ((buf[3] & 0xC) >> 2); - printf("X: 0x%03x Y: 0x%03x",x,y); - - x = (x*LCD_WIDTH) / 1024; - y = (y*LCD_HEIGHT) / 1024; - lcd_hline(x-5, x+5, y); - lcd_vline(x, y-5, y+5); - - pcf50606_write(PCF5060X_ADCC2, (0xF<<1) | 1); /* ADC start P1+P2 */ - pcf50606_read_multiple(PCF5060X_ADCC1, buf, 5); - x = (buf[2] << 2) | (buf[3] & 3); - y = (buf[4] << 2) | ((buf[3] & 0xC) >> 2); - printf("P1: 0x%03x P2: 0x%03x",x,y); - } -#endif - count++; printf("Count: %d",count); } @@ -186,16 +153,12 @@ void* main(void) { int(*kernel_entry)(void); - /* wait for hold release to allow debug statements to be read */ - while (button_hold()) {}; - kernel_entry = (void*) loadbuffer; - - /* allow entry to the debug screen if still holding power */ - if (!(button_read_device() & POWEROFF_BUTTON)) rc = kernel_entry(); + rc = kernel_entry(); } -#endif +#else show_debug_screen(); +#endif return 0; } diff --git a/firmware/export/config-cowond2.h b/firmware/export/config-cowond2.h index d71e528134..cbc4ea98e3 100644 --- a/firmware/export/config-cowond2.h +++ b/firmware/export/config-cowond2.h @@ -57,6 +57,7 @@ /* define this to indicate your device's keypad */ #define CONFIG_KEYPAD COWOND2_PAD #define HAVE_TOUCHPAD +#define HAVE_BUTTON_DATA /* define this if you have a real-time clock */ #define CONFIG_RTC RTC_PCF50606 diff --git a/firmware/target/arm/tcc780x/cowond2/button-cowond2.c b/firmware/target/arm/tcc780x/cowond2/button-cowond2.c index ea37893f40..c0672f1c3a 100644 --- a/firmware/target/arm/tcc780x/cowond2/button-cowond2.c +++ b/firmware/target/arm/tcc780x/cowond2/button-cowond2.c @@ -21,20 +21,92 @@ #include "cpu.h" #include "button.h" #include "adc.h" +#include "pcf50606.h" + +#define TOUCH_MARGIN 8 static enum touchpad_mode current_mode = TOUCHPAD_POINT; + +static short last_x, last_y; +static bool touch_available = false; + +static int touchpad_buttons[3][3] = +{ + {BUTTON_TOPLEFT, BUTTON_TOPMIDDLE, BUTTON_TOPRIGHT}, + {BUTTON_MIDLEFT, BUTTON_CENTER, BUTTON_MIDRIGHT}, + {BUTTON_BOTTOMLEFT, BUTTON_BOTTOMMIDDLE, BUTTON_BOTTOMRIGHT}, +}; + void touchpad_set_mode(enum touchpad_mode mode) { current_mode = mode; } + enum touchpad_mode touchpad_get_mode(void) { return current_mode; } +void button_set_touch_available(void) +{ + touch_available = true; +} + +struct touch_calibration_point { + short px_x; /* known pixel value */ + short px_y; + short val_x; /* touchpad 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; +} + void button_init_device(void) { - /* Nothing to do */ + /* Configure GPIOA 4 (POWER) and 8 (HOLD) for input */ + GPIOA_DIR &= ~0x110; + + /* 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; } bool button_hold(void) @@ -42,10 +114,11 @@ bool button_hold(void) return (GPIOA & 0x8) ? false : true; } -int button_read_device(void) +int button_read_device(int *data) { int btn = BUTTON_NONE; int adc; + *data = 0; if (GPIOB & 0x4) { @@ -69,8 +142,63 @@ int button_read_device(void) } } - /* TODO: Read 'fake' buttons based on touchscreen quadrants. - Question: How can I read from the PCF chip (I2C) in a tick task? */ + if (touch_available) + { + short x = 0, y = 0; + static long last_touch = 0; + bool send_touch = false; + + int irq_level = disable_irq_save(); + if (pcf50606_read(PCF5060X_ADCC1) & 0x80) /* Pen down */ + { + unsigned char buf[3]; + pcf50606_write(PCF5060X_ADCC2, (0xE<<1) | 1); /* ADC start X+Y */ + pcf50606_read_multiple(PCF5060X_ADCS1, buf, 3); + pcf50606_write(PCF5060X_ADCC2, 0); /* ADC stop */ + + x = (buf[0] << 2) | (buf[1] & 3); + y = (buf[2] << 2) | ((buf[1] & 0xC) >> 2); + + if (TIME_BEFORE(last_touch + HZ/5, current_tick)) + { + if ((x > last_x + TOUCH_MARGIN) || + (x < last_x - TOUCH_MARGIN) || + (y > last_y + TOUCH_MARGIN) || + (y < last_y - TOUCH_MARGIN)) + { + send_touch = true; + } + } + else + { + send_touch = true; + } + } + restore_irq(irq_level); + + if (send_touch) + { + last_x = x; + last_y = y; + *data = touch_to_pixels(x, y); + switch (current_mode) + { + case TOUCHPAD_POINT: + btn |= BUTTON_TOUCHPAD; + break; + case TOUCHPAD_BUTTON: + { + int px_x = (*data&0xffff0000)>>16; + int px_y = (*data&0x0000ffff); + btn |= touchpad_buttons[px_y/(LCD_HEIGHT/3)] + [px_x/(LCD_WIDTH/3)]; + break; + } + } + } + last_touch = current_tick; + touch_available = false; + } 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 2890ef65a3..051ed39689 100644 --- a/firmware/target/arm/tcc780x/cowond2/button-target.h +++ b/firmware/target/arm/tcc780x/cowond2/button-target.h @@ -27,7 +27,8 @@ bool button_hold(void); void button_init_device(void); -int button_read_device(void); +int button_read_device(int *data); +void button_set_touch_available(void); /* Main unit's buttons */ #define BUTTON_POWER 0x00000001 @@ -42,7 +43,6 @@ int button_read_device(void); #define BUTTON_UP BUTTON_TOPMIDDLE #define BUTTON_DOWN BUTTON_BOTTOMMIDDLE -/* Faked buttons based on touchscreen quadrants (not yet read) */ /* Touchpad Screen Area Buttons */ #define BUTTON_TOPLEFT 0x00000010 #define BUTTON_TOPMIDDLE 0x00000020 @@ -54,7 +54,9 @@ int button_read_device(void); #define BUTTON_BOTTOMMIDDLE 0x00000800 #define BUTTON_BOTTOMRIGHT 0x00001000 -#define BUTTON_MAIN 0x1FFF +#define BUTTON_TOUCH 0x00002000 + +#define BUTTON_MAIN 0x3FFF /* No remote */ #define BUTTON_REMOTE 0 diff --git a/firmware/target/arm/tcc780x/cowond2/power-cowond2.c b/firmware/target/arm/tcc780x/cowond2/power-cowond2.c index af5559dfb5..c7441256c5 100644 --- a/firmware/target/arm/tcc780x/cowond2/power-cowond2.c +++ b/firmware/target/arm/tcc780x/cowond2/power-cowond2.c @@ -21,7 +21,7 @@ #include "system.h" #include "power.h" #include "pcf50606.h" -#include "cpu.h" +#include "button-target.h" #ifndef SIMULATOR @@ -74,15 +74,19 @@ void EXT3(void) if (data[0] & 0x04) { + /* ONKEY1S: don't reset the timeout, because we want a way to power off + the player in the event of a crashed plugin or UIE/panic, etc. */ +#if 0 /* ONKEY1S: reset timeout as we're using SW poweroff */ pcf50606_write(0x08, pcf50606_read(0x08) | 0x02); /* OOCC1: TOTRST=1 */ +#endif } if (data[2] & 0x08) { - /* TODO: Touchscreen pen down event, do something about it */ + /* Touchscreen event, do something about it */ + button_set_touch_available(); } - restore_fiq(fiq_status); } #endif -- cgit v1.2.3