mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2025-04-15 23:46:58 +02:00
touch: plug into event system (+ refactoring)
* Interrupt now at level 15 so it can work in the input timer callback * Remember last raw/conv/dots and expose unstable API to use it via new include <gint/drivers/touch.h> * Put number of touches in the structures
This commit is contained in:
parent
4e20f7bc5b
commit
bc8b9863ae
12 changed files with 272 additions and 313 deletions
|
@ -256,7 +256,6 @@ set(SOURCES
|
|||
# Touch-screen driver
|
||||
src/touch/i2c.c
|
||||
src/touch/i2c_inth.c
|
||||
src/touch/adconv.c
|
||||
src/touch/touch.c
|
||||
src/touch/driver.c
|
||||
)
|
||||
|
|
|
@ -254,6 +254,10 @@ void keydev_tick(keydev_t *d, uint us);
|
|||
// Low-level API to read events from the device
|
||||
//---
|
||||
|
||||
/* keydev_queue_event(): Add an event in a device's buffer
|
||||
Returns false if the event cannot be pushed. */
|
||||
bool keydev_queue_event(keydev_t *d, key_event_t ev);
|
||||
|
||||
/* keydev_unqueue_event(): Retrieve the next keyboard event in queue
|
||||
|
||||
This source provides the queued KEYEV_UP, KEYEV_DOWN and KEYEV_HOLD events
|
||||
|
|
70
include/gint/drivers/touch.h
Normal file
70
include/gint/drivers/touch.h
Normal file
|
@ -0,0 +1,70 @@
|
|||
//---
|
||||
// gint:drivers:touch - Internals of the touch driver
|
||||
//---
|
||||
|
||||
#ifndef GINT_DRIVERS_TOUCH
|
||||
#define GINT_DRIVERS_TOUCH
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <gint/config.h>
|
||||
#include <gint/defs/types.h>
|
||||
#include <gint/keyboard.h>
|
||||
|
||||
#if GINT_HW_CP
|
||||
|
||||
/* Access to the latest data of each stage of the touch input sequence.
|
||||
* First stage is the raw output of the 0x84 command from I2C.
|
||||
* Second stage is the same data after adjusting resolution and bit formats,
|
||||
then determining then number of touches based on multi-touch parameters.
|
||||
* Third stage is converting to screen-space coordinates based on calibration
|
||||
parameters. */
|
||||
|
||||
/* First stage: raw output of command 0x84. There may not be data at all if the
|
||||
input port indicates there are no touches. */
|
||||
struct _touch_adraw {
|
||||
/* Response to command 0x84 */
|
||||
u16 x1, y1, z1, gh;
|
||||
u16 x2, y2, z2, dm;
|
||||
/* Whether data is present (if false, everything is 0 and no touches) */
|
||||
bool has_data;
|
||||
};
|
||||
|
||||
/* Second stage: decoded form of command 0x84 output. */
|
||||
struct _touch_adconv {
|
||||
/* Number of touches (0, 1 or 2) */
|
||||
int touches;
|
||||
int x1, y1;
|
||||
int x2, y2;
|
||||
int z1, z2;
|
||||
u16 gh, dm;
|
||||
};
|
||||
|
||||
/* Third stage: screen-space dots information. */
|
||||
struct _touch_addots {
|
||||
/* Number of touches (0, 1 or 2) */
|
||||
int touches;
|
||||
/* Valid if touches >= 1 */
|
||||
int x1, y1, z1;
|
||||
/* Valid if touches >= 2 */
|
||||
int x2, y2, z2;
|
||||
};
|
||||
|
||||
/* Run a scanning round and return the next event. This function is not
|
||||
reentrant and is already called by the input timer. Don't call it! */
|
||||
key_event_t touch_scan(void);
|
||||
|
||||
/* Get the last captured data from any of the 3 stages. All pointers can be
|
||||
NULL; fills the structures that are provided. */
|
||||
void touch_get_last_scan(struct _touch_adraw *raw,
|
||||
struct _touch_adconv *conv, struct _touch_addots *dots);
|
||||
|
||||
#endif /* GINT_HW_CP */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GINT_DRIVERS_TOUCH */
|
|
@ -33,12 +33,8 @@ extern int touch_calib_get_os(touch_calibration_t *calib);
|
|||
/* touch_calib_set() - set calibration information */
|
||||
extern int touch_calib_set(touch_calibration_t *calib);
|
||||
|
||||
// low-level API
|
||||
|
||||
#include <gint/keyboard.h>
|
||||
|
||||
/* touch_next_event() - get the next touchscreen event */
|
||||
extern key_event_t touch_next_event(void);
|
||||
// TODO: Functions to query the immediate state of the touch display
|
||||
// TODO| As per queue? Or real-time?
|
||||
|
||||
#endif /* GINT_HW_CP */
|
||||
|
||||
|
|
|
@ -108,9 +108,7 @@ static int standard_repeater(GUNUSED int key, GUNUSED int duration, int count)
|
|||
// Driver event generation
|
||||
//---
|
||||
|
||||
/* keydev_queue_push(): Add an event in a device's buffer
|
||||
Returns false if the event cannot be pushed. */
|
||||
bool keydev_queue_push(keydev_t *d, key_event_t ev)
|
||||
bool keydev_queue_event(keydev_t *d, key_event_t ev)
|
||||
{
|
||||
if(d->async_filter && !d->async_filter(ev))
|
||||
return true;
|
||||
|
@ -165,7 +163,7 @@ void keydev_process_state(keydev_t *d, uint8_t scan[12])
|
|||
ev.col = col;
|
||||
ev.key = keymatrix_to_keycode(row, col);
|
||||
/* Update state only if the push succeeds */
|
||||
if((diff & mask) && keydev_queue_push(d, ev))
|
||||
if((diff & mask) && keydev_queue_event(d, ev))
|
||||
d->state_now[row] = mode
|
||||
? d->state_now[row] | mask
|
||||
: d->state_now[row] & ~mask;
|
||||
|
@ -221,7 +219,7 @@ void keydev_tick(keydev_t *d, uint us)
|
|||
/* Generate the next repeat */
|
||||
key_event_t repeat = keydev_repeat_event(d);
|
||||
if(repeat.type != KEYEV_NONE)
|
||||
keydev_queue_push(d, repeat);
|
||||
keydev_queue_event(d, repeat);
|
||||
|
||||
d->time++;
|
||||
|
||||
|
|
|
@ -14,6 +14,10 @@
|
|||
#include <gint/drivers/iokbd.h>
|
||||
#include <gint/hardware.h>
|
||||
|
||||
#if GINT_HW_CP
|
||||
#include <gint/drivers/touch.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
@ -71,6 +75,12 @@ int keysc_tick(void)
|
|||
abort();
|
||||
}
|
||||
|
||||
#if GINT_HW_CP
|
||||
key_event_t ev = touch_scan();
|
||||
if(ev.type != KEYEV_NONE)
|
||||
keydev_queue_event(&keysc_dev, ev);
|
||||
#endif
|
||||
|
||||
return TIMER_CONTINUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,166 +0,0 @@
|
|||
//---
|
||||
// gint:touch:adconv - 0x84 register data conversion
|
||||
//---
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <gint/defs/util.h>
|
||||
#include <gint/cpu.h>
|
||||
#include <gint/config.h>
|
||||
|
||||
#if GINT_HW_CP
|
||||
|
||||
#include "./adconv.h"
|
||||
#include "./i2c.h"
|
||||
#include "./driver.h"
|
||||
|
||||
//---
|
||||
// Internals
|
||||
//---
|
||||
|
||||
/* __touch_drv_info - global driver information */
|
||||
extern struct _touch_drv_info __touch_drv_info;
|
||||
|
||||
/* _adconv_check_dual() - check if it is dual or single */
|
||||
static int _adconv_check_dual(
|
||||
struct _touch_adconv *adconv,
|
||||
struct _touch_adraw *adraw
|
||||
) {
|
||||
extern struct _touch_drv_info __touch_drv_info;
|
||||
bool is_dual;
|
||||
int x2;
|
||||
int y2;
|
||||
int z2;
|
||||
int val;
|
||||
|
||||
cpu_atomic_start();
|
||||
x2 = ((int)((uint)(adraw->x2) >> 6)) + ((adraw->x2 & 1) * -0x400);
|
||||
y2 = ((int)((uint)(adraw->y2) >> 6)) + ((adraw->y2 & 1) * -0x400);
|
||||
z2 = ((int)((uint)(adraw->z2) >> 4)) + ((adraw->z2 & 1) * -0x1000);
|
||||
adconv->x2 = x2;
|
||||
adconv->y2 = y2;
|
||||
adconv->z2 = z2;
|
||||
val = __touch_drv_info.calibration.dual_sensi_entry;
|
||||
if (__touch_drv_info.adinfo.prev_is_dual)
|
||||
val = __touch_drv_info.calibration.dual_sensi_leave;
|
||||
is_dual = ((abs(z2) >= val) || (max(abs(x2),abs(y2)) >= val));
|
||||
__touch_drv_info.adinfo.prev_is_dual = is_dual;
|
||||
cpu_atomic_end();
|
||||
return is_dual;
|
||||
}
|
||||
|
||||
//---
|
||||
// Public
|
||||
//---
|
||||
|
||||
/* touch_adconv_get_raw() - read 0x84 register using I2C */
|
||||
int touch_adconv_get_raw(struct _touch_adraw *adraw)
|
||||
{
|
||||
volatile uint8_t *IO_PRDR = (void*)0xa405013c;
|
||||
|
||||
if (((*IO_PRDR) & 0x20) != 0)
|
||||
{
|
||||
adraw->x1 = 0;
|
||||
adraw->y1 = 0;
|
||||
adraw->z1 = 0;
|
||||
adraw->x2 = 0;
|
||||
adraw->y2 = 0;
|
||||
adraw->z2 = 0;
|
||||
adraw->gh = 0;
|
||||
cpu_atomic_start();
|
||||
__touch_drv_info.adinfo.prev_is_dual = false;
|
||||
cpu_atomic_end();
|
||||
return 0;
|
||||
}
|
||||
i2c_reg_read(0x84, adraw, 16);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* touch_adconv_convert() - perform the raw conversion */
|
||||
int touch_adconv_get_conv(
|
||||
struct _touch_adconv *adconv,
|
||||
struct _touch_adraw *adraw,
|
||||
int type
|
||||
) {
|
||||
if (type == 0)
|
||||
return 0;
|
||||
adconv->x1 = adraw->x1 >> 4;
|
||||
adconv->y1 = adraw->y1 >> 4;
|
||||
adconv->z1 = adraw->z1 >> 4;
|
||||
adconv->gh = adraw->gh >> 4;
|
||||
adconv->dm = adraw->dm >> 6;
|
||||
if (_adconv_check_dual(adconv, adraw) == 0)
|
||||
return 1;
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* touch_adconv_get_dots() - generate dots information */
|
||||
int touch_adconv_get_dots(
|
||||
struct _touch_addots *dots,
|
||||
struct _touch_adconv *adconv,
|
||||
int type
|
||||
) {
|
||||
int x_div;
|
||||
int x_base;
|
||||
int y_div;
|
||||
int y_base;
|
||||
|
||||
cpu_atomic_start();
|
||||
x_div = __touch_drv_info.calibration.x_div;
|
||||
x_base = __touch_drv_info.calibration.x_base;
|
||||
y_div = __touch_drv_info.calibration.y_div;
|
||||
y_base = __touch_drv_info.calibration.y_base;
|
||||
switch (type)
|
||||
{
|
||||
case 0:
|
||||
dots->type = TS_DOTS_TYPE_OFF;
|
||||
dots->x1 = 0;
|
||||
dots->y1 = 0;
|
||||
dots->z1 = 0;
|
||||
dots->x2 = 0;
|
||||
dots->y2 = 0;
|
||||
dots->z2 = 0;
|
||||
break;
|
||||
case 1:
|
||||
dots->type = TS_DOTS_TYPE_SINGLE;
|
||||
dots->x1 = ((adconv->x1 - x_base) * 0x100) / x_div;
|
||||
dots->y1 = ((adconv->y1 - y_base) * 0x100) / y_div;
|
||||
dots->z1 = adconv->z1;
|
||||
dots->x2 = 0;
|
||||
dots->y2 = 0;
|
||||
dots->z2 = 0;
|
||||
break;
|
||||
case 2: {
|
||||
dots->type = TS_DOTS_TYPE_DUAL;
|
||||
int xmin = ((adconv->x1 - x_base) * 0x100) / x_div;
|
||||
int ymin = ((adconv->y1 - y_base) * 0x100) / y_div;
|
||||
// x2 end-to-end: ~185 (changes along the height)
|
||||
// y2 end-to-end: 470
|
||||
// x2 *= 1.64
|
||||
// y2 *= 0.96
|
||||
int xmax = xmin + adconv->x2 * 0x1ba / 0x100;
|
||||
int ymax = ymin + adconv->y2 * 0x11f / 0x100;
|
||||
dots->z1 = adconv->z1;
|
||||
dots->z2 = adconv->z2;
|
||||
|
||||
if(dots->z2 >= 0) {
|
||||
dots->x1 = xmin;
|
||||
dots->y1 = ymin;
|
||||
dots->x2 = xmax;
|
||||
dots->y2 = ymax;
|
||||
}
|
||||
else {
|
||||
dots->x1 = xmin;
|
||||
dots->y1 = ymax;
|
||||
dots->x2 = xmax;
|
||||
dots->y2 = ymin;
|
||||
}
|
||||
dots->z1 = adconv->x2;
|
||||
dots->z2 = adconv->y2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
cpu_atomic_end();
|
||||
return type;
|
||||
}
|
||||
|
||||
#endif /* GINT_HW_CP */
|
|
@ -1,90 +0,0 @@
|
|||
#ifndef GINT_TOUCH_ADCONV_H
|
||||
#define GINT_TOUCH_ADCONV_H 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <gint/defs/types.h>
|
||||
#include <gint/config.h>
|
||||
|
||||
#if GINT_HW_CP
|
||||
|
||||
//---
|
||||
// Internals
|
||||
//---
|
||||
|
||||
/* _touch_adraw - raw 0x84 register information */
|
||||
struct _touch_adraw
|
||||
{
|
||||
uint16_t x1;
|
||||
uint16_t y1;
|
||||
uint16_t z1;
|
||||
uint16_t gh;
|
||||
uint16_t x2;
|
||||
uint16_t y2;
|
||||
uint16_t z2;
|
||||
uint16_t dm;
|
||||
};
|
||||
|
||||
/* _touch_adconv - post-conversion raw 0x84 register information */
|
||||
struct _touch_adconv
|
||||
{
|
||||
int x1;
|
||||
int y1;
|
||||
int x2;
|
||||
int y2;
|
||||
int z1;
|
||||
int z2;
|
||||
uint16_t gh;
|
||||
uint16_t dm;
|
||||
};
|
||||
|
||||
/* _touch_addots_type - type of dots */
|
||||
enum _touch_addots_type
|
||||
{
|
||||
TS_DOTS_TYPE_OFF = 0,
|
||||
TS_DOTS_TYPE_SINGLE = 1,
|
||||
TS_DOTS_TYPE_DUAL = 2,
|
||||
};
|
||||
|
||||
/* _touch_addots - touchscreen dots information */
|
||||
struct _touch_addots
|
||||
{
|
||||
enum _touch_addots_type type;
|
||||
int x1;
|
||||
int y1;
|
||||
int z1;
|
||||
int x2;
|
||||
int y2;
|
||||
int z2;
|
||||
};
|
||||
|
||||
//---
|
||||
// Public
|
||||
//---
|
||||
|
||||
/* touch_adconv_get_raw() - read 0x84 register using I2C */
|
||||
extern int touch_adconv_get_raw(struct _touch_adraw *adraw);
|
||||
|
||||
/* touch_adconv_get_conv() - perform the raw conversion */
|
||||
extern int touch_adconv_get_conv(
|
||||
struct _touch_adconv *adconv,
|
||||
struct _touch_adraw *adraw,
|
||||
int type
|
||||
);
|
||||
|
||||
/* touch_adconv_get_dots() - generate dots information */
|
||||
extern int touch_adconv_get_dots(
|
||||
struct _touch_addots *dots,
|
||||
struct _touch_adconv *adconv,
|
||||
int type
|
||||
);
|
||||
|
||||
#endif /* GINT_HW_CP */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GINT_TOUCH_ADCONV_H */
|
|
@ -109,6 +109,6 @@ gint_driver_t drv_touch = {
|
|||
.funbind = _touch_funbind,
|
||||
.state_size = sizeof(touch_state_t),
|
||||
};
|
||||
GINT_DECLARE_DRIVER(24, drv_touch);
|
||||
GINT_DECLARE_DRIVER(22, drv_touch);
|
||||
|
||||
#endif /* GINT_HW_CP */
|
||||
|
|
|
@ -5,9 +5,10 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <gint/config.h>
|
||||
#include <gint/keyboard.h>
|
||||
#include <gint/touch.h>
|
||||
#include <gint/config.h>
|
||||
#include <gint/drivers/touch.h>
|
||||
|
||||
#if GINT_HW_CP
|
||||
|
||||
|
@ -21,6 +22,20 @@ struct _touch_drv_info
|
|||
} adinfo;
|
||||
};
|
||||
|
||||
/* Gets raw data from I2C command 0x84. This function is *NOT REENTRANT* and
|
||||
must have only one user (from the scheduled input tick). */
|
||||
extern void touch_adconv_get_raw(struct _touch_adraw *adraw);
|
||||
|
||||
/* touch_adconv_get_conv() - perform the raw conversion */
|
||||
extern void touch_adconv_get_conv(
|
||||
struct _touch_adconv *adconv,
|
||||
struct _touch_adraw *adraw);
|
||||
|
||||
/* touch_adconv_get_dots() - generate dots information */
|
||||
extern void touch_adconv_get_dots(
|
||||
struct _touch_addots *dots,
|
||||
struct _touch_adconv *adconv);
|
||||
|
||||
#endif /* GINT_HW_CP */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -224,10 +224,10 @@ void i2c_configure(void)
|
|||
__i2c_request.status = I2C_REQ_STATUS_FINISHED;
|
||||
|
||||
// Enable interrupt
|
||||
intc_priority(INTC_I2C_AL, 1);
|
||||
intc_priority(INTC_I2C_TACK, 1);
|
||||
intc_priority(INTC_I2C_WAIT, 1);
|
||||
intc_priority(INTC_I2C_DTE, 1);
|
||||
intc_priority(INTC_I2C_AL, 15);
|
||||
intc_priority(INTC_I2C_TACK, 15);
|
||||
intc_priority(INTC_I2C_WAIT, 15);
|
||||
intc_priority(INTC_I2C_DTE, 15);
|
||||
}
|
||||
|
||||
/* i2c_unbind() - unbind from gint to casio */
|
||||
|
|
|
@ -2,23 +2,139 @@
|
|||
// gint:touch - touch driver (high-level)
|
||||
//----
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <gint/config.h>
|
||||
#include <gint/defs/util.h>
|
||||
#include <gint/touch.h>
|
||||
#include <gint/cpu.h>
|
||||
#include <gint/config.h>
|
||||
|
||||
#if GINT_HW_CP
|
||||
|
||||
#include "./i2c.h"
|
||||
#include "./adconv.h"
|
||||
#include "./driver.h"
|
||||
|
||||
/* __touch_drv_info - internal driver information */
|
||||
extern struct _touch_drv_info __touch_drv_info;
|
||||
|
||||
// TODO[touch]: Get rid of global last_cong by making raw -> conv stateless
|
||||
static struct _touch_adraw last_raw;
|
||||
static struct _touch_adconv last_conv;
|
||||
static struct _touch_addots last_dots;
|
||||
|
||||
//---
|
||||
// Internals
|
||||
//---
|
||||
|
||||
/* __touch_drv_info - internal driver information */
|
||||
extern struct _touch_drv_info __touch_drv_info;
|
||||
void touch_adconv_get_raw(struct _touch_adraw *adraw)
|
||||
{
|
||||
volatile uint8_t *IO_PRDR = (void*)0xa405013c;
|
||||
memset(adraw, 0, sizeof *adraw);
|
||||
|
||||
if ((*IO_PRDR & 0x20) == 0) {
|
||||
i2c_reg_read(0x84, adraw, 16);
|
||||
adraw->has_data = true;
|
||||
}
|
||||
}
|
||||
|
||||
void touch_adconv_get_conv(
|
||||
struct _touch_adconv *adconv,
|
||||
struct _touch_adraw *adraw)
|
||||
{
|
||||
if (!adraw->has_data) {
|
||||
memset(adconv, 0, sizeof *adconv);
|
||||
cpu_atomic_start();
|
||||
__touch_drv_info.adinfo.prev_is_dual = false;
|
||||
cpu_atomic_end();
|
||||
return;
|
||||
}
|
||||
|
||||
adconv->x1 = adraw->x1 >> 4;
|
||||
adconv->y1 = adraw->y1 >> 4;
|
||||
adconv->z1 = adraw->z1 >> 4;
|
||||
adconv->x2 = ((int)((uint)(adraw->x2) >> 6)) + ((adraw->x2 & 1) * -0x400);
|
||||
adconv->y2 = ((int)((uint)(adraw->y2) >> 6)) + ((adraw->y2 & 1) * -0x400);
|
||||
adconv->z2 = ((int)((uint)(adraw->z2) >> 4)) + ((adraw->z2 & 1) * -0x1000);
|
||||
adconv->gh = adraw->gh >> 4;
|
||||
adconv->dm = adraw->dm >> 6;
|
||||
|
||||
cpu_atomic_start();
|
||||
int dual_threshold = __touch_drv_info.calibration.dual_sensi_entry;
|
||||
if (__touch_drv_info.adinfo.prev_is_dual)
|
||||
dual_threshold = __touch_drv_info.calibration.dual_sensi_leave;
|
||||
bool is_dual = (abs(adconv->z2) >= dual_threshold ||
|
||||
max(abs(adconv->x2), abs(adconv->y2)) >= dual_threshold);
|
||||
__touch_drv_info.adinfo.prev_is_dual = is_dual;
|
||||
cpu_atomic_end();
|
||||
|
||||
adconv->touches = is_dual ? 2 : 1;
|
||||
}
|
||||
|
||||
void touch_adconv_get_dots(
|
||||
struct _touch_addots *dots,
|
||||
struct _touch_adconv *adconv)
|
||||
{
|
||||
int x_div;
|
||||
int x_base;
|
||||
int y_div;
|
||||
int y_base;
|
||||
|
||||
cpu_atomic_start();
|
||||
x_div = __touch_drv_info.calibration.x_div;
|
||||
x_base = __touch_drv_info.calibration.x_base;
|
||||
y_div = __touch_drv_info.calibration.y_div;
|
||||
y_base = __touch_drv_info.calibration.y_base;
|
||||
cpu_atomic_end();
|
||||
|
||||
dots->touches = adconv->touches;
|
||||
switch (adconv->touches)
|
||||
{
|
||||
case 0:
|
||||
dots->x1 = 0;
|
||||
dots->y1 = 0;
|
||||
dots->z1 = 0;
|
||||
dots->x2 = 0;
|
||||
dots->y2 = 0;
|
||||
dots->z2 = 0;
|
||||
break;
|
||||
case 1:
|
||||
dots->x1 = ((adconv->x1 - x_base) * 0x100) / x_div;
|
||||
dots->y1 = ((adconv->y1 - y_base) * 0x100) / y_div;
|
||||
dots->z1 = adconv->z1;
|
||||
dots->x2 = 0;
|
||||
dots->y2 = 0;
|
||||
dots->z2 = 0;
|
||||
break;
|
||||
case 2: {
|
||||
int xmin = ((adconv->x1 - x_base) * 0x100) / x_div;
|
||||
int ymin = ((adconv->y1 - y_base) * 0x100) / y_div;
|
||||
// x2 end-to-end: ~185 (changes along the height)
|
||||
// y2 end-to-end: 470
|
||||
// x2 *= 1.64
|
||||
// y2 *= 0.96
|
||||
int xmax = xmin + adconv->x2 * 0x1ba / 0x100;
|
||||
int ymax = ymin + adconv->y2 * 0x11f / 0x100;
|
||||
dots->z1 = adconv->z1;
|
||||
dots->z2 = adconv->z2;
|
||||
|
||||
if(dots->z2 >= 0) {
|
||||
dots->x1 = xmin;
|
||||
dots->y1 = ymin;
|
||||
dots->x2 = xmax;
|
||||
dots->y2 = ymax;
|
||||
}
|
||||
else {
|
||||
dots->x1 = xmin;
|
||||
dots->y1 = ymax;
|
||||
dots->x2 = xmax;
|
||||
dots->y2 = ymin;
|
||||
}
|
||||
dots->z1 = adconv->x2;
|
||||
dots->z2 = adconv->y2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---
|
||||
// Public
|
||||
|
@ -62,50 +178,57 @@ int touch_calib_set(touch_calibration_t *calib)
|
|||
|
||||
// low-level API
|
||||
|
||||
/* touch_next_event() - get the next touch event */
|
||||
key_event_t touch_next_event(void)
|
||||
static key_event_t make_event(struct _touch_addots const *dots)
|
||||
{
|
||||
struct _touch_adconv adconv;
|
||||
struct _touch_addots addots;
|
||||
struct _touch_adraw adraw;
|
||||
key_event_t evt;
|
||||
int type;
|
||||
evt.type = KEYEV_NONE;
|
||||
|
||||
evt.type = KEYEV_TOUCH_RELEASE;
|
||||
type = touch_adconv_get_raw(&adraw);
|
||||
if (type != 0)
|
||||
{
|
||||
type = touch_adconv_get_conv(&adconv, &adraw, type);
|
||||
type = touch_adconv_get_dots(&addots, &adconv, type);
|
||||
if (type == 1)
|
||||
{
|
||||
evt.type = KEYEV_TOUCH_DRAG;
|
||||
evt.x = addots.x1;
|
||||
evt.y = addots.y1;
|
||||
}
|
||||
}
|
||||
cpu_atomic_start();
|
||||
if (evt.type == KEYEV_TOUCH_DRAG) {
|
||||
if (
|
||||
(__touch_drv_info.prev_evt.type == KEYEV_NONE) ||
|
||||
(__touch_drv_info.prev_evt.type == KEYEV_TOUCH_RELEASE)
|
||||
) {
|
||||
int prev_type = __touch_drv_info.prev_evt.type;
|
||||
int prev_x = __touch_drv_info.prev_evt.x;
|
||||
int prev_y = __touch_drv_info.prev_evt.y;
|
||||
|
||||
// TODO: Handle dual touch here
|
||||
if(dots->touches != 1) {
|
||||
if(prev_type != KEYEV_TOUCH_RELEASE && prev_type != KEYEV_NONE)
|
||||
evt.type = KEYEV_TOUCH_RELEASE;
|
||||
}
|
||||
else {
|
||||
if(prev_type == KEYEV_TOUCH_RELEASE || prev_type == KEYEV_NONE)
|
||||
evt.type = KEYEV_TOUCH_PRESSED;
|
||||
/* Don't emit successive DRAG events at the same location */
|
||||
else if(dots->x1 != prev_x || dots->y1 != prev_y)
|
||||
evt.type = KEYEV_TOUCH_DRAG;
|
||||
|
||||
if(evt.type != KEYEV_NONE) {
|
||||
evt.x = dots->x1;
|
||||
evt.y = dots->y1;
|
||||
}
|
||||
}
|
||||
if (evt.type == KEYEV_TOUCH_RELEASE) {
|
||||
if (
|
||||
(__touch_drv_info.prev_evt.type == KEYEV_NONE) ||
|
||||
(__touch_drv_info.prev_evt.type == KEYEV_TOUCH_RELEASE)
|
||||
) {
|
||||
evt.type = KEYEV_NONE;
|
||||
}
|
||||
}
|
||||
__touch_drv_info.prev_evt.type = evt.type;
|
||||
__touch_drv_info.prev_evt.x = evt.x;
|
||||
__touch_drv_info.prev_evt.y = evt.y;
|
||||
|
||||
if(evt.type != KEYEV_NONE)
|
||||
__touch_drv_info.prev_evt = evt;
|
||||
cpu_atomic_end();
|
||||
return evt;
|
||||
}
|
||||
|
||||
key_event_t touch_scan(void)
|
||||
{
|
||||
touch_adconv_get_raw(&last_raw);
|
||||
touch_adconv_get_conv(&last_conv, &last_raw);
|
||||
touch_adconv_get_dots(&last_dots, &last_conv);
|
||||
return make_event(&last_dots);
|
||||
}
|
||||
|
||||
void touch_get_last_scan(struct _touch_adraw *raw,
|
||||
struct _touch_adconv *conv, struct _touch_addots *dots)
|
||||
{
|
||||
if(raw)
|
||||
*raw = last_raw;
|
||||
if(conv)
|
||||
*conv = last_conv;
|
||||
if(dots)
|
||||
*dots = last_dots;
|
||||
}
|
||||
|
||||
#endif /* GINT_HW_CP */
|
||||
|
|
Loading…
Add table
Reference in a new issue