mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2025-04-03 17:17:10 +02:00
touch: support event generation + support calibration information
This commit is contained in:
parent
24d932906b
commit
0ec45f92d3
6 changed files with 225 additions and 133 deletions
|
@ -258,6 +258,7 @@ set(SOURCES
|
|||
src/touch/i2c_inth.c
|
||||
src/touch/adconv.c
|
||||
src/touch/touch.c
|
||||
src/touch/driver.c
|
||||
)
|
||||
|
||||
set(ASSETS_FX src/font5x7.png src/gdb/icons-i1msb.png)
|
||||
|
|
|
@ -128,22 +128,32 @@ typedef struct
|
|||
|
||||
// The following attributes will be union'd with touch info on the CP.
|
||||
|
||||
/* Matrix code: physical location of the key being it. */
|
||||
u8 row, col;
|
||||
|
||||
/* Reserved for future use. */
|
||||
uint :16;
|
||||
union {
|
||||
struct {
|
||||
/* Matrix code: physical location of the key being it. */
|
||||
u8 row;
|
||||
u8 col;
|
||||
};
|
||||
struct {
|
||||
/* X/Y touch-screen coordinate */
|
||||
u16 x;
|
||||
u16 y;
|
||||
};
|
||||
};
|
||||
|
||||
} GPACKED(4) key_event_t;
|
||||
|
||||
/* Keyboard event types, as in the [type] field of key_event_t */
|
||||
enum
|
||||
{
|
||||
KEYEV_NONE = 0, /* No event available (poll() only) */
|
||||
KEYEV_DOWN = 1, /* Key was pressed */
|
||||
KEYEV_UP = 2, /* Key was released */
|
||||
KEYEV_HOLD = 3, /* A key that was pressed has been held down */
|
||||
KEYEV_OSMENU = 4, /* We went to the main menu and back */
|
||||
KEYEV_NONE = 0, /* No event available (poll() only) */
|
||||
KEYEV_DOWN = 1, /* Key was pressed */
|
||||
KEYEV_UP = 2, /* Key was released */
|
||||
KEYEV_HOLD = 3, /* A key that was pressed has been held down */
|
||||
KEYEV_OSMENU = 4, /* We went to the main menu and back */
|
||||
KEYEV_TOUCH_PRESSED = 5, /* Touch was detected */
|
||||
KEYEV_TOUCH_DRAG = 6, /* A touch that was detected has been held down */
|
||||
KEYEV_TOUCH_RELEASE = 7, /* Touch was released */
|
||||
};
|
||||
|
||||
/* Keyboard frequency analysis is a runtime setting since gint 2.4. This macro
|
||||
|
|
|
@ -4,35 +4,45 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#include <gint/defs/util.h>
|
||||
#include <gint/cpu.h>
|
||||
|
||||
#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 */
|
||||
// fixme : atomic
|
||||
static int _adconv_check_dual(
|
||||
struct _touch_adconv *adconv,
|
||||
struct _touch_adraw *adraw
|
||||
) {
|
||||
static int _prev_type = 0;
|
||||
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 = (_prev_type == 0) ? 0x18 : 0x12;
|
||||
_prev_type = ((abs(z2) >= val) || (max(abs(x2),abs(y2)) >= val));
|
||||
return _prev_type;
|
||||
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;
|
||||
}
|
||||
|
||||
//---
|
||||
|
@ -53,6 +63,9 @@ int touchscreen_adconv_get_raw(struct _touch_adraw *adraw)
|
|||
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);
|
||||
|
@ -83,6 +96,16 @@ int touchscreen_adconv_get_dots(
|
|||
struct _touch_adconv *adconv,
|
||||
int type
|
||||
) {
|
||||
int x_div;
|
||||
int x_mul;
|
||||
int y_div;
|
||||
int y_mul;
|
||||
|
||||
cpu_atomic_start();
|
||||
x_div = __touch_drv_info.calibration.x_div;
|
||||
x_mul = __touch_drv_info.calibration.x_mul;
|
||||
y_div = __touch_drv_info.calibration.y_div;
|
||||
y_mul = __touch_drv_info.calibration.y_mul;
|
||||
switch (type)
|
||||
{
|
||||
case 0:
|
||||
|
@ -96,8 +119,8 @@ int touchscreen_adconv_get_dots(
|
|||
break;
|
||||
case 1:
|
||||
dots->type = TS_DOTS_TYPE_SINGLE;
|
||||
dots->x1 = ((adconv->x1 - 0x1b8) * 0x100) / 0x9e5;
|
||||
dots->y1 = ((adconv->y1 - 0x104) * 0x100) / 0x660;
|
||||
dots->x1 = ((adconv->x1 - x_mul) * 0x100) / x_div;
|
||||
dots->y1 = ((adconv->y1 - y_mul) * 0x100) / y_div;
|
||||
dots->z1 = adconv->z1;
|
||||
dots->x2 = 0;
|
||||
dots->y2 = 0;
|
||||
|
@ -105,13 +128,14 @@ int touchscreen_adconv_get_dots(
|
|||
break;
|
||||
case 2:
|
||||
dots->type = TS_DOTS_TYPE_DUAL;
|
||||
dots->x1 = ((adconv->x1 - 0x1b8) * 0x100) / 0x9e5;
|
||||
dots->y1 = ((adconv->y1 - 0x104) * 0x100) / 0x660;
|
||||
dots->x1 = ((adconv->x1 - x_mul) * 0x100) / x_div;
|
||||
dots->y1 = ((adconv->y1 - y_mul) * 0x100) / y_div;
|
||||
dots->z1 = adconv->z1;
|
||||
dots->x2 = ((adconv->x2 - 0x1b8) * 0x100) / 0x9e5;
|
||||
dots->y2 = ((adconv->y2 - 0x104) * 0x100) / 0x660;
|
||||
dots->x2 = ((adconv->x2 - x_mul) * 0x100) / x_div;
|
||||
dots->y2 = ((adconv->y2 - y_mul) * 0x100) / y_div;
|
||||
dots->z2 = adconv->z2;
|
||||
break;
|
||||
}
|
||||
cpu_atomic_end();
|
||||
return type;
|
||||
}
|
||||
|
|
107
src/touch/driver.c
Normal file
107
src/touch/driver.c
Normal file
|
@ -0,0 +1,107 @@
|
|||
//---
|
||||
// gint:touch:driver - touch-screen driver declaration
|
||||
//---
|
||||
#include <string.h>
|
||||
|
||||
#include <gint/drivers.h>
|
||||
#include <gint/drivers/states.h>
|
||||
|
||||
#include "./driver.h"
|
||||
#include "./i2c.h"
|
||||
|
||||
//---
|
||||
// Internals
|
||||
//---
|
||||
|
||||
/* __touch_drv_info - internal driver information */
|
||||
extern struct _touch_drv_info __touch_drv_info;
|
||||
|
||||
/* _touch_configure() - configure touch-screen */
|
||||
static void _touch_configure(void)
|
||||
{
|
||||
volatile uint16_t *IO_PRCR = (void*)0xa405011c;
|
||||
|
||||
i2c_configure();
|
||||
*(IO_PRCR) = (*(IO_PRCR) & 0xf3ff) | 0xc00;
|
||||
memset(&__touch_drv_info, 0x00, sizeof(struct _touch_drv_info));
|
||||
__touch_drv_info.prev_evt.type = KEYEV_NONE;
|
||||
__touch_drv_info.prev_evt.x = 0xffff;
|
||||
__touch_drv_info.prev_evt.y = 0xffff;
|
||||
__touch_drv_info.calibration.x_mul = 0x20b;
|
||||
__touch_drv_info.calibration.x_div = 0x9b6;
|
||||
__touch_drv_info.calibration.y_mul = 0x0f4;
|
||||
__touch_drv_info.calibration.y_div = 0x66f;
|
||||
__touch_drv_info.calibration.dual_debounce_frame = 0;
|
||||
__touch_drv_info.calibration.dual_sensi_entry = 0x18;
|
||||
__touch_drv_info.calibration.dual_sensi_leave = 0x24;
|
||||
}
|
||||
|
||||
/* _touch_hsave() - save hardware state */
|
||||
static void _touch_hsave(touch_state_t *state)
|
||||
{
|
||||
volatile uint16_t *IO_PRCR = (void*)0xa405011c;
|
||||
|
||||
i2c_hsave(state);
|
||||
state->PRCR = *(IO_PRCR);
|
||||
}
|
||||
|
||||
/* _touch_hrestore() - restore hardware state */
|
||||
static void _touch_hrestore(touch_state_t *state)
|
||||
{
|
||||
volatile uint16_t *IO_PRCR = (void*)0xa405011c;
|
||||
|
||||
*(IO_PRCR) = state->PRCR;
|
||||
i2c_hrestore(state);
|
||||
}
|
||||
|
||||
/* _touch_hpowered() - check if the module is powered */
|
||||
static bool _touch_hpowered(void)
|
||||
{
|
||||
return i2c_hpowered();
|
||||
}
|
||||
|
||||
/* _touch_hpoweron() - power on the module */
|
||||
static void _touch_hpoweron(void)
|
||||
{
|
||||
i2c_hpoweron();
|
||||
}
|
||||
|
||||
/* _touch_hpoweroff() - power off the module */
|
||||
static void _touch_hpoweroff(void)
|
||||
{
|
||||
i2c_hpoweroff();
|
||||
}
|
||||
|
||||
/* _touch_unbin() - unbind from gint to casio */
|
||||
static void _touch_unbin(void)
|
||||
{
|
||||
i2c_unbin();
|
||||
}
|
||||
|
||||
/* _touch_funbin() - funbind from casio to gint */
|
||||
static void _touch_funbin(void)
|
||||
{
|
||||
i2c_funbin();
|
||||
}
|
||||
|
||||
//---
|
||||
// Public
|
||||
//---
|
||||
|
||||
/* __touch_drv_info - internal driver information */
|
||||
struct _touch_drv_info __touch_drv_info;
|
||||
|
||||
/* drv_touch - touch-screen driver declaration */
|
||||
gint_driver_t drv_touch = {
|
||||
.name = "TOUCH",
|
||||
.configure = _touch_configure,
|
||||
.hsave = (void *)_touch_hsave,
|
||||
.hrestore = (void *)_touch_hrestore,
|
||||
.hpowered = _touch_hpowered,
|
||||
.hpoweron = _touch_hpoweron,
|
||||
.hpoweroff = _touch_hpoweroff,
|
||||
.unbind = _touch_unbin,
|
||||
.funbind = _touch_funbin,
|
||||
.state_size = sizeof(touch_state_t),
|
||||
};
|
||||
GINT_DECLARE_DRIVER(16, drv_touch);
|
17
src/touch/driver.h
Normal file
17
src/touch/driver.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
#ifndef GINT_TOUCH_DRIVER_H
|
||||
#define GINT_TOUCH_DRIVER_H 1
|
||||
|
||||
#include <gint/keyboard.h>
|
||||
#include <gint/touch.h>
|
||||
|
||||
/* _touch_drv_info() - internal driver information */
|
||||
struct _touch_drv_info
|
||||
{
|
||||
touch_calib calibration;
|
||||
key_event_t prev_evt;
|
||||
struct {
|
||||
bool prev_is_dual;
|
||||
} adinfo;
|
||||
};
|
||||
|
||||
#endif /* GINT_TOUCH_DRIVER_H */
|
|
@ -1,20 +1,21 @@
|
|||
//---
|
||||
// gint:touch - touchscreen driver
|
||||
// gint:touch - touchscreen driver (high-level)
|
||||
//----
|
||||
#include <string.h>
|
||||
|
||||
#include <gint/drivers/states.h>
|
||||
#include <gint/drivers.h>
|
||||
#include <gint/touch.h>
|
||||
#include <gint/cpu.h>
|
||||
|
||||
#include "./i2c.h"
|
||||
#include "./adconv.h"
|
||||
#include "./driver.h"
|
||||
|
||||
//---
|
||||
// Internals
|
||||
//---
|
||||
|
||||
touch_calib __ts_calib;
|
||||
/* __touch_drv_info - internal driver information */
|
||||
extern struct _touch_drv_info __touch_drv_info;
|
||||
|
||||
//---
|
||||
// Public
|
||||
|
@ -27,7 +28,7 @@ int touch_calib_get(touch_calib *calib)
|
|||
{
|
||||
if (calib == NULL)
|
||||
return -1;
|
||||
memcpy(calib, &__ts_calib, sizeof(touch_calib));
|
||||
memcpy(calib, &__touch_drv_info.calibration, sizeof(touch_calib));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -36,122 +37,54 @@ int touch_calib_set(touch_calib *calib)
|
|||
{
|
||||
if (calib == NULL)
|
||||
return -1;
|
||||
memcpy(&__ts_calib, calib, sizeof(touch_calib));
|
||||
memcpy(&__touch_drv_info.calibration, calib, sizeof(touch_calib));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* touch_get_dots() - get dots information */
|
||||
int touch_get_dots(struct _touch_addots *dots)
|
||||
{
|
||||
struct _touch_adraw adraw;
|
||||
struct _touch_adconv adconv;
|
||||
int type;
|
||||
|
||||
type = touchscreen_adconv_get_raw(&adraw);
|
||||
type = touchscreen_adconv_get_conv(&adconv, &adraw, type);
|
||||
type = touchscreen_adconv_get_dots(dots, &adconv, type);
|
||||
return type;
|
||||
}
|
||||
|
||||
// low-level API
|
||||
|
||||
/* touch_next_event() - get the next touchscreen event */
|
||||
key_event_t touch_next_event(void)
|
||||
{
|
||||
key_event_t evt = { 0 };
|
||||
evt.type = KEYEV_NONE;
|
||||
return evt;
|
||||
#if 0
|
||||
struct _ts_adraw adraw;
|
||||
struct _ts_adconv adconv;
|
||||
struct _touch_adconv adconv;
|
||||
struct _touch_addots addots;
|
||||
struct _touch_adraw adraw;
|
||||
key_event_t evt;
|
||||
int type;
|
||||
|
||||
evt.type = KEYEV_TOUCH_RELEASE;
|
||||
type = touchscreen_adconv_get_raw(&adraw);
|
||||
type = touchscreen_adconv_get_conv(&adconv, &adraw, type);
|
||||
type = touchscreen_adconv_get_dots(dots, &adconv, type);
|
||||
return type;
|
||||
#endif
|
||||
if (type != 0)
|
||||
{
|
||||
type = touchscreen_adconv_get_conv(&adconv, &adraw, type);
|
||||
type = touchscreen_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)
|
||||
) {
|
||||
evt.type = KEYEV_TOUCH_PRESSED;
|
||||
}
|
||||
}
|
||||
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;
|
||||
cpu_atomic_end();
|
||||
return evt;
|
||||
}
|
||||
|
||||
//---
|
||||
// Driver and state
|
||||
//---
|
||||
|
||||
/* _touch_configure() - configure touch-screen */
|
||||
static void _touch_configure(void)
|
||||
{
|
||||
volatile uint16_t *IO_PRCR = (void*)0xa405011c;
|
||||
|
||||
i2c_configure();
|
||||
*(IO_PRCR) = (*(IO_PRCR) & 0xf3ff) | 0xc00;
|
||||
__ts_calib.x_mul = 0x20b;
|
||||
__ts_calib.x_div = 0x9b6;
|
||||
__ts_calib.y_mul = 0x0f4;
|
||||
__ts_calib.y_div = 0x66f;
|
||||
__ts_calib.dual_debounce_frame = 0;
|
||||
__ts_calib.dual_sensi_entry = 0x18;
|
||||
__ts_calib.dual_sensi_leave = 0x24;
|
||||
}
|
||||
|
||||
/* _touch_hsave() - save hardware state */
|
||||
static void _touch_hsave(touch_state_t *state)
|
||||
{
|
||||
volatile uint16_t *IO_PRCR = (void*)0xa405011c;
|
||||
|
||||
i2c_hsave(state);
|
||||
state->PRCR = *(IO_PRCR);
|
||||
}
|
||||
|
||||
/* _touch_hrestore() - restore hardware state */
|
||||
static void _touch_hrestore(touch_state_t *state)
|
||||
{
|
||||
volatile uint16_t *IO_PRCR = (void*)0xa405011c;
|
||||
|
||||
*(IO_PRCR) = state->PRCR;
|
||||
i2c_hrestore(state);
|
||||
}
|
||||
|
||||
/* _touch_hpowered() - check if the module is powered */
|
||||
static bool _touch_hpowered(void)
|
||||
{
|
||||
return i2c_hpowered();
|
||||
}
|
||||
|
||||
/* _touch_hpoweron() - power on the module */
|
||||
static void _touch_hpoweron(void)
|
||||
{
|
||||
i2c_hpoweron();
|
||||
}
|
||||
|
||||
/* _touch_hpoweroff() - power off the module */
|
||||
static void _touch_hpoweroff(void)
|
||||
{
|
||||
i2c_hpoweroff();
|
||||
}
|
||||
|
||||
/* _touch_unbin() - unbind from gint to casio */
|
||||
static void _touch_unbin(void)
|
||||
{
|
||||
i2c_unbin();
|
||||
}
|
||||
|
||||
/* _touch_funbin() - funbind from casio to gint */
|
||||
static void _touch_funbin(void)
|
||||
{
|
||||
i2c_funbin();
|
||||
}
|
||||
|
||||
/* drv_touch - touch-screen driver declaration */
|
||||
gint_driver_t drv_touch = {
|
||||
.name = "TOUCH",
|
||||
.configure = _touch_configure,
|
||||
.hsave = (void *)_touch_hsave,
|
||||
.hrestore = (void *)_touch_hrestore,
|
||||
.hpowered = _touch_hpowered,
|
||||
.hpoweron = _touch_hpoweron,
|
||||
.hpoweroff = _touch_hpoweroff,
|
||||
.unbind = _touch_unbin,
|
||||
.funbind = _touch_funbin,
|
||||
.state_size = sizeof(touch_state_t),
|
||||
};
|
||||
GINT_DECLARE_DRIVER(16, drv_touch);
|
||||
|
|
Loading…
Add table
Reference in a new issue