mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2025-06-07 19:45:04 +02:00
Compare commits
No commits in common. "294d6afc8cbe4879fa1a1f8429a9bbc7ee7464c7" and "03c5d02142658ba45a3ec7c6270d6d61cb3327e6" have entirely different histories.
294d6afc8c
...
03c5d02142
17 changed files with 11 additions and 1179 deletions
|
@ -253,12 +253,6 @@ set(SOURCES
|
||||||
src/usb/write4.S
|
src/usb/write4.S
|
||||||
# Video driver interface
|
# Video driver interface
|
||||||
src/video/video.c
|
src/video/video.c
|
||||||
# Touch-screen driver
|
|
||||||
src/touch/i2c.c
|
|
||||||
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)
|
set(ASSETS_FX src/font5x7.png src/gdb/icons-i1msb.png)
|
||||||
|
|
|
@ -109,16 +109,6 @@ typedef struct {
|
||||||
|
|
||||||
} usb_state_t;
|
} usb_state_t;
|
||||||
|
|
||||||
/* Touch-screen modules */
|
|
||||||
typedef struct {
|
|
||||||
uint16_t PRCR;
|
|
||||||
uint16_t PJCR;
|
|
||||||
uint8_t ICCR;
|
|
||||||
uint8_t ICIC;
|
|
||||||
uint8_t ICCL;
|
|
||||||
uint8_t ICCH;
|
|
||||||
} touch_state_t;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -52,11 +52,6 @@ enum {
|
||||||
INTC_SPU_DSP1,
|
INTC_SPU_DSP1,
|
||||||
/* USB communication */
|
/* USB communication */
|
||||||
INTC_USB,
|
INTC_USB,
|
||||||
/* I2C */
|
|
||||||
INTC_I2C_AL,
|
|
||||||
INTC_I2C_TACK,
|
|
||||||
INTC_I2C_WAIT,
|
|
||||||
INTC_I2C_DTE,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//---
|
//---
|
||||||
|
|
|
@ -128,32 +128,22 @@ typedef struct
|
||||||
|
|
||||||
// The following attributes will be union'd with touch info on the CP.
|
// The following attributes will be union'd with touch info on the CP.
|
||||||
|
|
||||||
union {
|
/* Matrix code: physical location of the key being it. */
|
||||||
struct {
|
u8 row, col;
|
||||||
/* Matrix code: physical location of the key being it. */
|
|
||||||
u8 row;
|
/* Reserved for future use. */
|
||||||
u8 col;
|
uint :16;
|
||||||
};
|
|
||||||
struct {
|
|
||||||
/* X/Y touch-screen coordinate */
|
|
||||||
u16 x;
|
|
||||||
u16 y;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
} GPACKED(4) key_event_t;
|
} GPACKED(4) key_event_t;
|
||||||
|
|
||||||
/* Keyboard event types, as in the [type] field of key_event_t */
|
/* Keyboard event types, as in the [type] field of key_event_t */
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
KEYEV_NONE = 0, /* No event available (poll() only) */
|
KEYEV_NONE = 0, /* No event available (poll() only) */
|
||||||
KEYEV_DOWN = 1, /* Key was pressed */
|
KEYEV_DOWN = 1, /* Key was pressed */
|
||||||
KEYEV_UP = 2, /* Key was released */
|
KEYEV_UP = 2, /* Key was released */
|
||||||
KEYEV_HOLD = 3, /* A key that was pressed has been held down */
|
KEYEV_HOLD = 3, /* A key that was pressed has been held down */
|
||||||
KEYEV_OSMENU = 4, /* We went to the main menu and back */
|
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
|
/* Keyboard frequency analysis is a runtime setting since gint 2.4. This macro
|
||||||
|
|
|
@ -1,74 +0,0 @@
|
||||||
#ifndef GINT_MPU_I2C_H
|
|
||||||
#define GINT_MPU_I2C_H 1
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <gint/defs/attributes.h>
|
|
||||||
#include <gint/defs/types.h>
|
|
||||||
|
|
||||||
//---
|
|
||||||
// SH7305 I2C Bus Interface. Refer to:
|
|
||||||
// "Renesas SH7724 User's Manual: Hardware"
|
|
||||||
// Section 32: "I2C Bus Interface (I2C)"
|
|
||||||
//---
|
|
||||||
|
|
||||||
/* sh7305_i2c_t - I2C peripheral definition */
|
|
||||||
typedef struct {
|
|
||||||
// read/write register
|
|
||||||
uint8_t ICDR;
|
|
||||||
pad(3);
|
|
||||||
|
|
||||||
// control register
|
|
||||||
byte_union(ICCR,
|
|
||||||
uint8_t ICE :1;
|
|
||||||
uint8_t RACK :1;
|
|
||||||
uint8_t :1;
|
|
||||||
uint8_t TRS :1;
|
|
||||||
uint8_t :1;
|
|
||||||
uint8_t BBSY :1;
|
|
||||||
uint8_t :1;
|
|
||||||
uint8_t SCP :1;
|
|
||||||
);
|
|
||||||
pad(3);
|
|
||||||
|
|
||||||
// status register
|
|
||||||
byte_union(ICSR,
|
|
||||||
uint8_t SCLM :1;
|
|
||||||
uint8_t SDAM :1;
|
|
||||||
uint8_t :1;
|
|
||||||
uint8_t BUSY :1;
|
|
||||||
uint8_t AL :1;
|
|
||||||
uint8_t TACK :1;
|
|
||||||
uint8_t WAIT :1;
|
|
||||||
uint8_t DTE :1;
|
|
||||||
);
|
|
||||||
pad(3);
|
|
||||||
|
|
||||||
// interrupt control register
|
|
||||||
byte_union(ICIC,
|
|
||||||
uint8_t :1;
|
|
||||||
uint8_t :1;
|
|
||||||
uint8_t :1;
|
|
||||||
uint8_t :1;
|
|
||||||
uint8_t ALE :1;
|
|
||||||
uint8_t TACKE :1;
|
|
||||||
uint8_t WAITE :1;
|
|
||||||
uint8_t DTEE :1;
|
|
||||||
);
|
|
||||||
pad(3);
|
|
||||||
|
|
||||||
// clock control registers
|
|
||||||
uint8_t ICCL;
|
|
||||||
pad(3);
|
|
||||||
uint8_t ICCH;
|
|
||||||
} GPACKED(1) sh7305_i2c_t;
|
|
||||||
|
|
||||||
#define SH7305_I2C (*((volatile sh7305_i2c_t *)0xa4470000))
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* GINT_MPU_I2C_H */
|
|
|
@ -192,7 +192,7 @@ typedef volatile struct
|
||||||
uint16_t _MSIOF0:4; /* SH7724: Sync SCIF channel 0 */
|
uint16_t _MSIOF0:4; /* SH7724: Sync SCIF channel 0 */
|
||||||
uint16_t _MSIOF1:4; /* SH7724: Sync SCIF channel 1 */
|
uint16_t _MSIOF1:4; /* SH7724: Sync SCIF channel 1 */
|
||||||
uint16_t _1 :4; /* Unknown (TODO) */
|
uint16_t _1 :4; /* Unknown (TODO) */
|
||||||
uint16_t I2C:4; /* I2C */
|
uint16_t _2 :4; /* Unknown (TODO) */
|
||||||
);
|
);
|
||||||
pad(2);
|
pad(2);
|
||||||
|
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
//---
|
|
||||||
// gint:touch - touch-screen driver API
|
|
||||||
//---
|
|
||||||
#ifndef GINT_TOUCH_H
|
|
||||||
#define GINT_TOUCH_H 1
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <gint/config.h>
|
|
||||||
|
|
||||||
#if GINT_HW_CP
|
|
||||||
|
|
||||||
/* touch_calib - tounch-screen calibration information */
|
|
||||||
typedef struct {
|
|
||||||
int x_base;
|
|
||||||
int x_div;
|
|
||||||
int y_base;
|
|
||||||
int y_div;
|
|
||||||
int dual_debounce_frame;
|
|
||||||
int dual_sensi_entry;
|
|
||||||
int dual_sensi_leave;
|
|
||||||
} touch_calibration_t;
|
|
||||||
|
|
||||||
/* touch_calib_get() - get calibration information */
|
|
||||||
extern int touch_calib_get(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);
|
|
||||||
|
|
||||||
#endif /* GINT_HW_CP */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* GINT_TOUCH_H */
|
|
|
@ -71,11 +71,6 @@ static struct info {
|
||||||
{ IPRC, 0x000f, IMR4, 0x08, _ },
|
{ IPRC, 0x000f, IMR4, 0x08, _ },
|
||||||
/* USB */
|
/* USB */
|
||||||
{ IPRF, 0x00f0, IMR9, 0x02, _ /* Driver not SH3-compatible yet */ },
|
{ IPRF, 0x00f0, IMR9, 0x02, _ /* Driver not SH3-compatible yet */ },
|
||||||
/* I2C */
|
|
||||||
{ IPRH, 0x000f, IMR7, 0x10, _ },
|
|
||||||
{ IPRH, 0x000f, IMR7, 0x20, _ },
|
|
||||||
{ IPRH, 0x000f, IMR7, 0x40, _ },
|
|
||||||
{ IPRH, 0x000f, IMR7, 0x80, _ },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Compact SH3 VBR-space scheme
|
/* Compact SH3 VBR-space scheme
|
||||||
|
|
|
@ -123,7 +123,6 @@ GNORETURN static void gint_default_panic(GUNUSED uint32_t code)
|
||||||
if(code == 0x1080) name = "Stack overflow during world switch";
|
if(code == 0x1080) name = "Stack overflow during world switch";
|
||||||
if(code == 0x10a0) name = "UBC break in register bank 1 code";
|
if(code == 0x10a0) name = "UBC break in register bank 1 code";
|
||||||
if(code == 0x10c0) name = "Missing syscall for this OS version";
|
if(code == 0x10c0) name = "Missing syscall for this OS version";
|
||||||
if(code == 0x10e0) name = "I2C (touch-screen) error";
|
|
||||||
|
|
||||||
dprint(6, 25, "%03x %s", code, name);
|
dprint(6, 25, "%03x %s", code, name);
|
||||||
|
|
||||||
|
@ -174,11 +173,6 @@ GNORETURN static void gint_default_panic(GUNUSED uint32_t code)
|
||||||
dprint(6, 160, "Opcodes: %04x %04x [%04x] %04x",
|
dprint(6, 160, "Opcodes: %04x %04x [%04x] %04x",
|
||||||
opcodes[-2], opcodes[-1], opcodes[0], opcodes[1]);
|
opcodes[-2], opcodes[-1], opcodes[0], opcodes[1]);
|
||||||
}
|
}
|
||||||
/* I2C exception error */
|
|
||||||
if (code == 0x10e0)
|
|
||||||
{
|
|
||||||
//todo
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_WEAK_dupdate();
|
_WEAK_dupdate();
|
||||||
|
|
|
@ -1,146 +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;
|
|
||||||
dots->x1 = ((adconv->x1 - x_base) * 0x100) / x_div;
|
|
||||||
dots->y1 = ((adconv->y1 - y_base) * 0x100) / y_div;
|
|
||||||
dots->z1 = adconv->z1;
|
|
||||||
dots->x2 = ((adconv->x2 - x_base) * 0x100) / x_div;
|
|
||||||
dots->y2 = ((adconv->y2 - y_base) * 0x100) / y_div;
|
|
||||||
dots->z2 = adconv->z2;
|
|
||||||
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 */
|
|
|
@ -1,112 +0,0 @@
|
||||||
//---
|
|
||||||
// gint:touch:driver - touch-screen driver declaration
|
|
||||||
//---
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <gint/drivers.h>
|
|
||||||
#include <gint/drivers/states.h>
|
|
||||||
#include <gint/config.h>
|
|
||||||
|
|
||||||
#if GINT_HW_CP
|
|
||||||
|
|
||||||
#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_base = 0x20b;
|
|
||||||
__touch_drv_info.calibration.x_div = 0x9b6;
|
|
||||||
__touch_drv_info.calibration.y_base = 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_unbind() - unbind from gint to casio */
|
|
||||||
static void _touch_unbind(void)
|
|
||||||
{
|
|
||||||
i2c_unbind();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* _touch_funbind() - funbind from casio to gint */
|
|
||||||
static void _touch_funbind(void)
|
|
||||||
{
|
|
||||||
i2c_funbind();
|
|
||||||
}
|
|
||||||
|
|
||||||
//---
|
|
||||||
// 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_unbind,
|
|
||||||
.funbind = _touch_funbind,
|
|
||||||
.state_size = sizeof(touch_state_t),
|
|
||||||
};
|
|
||||||
GINT_DECLARE_DRIVER(24, drv_touch);
|
|
||||||
|
|
||||||
#endif /* GINT_HW_CP */
|
|
|
@ -1,30 +0,0 @@
|
||||||
#ifndef GINT_TOUCH_DRIVER_H
|
|
||||||
#define GINT_TOUCH_DRIVER_H 1
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <gint/keyboard.h>
|
|
||||||
#include <gint/touch.h>
|
|
||||||
#include <gint/config.h>
|
|
||||||
|
|
||||||
#if GINT_HW_CP
|
|
||||||
|
|
||||||
/* _touch_drv_info() - internal driver information */
|
|
||||||
struct _touch_drv_info
|
|
||||||
{
|
|
||||||
touch_calibration_t calibration;
|
|
||||||
key_event_t prev_evt;
|
|
||||||
struct {
|
|
||||||
bool prev_is_dual;
|
|
||||||
} adinfo;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* GINT_HW_CP */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* GINT_TOUCH_DRIVER_H */
|
|
254
src/touch/i2c.c
254
src/touch/i2c.c
|
@ -1,254 +0,0 @@
|
||||||
//---
|
|
||||||
// gint:touch:i2c - I2C driver
|
|
||||||
//---
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <gint/defs/attributes.h>
|
|
||||||
#include <gint/defs/types.h>
|
|
||||||
#include <gint/defs/call.h>
|
|
||||||
#include <gint/cpu.h>
|
|
||||||
#include <gint/intc.h>
|
|
||||||
#include <gint/config.h>
|
|
||||||
|
|
||||||
#if GINT_HW_CP
|
|
||||||
|
|
||||||
#include "./i2c.h"
|
|
||||||
|
|
||||||
//---
|
|
||||||
// Internals
|
|
||||||
//---
|
|
||||||
|
|
||||||
/* __i2c_request - internal I2C request information */
|
|
||||||
volatile struct i2c_request_info __i2c_request;
|
|
||||||
|
|
||||||
/* i2c_hw_enable() - enable the I2C peripheral and configure the clock
|
|
||||||
*
|
|
||||||
* notes
|
|
||||||
* Clock configuration are the same used by Casio. Investigation must be
|
|
||||||
* made to ensure overclock/underclock validity */
|
|
||||||
static void _i2c_hw_enable(void)
|
|
||||||
{
|
|
||||||
SH7305_I2C.ICCR.ICE = 1;
|
|
||||||
while(true) {
|
|
||||||
if (SH7305_I2C.ICSR.BUSY == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
SH7305_I2C.ICCL = 0x29;
|
|
||||||
SH7305_I2C.ICCH = 0x22;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* i2c_hw_start_operation() - start I2C operation
|
|
||||||
*
|
|
||||||
* notes
|
|
||||||
* Enable only data transmit and arbitration lost interrupt then perform
|
|
||||||
* a start condition (0x94) */
|
|
||||||
static void _i2c_hw_start_operation(void)
|
|
||||||
{
|
|
||||||
SH7305_I2C.ICIC.ALE = 1;
|
|
||||||
SH7305_I2C.ICIC.TACKE = 1;
|
|
||||||
SH7305_I2C.ICIC.WAITE = 0;
|
|
||||||
SH7305_I2C.ICIC.DTEE = 1;
|
|
||||||
SH7305_I2C.ICCR.byte = 0x94;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* i2c_request_await() - await async operation */
|
|
||||||
static int _i2c_request_await(void)
|
|
||||||
{
|
|
||||||
int status;
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
cpu_atomic_start();
|
|
||||||
status = (__i2c_request.status == I2C_REQ_STATUS_FINISHED);
|
|
||||||
cpu_atomic_end();
|
|
||||||
if (status)
|
|
||||||
break;
|
|
||||||
__asm__ volatile ("sleep");
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//---
|
|
||||||
// Public
|
|
||||||
//---
|
|
||||||
|
|
||||||
/* i2c_reg_select() - select a register */
|
|
||||||
int i2c_reg_select(int reg)
|
|
||||||
{
|
|
||||||
cpu_atomic_start();
|
|
||||||
_i2c_hw_enable();
|
|
||||||
|
|
||||||
__i2c_request.mode = I2C_REQ_MODE_REG_SELECT;
|
|
||||||
__i2c_request.target_register = reg;
|
|
||||||
__i2c_request.buffer = NULL;
|
|
||||||
__i2c_request.buffer_size = 0;
|
|
||||||
__i2c_request.buffer_size_remaning = 0;
|
|
||||||
__i2c_request.buffer_cursor = 0;
|
|
||||||
__i2c_request.status = I2C_REQ_STATUS_START;
|
|
||||||
__i2c_request.state = I2C_REQ_STATE_START;
|
|
||||||
|
|
||||||
cpu_atomic_end();
|
|
||||||
_i2c_hw_start_operation();
|
|
||||||
return _i2c_request_await();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* i2c_reg_read() - register read operation */
|
|
||||||
int i2c_reg_read(int reg, void *buffer, size_t size)
|
|
||||||
{
|
|
||||||
if (buffer == NULL)
|
|
||||||
return -1;
|
|
||||||
if (size == 0)
|
|
||||||
return -2;
|
|
||||||
|
|
||||||
cpu_atomic_start();
|
|
||||||
_i2c_hw_enable();
|
|
||||||
|
|
||||||
__i2c_request.mode = I2C_REQ_MODE_REG_READ;
|
|
||||||
__i2c_request.target_register = reg;
|
|
||||||
__i2c_request.buffer = buffer;
|
|
||||||
__i2c_request.buffer_size = size;
|
|
||||||
__i2c_request.buffer_size_remaning = size;
|
|
||||||
__i2c_request.buffer_cursor = 0;
|
|
||||||
__i2c_request.status = I2C_REQ_STATUS_START;
|
|
||||||
__i2c_request.state = I2C_REQ_STATE_START;
|
|
||||||
|
|
||||||
cpu_atomic_end();
|
|
||||||
_i2c_hw_start_operation();
|
|
||||||
return _i2c_request_await();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* i2c_read_stream() - "stream" read operation (skip reg selection) */
|
|
||||||
int i2c_read_stream(void *buffer, size_t size)
|
|
||||||
{
|
|
||||||
if (buffer == NULL)
|
|
||||||
return -1;
|
|
||||||
if (size == 0)
|
|
||||||
return -2;
|
|
||||||
|
|
||||||
cpu_atomic_start();
|
|
||||||
_i2c_hw_enable();
|
|
||||||
|
|
||||||
__i2c_request.mode = I2C_REQ_MODE_READ_STREAM;
|
|
||||||
__i2c_request.target_register = 0x00;
|
|
||||||
__i2c_request.buffer = buffer;
|
|
||||||
__i2c_request.buffer_size = size;
|
|
||||||
__i2c_request.buffer_size_remaning = size;
|
|
||||||
__i2c_request.buffer_cursor = 0;
|
|
||||||
__i2c_request.status = I2C_REQ_STATUS_START;
|
|
||||||
__i2c_request.state = I2C_REQ_STATE_START;
|
|
||||||
|
|
||||||
cpu_atomic_end();
|
|
||||||
_i2c_hw_start_operation();
|
|
||||||
return _i2c_request_await();
|
|
||||||
}
|
|
||||||
|
|
||||||
//---
|
|
||||||
// Driver and state management
|
|
||||||
//---
|
|
||||||
|
|
||||||
#include <gint/mpu/power.h>
|
|
||||||
#include <gint/mpu/pfc.h>
|
|
||||||
#include <gint/mpu/intc.h>
|
|
||||||
|
|
||||||
|
|
||||||
/* i2c_hpowered() - check if the module is powered */
|
|
||||||
bool i2c_hpowered(void)
|
|
||||||
{
|
|
||||||
return (SH7305_POWER.MSTPCR2.I2C == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* i2c_hpoweron() - power on the module */
|
|
||||||
void i2c_hpoweron(void)
|
|
||||||
{
|
|
||||||
SH7305_POWER.MSTPCR2.I2C = 0;
|
|
||||||
SH7305_I2C.ICCR.ICE = 0;
|
|
||||||
SH7305_I2C.ICDR = 0;
|
|
||||||
SH7305_I2C.ICCL = 0x00;
|
|
||||||
SH7305_I2C.ICCH = 0x00;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* i2c_hpoweroff() - power on the module */
|
|
||||||
void i2c_hpoweroff(void)
|
|
||||||
{
|
|
||||||
SH7305_POWER.MSTPCR2.I2C = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* i2c_hsave() - save hardware information */
|
|
||||||
void i2c_hsave(touch_state_t *state)
|
|
||||||
{
|
|
||||||
state->PJCR = SH7305_PFC.PJCR.word;
|
|
||||||
state->ICCR = SH7305_I2C.ICCR.byte;
|
|
||||||
state->ICIC = SH7305_I2C.ICIC.byte;
|
|
||||||
state->ICCL = SH7305_I2C.ICCL;
|
|
||||||
state->ICCH = SH7305_I2C.ICCH;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* i2c_hrestore() - restore hardware information */
|
|
||||||
void i2c_hrestore(touch_state_t *state)
|
|
||||||
{
|
|
||||||
SH7305_I2C.ICCH = state->ICCH;
|
|
||||||
SH7305_I2C.ICCL = state->ICCL;
|
|
||||||
SH7305_I2C.ICIC.byte = state->ICIC;
|
|
||||||
SH7305_I2C.ICCR.byte = state->ICCR;
|
|
||||||
SH7305_PFC.PJCR.word = state->PJCR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* i2c_configure() - configure and install interrupt handlers */
|
|
||||||
void i2c_configure(void)
|
|
||||||
{
|
|
||||||
extern void i2c_inth_tack(void);
|
|
||||||
extern void i2c_inth_wait(void);
|
|
||||||
extern void i2c_inth_trans(void);
|
|
||||||
extern void i2c_inth_al(void);
|
|
||||||
|
|
||||||
// install I2C handler
|
|
||||||
intc_handler_function(0xe00, GINT_CALL(i2c_inth_al));
|
|
||||||
intc_handler_function(0xe20, GINT_CALL(i2c_inth_tack));
|
|
||||||
intc_handler_function(0xe40, GINT_CALL(i2c_inth_wait));
|
|
||||||
intc_handler_function(0xe60, GINT_CALL(i2c_inth_trans));
|
|
||||||
|
|
||||||
// configure I2C PIN
|
|
||||||
SH7305_PFC.PJCR.P5MD = 0b00;
|
|
||||||
SH7305_PFC.PJCR.P4MD = 0b00;
|
|
||||||
|
|
||||||
// configure I2C module
|
|
||||||
SH7305_I2C.ICCR.ICE = 0;
|
|
||||||
SH7305_I2C.ICDR = 0;
|
|
||||||
SH7305_I2C.ICCL = 0x00;
|
|
||||||
SH7305_I2C.ICCH = 0x00;
|
|
||||||
SH7305_I2C.ICSR.byte = 0x00;
|
|
||||||
SH7305_I2C.ICIC.byte = 0x00;
|
|
||||||
|
|
||||||
// init high-level driver information
|
|
||||||
memset((void*)&__i2c_request, 0x00, sizeof(struct i2c_request_info));
|
|
||||||
__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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* i2c_unbind() - unbind from gint to casio */
|
|
||||||
void i2c_unbind(void)
|
|
||||||
{
|
|
||||||
_i2c_request_await();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* i2c_funbind() - funbind from casio to gint */
|
|
||||||
void i2c_funbind(void)
|
|
||||||
{
|
|
||||||
if (i2c_hpowered() == false)
|
|
||||||
return;
|
|
||||||
// fixme : avoid force terminate
|
|
||||||
// We cannot easily know the state of Casio's driver since they use
|
|
||||||
// an state machine to work, and finding the current state require a
|
|
||||||
// lot of hardcoded OS-specific offsets information. So, for now,
|
|
||||||
// force terminate the transaction and disable the module to avoid
|
|
||||||
// any error
|
|
||||||
SH7305_I2C.ICCR.ICE = 0;
|
|
||||||
SH7305_I2C.ICDR = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* GINT_HW_CP */
|
|
109
src/touch/i2c.h
109
src/touch/i2c.h
|
@ -1,109 +0,0 @@
|
||||||
#ifndef GINT_TOUCH_I2C_H
|
|
||||||
#define GINT_TOUCH_I2C_H 1
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <gint/defs/attributes.h>
|
|
||||||
#include <gint/defs/types.h>
|
|
||||||
#include <gint/config.h>
|
|
||||||
|
|
||||||
#if GINT_HW_CP
|
|
||||||
|
|
||||||
//---
|
|
||||||
// User API
|
|
||||||
//---
|
|
||||||
|
|
||||||
/* i2c_reg_select() - select a register */
|
|
||||||
extern int i2c_reg_select(int reg);
|
|
||||||
|
|
||||||
/* i2c_reg_read() - register read operation */
|
|
||||||
extern int i2c_reg_read(int reg, void *buffer, size_t size);
|
|
||||||
|
|
||||||
/* i2c_read_stream() - "stream" read operation (skip reg selection) */
|
|
||||||
extern int i2c_read_stream(void *buffer, size_t size);
|
|
||||||
|
|
||||||
//---
|
|
||||||
// Internals
|
|
||||||
//---
|
|
||||||
|
|
||||||
/* i2c_request_mode - enumerate request mode */
|
|
||||||
enum i2c_request_mode {
|
|
||||||
I2C_REQ_MODE_REG_READ = 0,
|
|
||||||
I2C_REQ_MODE_REG_WRITE = 1,
|
|
||||||
I2C_REQ_MODE_REG_SELECT = 2,
|
|
||||||
I2C_REQ_MODE_READ_STREAM = 3,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* i2c_request_status - request status */
|
|
||||||
enum i2c_request_status {
|
|
||||||
I2C_REQ_STATUS_START = 0,
|
|
||||||
I2C_REQ_STATUS_FINISHED = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum i2c_request_state {
|
|
||||||
I2C_REQ_STATE_START = 0,
|
|
||||||
I2C_REQ_STATE_REG_SELECT = 10,
|
|
||||||
I2C_REQ_STATE_REG_SELECT_WAIT = 11,
|
|
||||||
I2C_REQ_STATE_SWITCH_TO_RECEIVE = 20,
|
|
||||||
I2C_REQ_STATE_SWITCH_TO_RECEIVE_WAIT = 21,
|
|
||||||
I2C_REQ_STATE_READ = 30,
|
|
||||||
I2C_REQ_STATE_READ_LAST = 31,
|
|
||||||
I2C_REQ_STATE_ZOMBIE = 667,
|
|
||||||
I2C_REQ_STATE_DEAD = 2617,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* struct i2c_request_info - internal I2C request information */
|
|
||||||
struct i2c_request_info {
|
|
||||||
enum i2c_request_mode mode;
|
|
||||||
int target_register;
|
|
||||||
uint8_t *buffer;
|
|
||||||
size_t buffer_size;
|
|
||||||
size_t buffer_size_remaning;
|
|
||||||
size_t buffer_cursor;
|
|
||||||
enum i2c_request_status status;
|
|
||||||
int state;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* __i2c_request - internal current I2C request */
|
|
||||||
extern volatile struct i2c_request_info __i2c_request;
|
|
||||||
|
|
||||||
//---
|
|
||||||
// Hardware information
|
|
||||||
//---
|
|
||||||
|
|
||||||
#include <gint/drivers/states.h>
|
|
||||||
#include <gint/mpu/i2c.h>
|
|
||||||
|
|
||||||
/* i2c_configure() - driver/hardware configuration */
|
|
||||||
extern void i2c_configure(void);
|
|
||||||
|
|
||||||
/* i2c_hsave() - save hardware information */
|
|
||||||
extern void i2c_hsave(touch_state_t *states);
|
|
||||||
|
|
||||||
/* i2c_hrestore() - restore hardware information */
|
|
||||||
extern void i2c_hrestore(touch_state_t *states);
|
|
||||||
|
|
||||||
/* i2c_hpowered() - check if the module is powered */
|
|
||||||
extern bool i2c_hpowered(void);
|
|
||||||
|
|
||||||
/* i2c_hpoweron() - power on the module */
|
|
||||||
extern void i2c_hpoweron(void);
|
|
||||||
|
|
||||||
/* i2c_hpoweroff() - power off the module */
|
|
||||||
extern void i2c_hpoweroff(void);
|
|
||||||
|
|
||||||
/* i2c_funbind() - funbind from casio to gint */
|
|
||||||
extern void i2c_funbind(void);
|
|
||||||
|
|
||||||
/* i2c_unbind() - unbind from gint to casio */
|
|
||||||
extern void i2c_unbind(void);
|
|
||||||
|
|
||||||
#endif /* GINT_HW_CP */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* GINT_TOUCH_I2C_H */
|
|
|
@ -1,171 +0,0 @@
|
||||||
//---
|
|
||||||
// gint:touch:i2c_inth - I2C interrupt handlers
|
|
||||||
//---
|
|
||||||
#include <gint/exc.h>
|
|
||||||
#include <gint/config.h>
|
|
||||||
|
|
||||||
#if GINT_HW_CP
|
|
||||||
|
|
||||||
#include "./i2c.h"
|
|
||||||
|
|
||||||
//---
|
|
||||||
// Private
|
|
||||||
//---
|
|
||||||
|
|
||||||
/* _i2c_inth_read() - generic read byte operation */
|
|
||||||
static int _i2c_inth_io_operation(bool read)
|
|
||||||
{
|
|
||||||
if (read) {
|
|
||||||
__i2c_request.buffer[
|
|
||||||
__i2c_request.buffer_cursor
|
|
||||||
] = SH7305_I2C.ICDR;
|
|
||||||
} else {
|
|
||||||
SH7305_I2C.ICDR = __i2c_request.buffer[
|
|
||||||
__i2c_request.buffer_cursor
|
|
||||||
];
|
|
||||||
}
|
|
||||||
__i2c_request.buffer_cursor += 1;
|
|
||||||
__i2c_request.buffer_size_remaning -= 1;
|
|
||||||
return __i2c_request.buffer_size_remaning;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* _i2c_inth_stop() - stop I2C module (with force wait) */
|
|
||||||
static void _i2c_inth_stop(void)
|
|
||||||
{
|
|
||||||
while(true) {
|
|
||||||
if (SH7305_I2C.ICSR.BUSY == 0)
|
|
||||||
break;
|
|
||||||
SH7305_I2C.ICDR = SH7305_I2C.ICDR;
|
|
||||||
}
|
|
||||||
SH7305_I2C.ICIC.byte = 0x00;
|
|
||||||
SH7305_I2C.ICSR.byte = 0x00;
|
|
||||||
SH7305_I2C.ICCR.byte = 0x00;
|
|
||||||
__i2c_request.state = I2C_REQ_STATE_DEAD;
|
|
||||||
__i2c_request.status = I2C_REQ_STATUS_FINISHED;
|
|
||||||
}
|
|
||||||
|
|
||||||
//---
|
|
||||||
// Public
|
|
||||||
//---
|
|
||||||
|
|
||||||
/* i2c_inth_trans() - TRANS interrupt handler */
|
|
||||||
void i2c_inth_trans(void)
|
|
||||||
{
|
|
||||||
switch (__i2c_request.state)
|
|
||||||
{
|
|
||||||
// start byte (writing or reading) and select the proper mode
|
|
||||||
// note that the "read stream" just changes the internal state
|
|
||||||
// because the starting byte (0x81) is force-sent over there
|
|
||||||
case I2C_REQ_STATE_START:
|
|
||||||
SH7305_I2C.ICIC.DTEE = 0;
|
|
||||||
SH7305_I2C.ICIC.WAITE = 1;
|
|
||||||
if (__i2c_request.mode == I2C_REQ_MODE_READ_STREAM) {
|
|
||||||
SH7305_I2C.ICDR = 0x81;
|
|
||||||
__i2c_request.state = I2C_REQ_STATE_SWITCH_TO_RECEIVE_WAIT;
|
|
||||||
} else {
|
|
||||||
SH7305_I2C.ICDR = 0x80;
|
|
||||||
__i2c_request.state = I2C_REQ_STATE_REG_SELECT;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
// switch the I2C module to receive mode and setup the next state
|
|
||||||
// use WAIT interrupt to really switch the I2C to receive
|
|
||||||
case I2C_REQ_STATE_SWITCH_TO_RECEIVE:
|
|
||||||
SH7305_I2C.ICIC.DTEE = 0;
|
|
||||||
SH7305_I2C.ICDR = 0x81;
|
|
||||||
__i2c_request.state = I2C_REQ_STATE_SWITCH_TO_RECEIVE_WAIT;
|
|
||||||
break;
|
|
||||||
|
|
||||||
// for the read operation, the only thing to do is to send the
|
|
||||||
// ACK at the end of the operation
|
|
||||||
case I2C_REQ_STATE_READ:
|
|
||||||
SH7305_I2C.ICIC.DTEE = 0;
|
|
||||||
if (_i2c_inth_io_operation(true) == 0)
|
|
||||||
_i2c_inth_stop();
|
|
||||||
break;
|
|
||||||
|
|
||||||
// error, unsupported sequences display tests/debug information
|
|
||||||
default:
|
|
||||||
gint_panic(0x10e0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* i2c_inth_wait() - WAIT interrupt handler */
|
|
||||||
void i2c_inth_wait(void)
|
|
||||||
{
|
|
||||||
switch (__i2c_request.state)
|
|
||||||
{
|
|
||||||
// indicate which register to perform the operation
|
|
||||||
// we will wait the next WAIT interrupt to ensure that the data has
|
|
||||||
// been sent
|
|
||||||
case I2C_REQ_STATE_REG_SELECT:
|
|
||||||
SH7305_I2C.ICDR = __i2c_request.target_register;
|
|
||||||
__i2c_request.state = I2C_REQ_STATE_REG_SELECT_WAIT;
|
|
||||||
SH7305_I2C.ICSR.WAIT = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
// the selected register is confirmed, stop or restart
|
|
||||||
// note that if the "select register" request is performed (or if
|
|
||||||
// no buffer is provided) then we send the stop condition (0x90)
|
|
||||||
// and force-stop the module.
|
|
||||||
// Otherwise, we trigger a new request (0x94) to (after
|
|
||||||
// the restart interruption) switch manually from "reading" or
|
|
||||||
// "writing" mode
|
|
||||||
case I2C_REQ_STATE_REG_SELECT_WAIT:
|
|
||||||
if (
|
|
||||||
__i2c_request.mode == I2C_REQ_MODE_REG_SELECT
|
|
||||||
|| __i2c_request.buffer_size_remaning == 0
|
|
||||||
|| __i2c_request.buffer == NULL
|
|
||||||
) {
|
|
||||||
SH7305_I2C.ICCR.byte = 0x90;
|
|
||||||
SH7305_I2C.ICSR.WAIT = 0;
|
|
||||||
_i2c_inth_stop();
|
|
||||||
} else {
|
|
||||||
SH7305_I2C.ICCR.byte = 0x94;
|
|
||||||
__i2c_request.state = I2C_REQ_STATE_SWITCH_TO_RECEIVE;
|
|
||||||
SH7305_I2C.ICIC.DTEE = 1;
|
|
||||||
SH7305_I2C.ICSR.WAIT = 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
// switch to receive mode
|
|
||||||
// waiting the next WAIT interrupt to start reading
|
|
||||||
case I2C_REQ_STATE_SWITCH_TO_RECEIVE_WAIT:
|
|
||||||
SH7305_I2C.ICCR.byte = 0x81;
|
|
||||||
__i2c_request.state = I2C_REQ_STATE_READ;
|
|
||||||
SH7305_I2C.ICSR.WAIT = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
// read operation
|
|
||||||
// can either be WAIT or DTE interrupt, a special case is
|
|
||||||
// performed to avoid DTE interrupt
|
|
||||||
case I2C_REQ_STATE_READ:
|
|
||||||
if (__i2c_request.buffer_size_remaning > 1) {
|
|
||||||
if (SH7305_I2C.ICSR.DTE != 0)
|
|
||||||
_i2c_inth_io_operation(true);
|
|
||||||
}
|
|
||||||
if (__i2c_request.buffer_size_remaning == 1)
|
|
||||||
SH7305_I2C.ICCR.byte = 0xc0;
|
|
||||||
SH7305_I2C.ICIC.DTEE = 1;
|
|
||||||
SH7305_I2C.ICSR.WAIT = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
// error cases, unable to handle the WAIT interrupt
|
|
||||||
default:
|
|
||||||
gint_panic(0x10e0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* i2c_inth_tack() - TACK interrupt handler */
|
|
||||||
void i2c_inth_tack(void)
|
|
||||||
{
|
|
||||||
gint_panic(0x10e0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* i2c_inth_al() - AL interrupt handler */
|
|
||||||
void i2c_inth_al(void)
|
|
||||||
{
|
|
||||||
gint_panic(0x10e0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* GINT_HW_CP */
|
|
|
@ -1,95 +0,0 @@
|
||||||
//---
|
|
||||||
// gint:touch - touch driver (high-level)
|
|
||||||
//----
|
|
||||||
#include <string.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"
|
|
||||||
|
|
||||||
//---
|
|
||||||
// Internals
|
|
||||||
//---
|
|
||||||
|
|
||||||
/* __touch_drv_info - internal driver information */
|
|
||||||
extern struct _touch_drv_info __touch_drv_info;
|
|
||||||
|
|
||||||
//---
|
|
||||||
// Public
|
|
||||||
//---
|
|
||||||
|
|
||||||
// user-API
|
|
||||||
|
|
||||||
/* touch_calib_get() - get calibration information */
|
|
||||||
int touch_calib_get(touch_calibration_t *calib)
|
|
||||||
{
|
|
||||||
if (calib == NULL)
|
|
||||||
return -1;
|
|
||||||
memcpy(calib, &__touch_drv_info.calibration, sizeof(*calib));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* touch_calib_set() - set calibration information */
|
|
||||||
int touch_calib_set(touch_calibration_t *calib)
|
|
||||||
{
|
|
||||||
if (calib == NULL)
|
|
||||||
return -1;
|
|
||||||
memcpy(&__touch_drv_info.calibration, calib, sizeof(*calib));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// low-level API
|
|
||||||
|
|
||||||
/* touch_next_event() - get the next touch event */
|
|
||||||
key_event_t touch_next_event(void)
|
|
||||||
{
|
|
||||||
struct _touch_adconv adconv;
|
|
||||||
struct _touch_addots addots;
|
|
||||||
struct _touch_adraw adraw;
|
|
||||||
key_event_t evt;
|
|
||||||
int type;
|
|
||||||
|
|
||||||
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)
|
|
||||||
) {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* GINT_HW_CP */
|
|
Loading…
Add table
Reference in a new issue