1
0
Fork 0
forked from len0rd/rockbox

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
This commit is contained in:
Rob Purchase 2008-04-27 13:30:11 +00:00
parent f79bc56430
commit 18b004b330
5 changed files with 155 additions and 57 deletions

View file

@ -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;

View file

@ -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

View file

@ -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