summaryrefslogtreecommitdiffstats
path: root/firmware
diff options
context:
space:
mode:
authorAmaury Pouly <pamaury@rockbox.org>2011-05-13 16:40:22 +0000
committerAmaury Pouly <pamaury@rockbox.org>2011-05-13 16:40:22 +0000
commita43509cc99a11665902ef8bba44c4ba2c9553236 (patch)
tree44be0dfc4ed204f58ec200c6363eff6537cef40a /firmware
parentbdb8f4c15cd60c7c4f648f1c6ba4bfd7c87383c0 (diff)
downloadrockbox-a43509cc99a11665902ef8bba44c4ba2c9553236.tar.gz
rockbox-a43509cc99a11665902ef8bba44c4ba2c9553236.zip
fuze+: implement a full-blown debug screen for touchpad with graphical feedback
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29869 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r--firmware/export/synaptics-rmi.h68
-rw-r--r--firmware/target/arm/imx233/sansa-fuzeplus/button-fuzeplus.c146
2 files changed, 186 insertions, 28 deletions
diff --git a/firmware/export/synaptics-rmi.h b/firmware/export/synaptics-rmi.h
index 59fbb807ab..2d7a0c8c1e 100644
--- a/firmware/export/synaptics-rmi.h
+++ b/firmware/export/synaptics-rmi.h
@@ -41,6 +41,74 @@
#define RMI_2D_SENSOR_YMAX_MSB(s) RMI_2D_REG(8 * (s) + 0x6)
#define RMI_2D_SENSOR_YMAX_LSB(s) RMI_2D_REG(8 * (s) + 0x7)
#define RMI_2D_SENSOR_RESOLUTION(s) RMI_2D_REG(8 * (s) + 0x8)
+#define RMI_2D_GLOBAL_SETTINGS RMI_2D_REG(0x41)
+#define RMI_2D_GESTURE_SETTINGS RMI_2D_REG(0x42)
+#define RMI_2D_GESTURE_PRESS_TIME_BM 0x7
+#define RMI_2D_GESTURE_PRESS_TIME_300MS 0
+#define RMI_2D_GESTURE_PRESS_TIME_400MS 1
+#define RMI_2D_GESTURE_PRESS_TIME_500MS 2
+#define RMI_2D_GESTURE_PRESS_TIME_600MS 3
+#define RMI_2D_GESTURE_PRESS_TIME_700MS 4
+#define RMI_2D_GESTURE_PRESS_TIME_800MS 5
+#define RMI_2D_GESTURE_PRESS_TIME_900MS 6
+#define RMI_2D_GESTURE_PRESS_TIME_1S 7
+#define RMI_2D_GESTURE_FLICK_DIST_BM (0x7 << 3)
+#define RMI_2D_GESTURE_FLICK_DIST_BP 3
+#define RMI_2D_GESTURE_FLICK_DIST_4MM 0
+#define RMI_2D_GESTURE_FLICK_DIST_5MM 1
+#define RMI_2D_GESTURE_FLICK_DIST_6MM 2
+#define RMI_2D_GESTURE_FLICK_DIST_7MM 3
+#define RMI_2D_GESTURE_FLICK_DIST_8MM 4
+#define RMI_2D_GESTURE_FLICK_DIST_9MM 5
+#define RMI_2D_GESTURE_FLICK_DIST_10MM 6
+#define RMI_2D_GESTURE_FLICK_DIST_11MM 7
+#define RMI_2D_GESTURE_FLICK_TIME_BM (2 << 6)
+#define RMI_2D_GESTURE_FLICK_TIME_BP 6
+#define RMI_2D_GESTURE_FLICK_TIME_250MS 0
+#define RMI_2D_GESTURE_FLICK_TIME_400MS 1
+#define RMI_2D_GESTURE_FLICK_TIME_550MS 2
+#define RMI_2D_GESTURE_FLICK_TIME_700MS 3
+#define RMI_2D_SENSITIVITY_ADJ RMI_2D_REG(0x44)
+#define RMI_2D_MIN_DIST RMI_2D_REG(0x45)
+/* 2D TouchPad/ClearPad data registers */
+struct rmi_2d_absolute_data_t
+{
+ unsigned char misc;
+ unsigned char z;
+ unsigned char x_msb;
+ unsigned char x_lsb;
+ unsigned char y_msb;
+ unsigned char y_lsb;
+} __attribute__((packed));
+
+#define RMI_2D_ABS_MISC_NR_FINGERS_BM 7
+#define RMI_2D_ABS_MISC_GESTURE (1 << 3)
+#define RMI_2D_ABS_MISC_WIDTH_BM 0xf0
+#define RMI_2D_ABS_MISC_WIDTH_BP 4
+#define RMI_2D_GEST_MISC_TAP_CODE_BM 7
+#define RMI_2D_GEST_MISC_NO_TAP 0
+#define RMI_2D_GEST_MISC_SINGLE_TAP 1
+#define RMI_2D_GEST_MISC_TAP_AND_HOLD 2
+#define RMI_2D_GEST_MISC_DOUBLE_TAP 3
+#define RMI_2D_GEST_MISC_PRESS (1 << 3)
+#define RMI_2D_GEST_MISC_FLICK (1 << 4)
+#define RMI_2D_GEST_MISC_PINCH (1 << 5)
+#define RMI_2D_GEST_MISC_CONFIRMED (1 << 7)
+#define RMI_2D_GEST_FLICK_X_BM 0x0f
+#define RMI_2D_GEST_FLICK_Y_BM 0xf0
+#define RMI_2D_GEST_FLICK_Y_BP 4
+
+struct rmi_2d_relative_data_t
+{
+ signed char x; /* signed */
+ signed char y; /* signed */
+} __attribute__((packed));
+
+struct rmi_2d_gesture_data_t
+{
+ unsigned char misc;
+ unsigned char flick;
+} __attribute__((packed));
/* Initialize the RMI driver, the i2c_bus_index is the bus index returned by
* the generic_i2c driver; the i2c_dev_addr is the i2c address of the device.
diff --git a/firmware/target/arm/imx233/sansa-fuzeplus/button-fuzeplus.c b/firmware/target/arm/imx233/sansa-fuzeplus/button-fuzeplus.c
index 1b8116b1b7..b6de9f73d8 100644
--- a/firmware/target/arm/imx233/sansa-fuzeplus/button-fuzeplus.c
+++ b/firmware/target/arm/imx233/sansa-fuzeplus/button-fuzeplus.c
@@ -25,6 +25,7 @@
#include "generic_i2c.h"
#include "synaptics-rmi.h"
#include "lcd.h"
+#include "string.h"
static void i2c_scl_dir(bool out)
{
@@ -84,51 +85,135 @@ void button_debug_screen(void)
{
char product_id[RMI_PRODUCT_ID_LEN];
rmi_read(RMI_PRODUCT_ID, RMI_PRODUCT_ID_LEN, product_id);
+ int x_max = rmi_read_single(RMI_2D_SENSOR_XMAX_MSB(0)) << 8 | rmi_read_single(RMI_2D_SENSOR_XMAX_LSB(0));
+ int y_max = rmi_read_single(RMI_2D_SENSOR_YMAX_MSB(0)) << 8 | rmi_read_single(RMI_2D_SENSOR_YMAX_LSB(0));
+ int func_presence = rmi_read_single(RMI_FUNCTION_PRESENCE(RMI_2D_TOUCHPAD_FUNCTION));
+ int sensor_prop = rmi_read_single(RMI_2D_SENSOR_PROP2(0));
+ int sensor_resol = rmi_read_single(RMI_2D_SENSOR_RESOLUTION(0));
+ int min_dist = rmi_read_single(RMI_2D_MIN_DIST);
+ int gesture_settings = rmi_read_single(RMI_2D_GESTURE_SETTINGS);
+ union
+ {
+ unsigned char data;
+ signed char value;
+ }sensitivity;
+ rmi_read(RMI_2D_SENSITIVITY_ADJ, 1, &sensitivity.data);
+ /* Device to screen */
+ int zone_w = LCD_WIDTH;
+ int zone_h = (zone_w * y_max + x_max - 1) / x_max;
+ int zone_x = 0;
+ int zone_y = LCD_HEIGHT - zone_h;
+ #define DX2SX(x) (((x) * zone_w ) / x_max)
+ #define DY2SY(y) (zone_h - ((y) * zone_h ) / y_max)
+ struct viewport report_vp;
+ memset(&report_vp, 0, sizeof(report_vp));
+ report_vp.x = zone_x;
+ report_vp.y = zone_y;
+ report_vp.width = zone_w;
+ report_vp.height = zone_h;
+ struct viewport gesture_vp;
+ memset(&gesture_vp, 0, sizeof(gesture_vp));
+ gesture_vp.x = 0;
+ gesture_vp.y = zone_y - 80;
+ gesture_vp.width = LCD_WIDTH;
+ gesture_vp.height = 80;
+
while(1)
{
+ lcd_set_viewport(NULL);
lcd_clear_display();
int btns = button_read_device();
lcd_putsf(0, 0, "button bitmap: %x", btns);
- lcd_putsf(0, 1, "RMI: product=%s", product_id);
- lcd_putsf(0, 2, "touchpad presence: %x", rmi_read_single(RMI_FUNCTION_PRESENCE(RMI_2D_TOUCHPAD_FUNCTION)));
- lcd_putsf(0, 3, "sensor prop: %x", rmi_read_single(RMI_2D_SENSOR_PROP2(0)));
- int x_max = rmi_read_single(RMI_2D_SENSOR_XMAX_MSB(0)) << 8 | rmi_read_single(RMI_2D_SENSOR_XMAX_LSB(0));
- int y_max = rmi_read_single(RMI_2D_SENSOR_YMAX_MSB(0)) << 8 | rmi_read_single(RMI_2D_SENSOR_YMAX_LSB(0));
- lcd_putsf(0, 4, "xmax=%d ymax=%d res=%d", x_max, y_max,
- rmi_read_single(RMI_2D_SENSOR_RESOLUTION(0)));
- lcd_putsf(0, 5, "din0=%x", imx233_get_gpio_input_mask(0, 0x08000000));
- lcd_putsf(0, 6, "dev ctl: %x", rmi_read_single(RMI_DEVICE_CONTROL));
- lcd_putsf(0, 7, "int en: %x", rmi_read_single(RMI_INTERRUPT_ENABLE));
- lcd_putsf(0, 8, "int req: %x", rmi_read_single(RMI_INTERRUPT_REQUEST));
+ lcd_putsf(0, 1, "RMI: id=%s p=%x s=%x", product_id, func_presence, sensor_prop);
+ lcd_putsf(0, 2, "xmax=%d ymax=%d res=%d", x_max, y_max, sensor_resol);
+ lcd_putsf(0, 3, "attn=%d ctl=%x int=%x",
+ imx233_get_gpio_input_mask(0, 0x08000000) ? 0 : 1,
+ rmi_read_single(RMI_DEVICE_CONTROL),
+ rmi_read_single(RMI_INTERRUPT_REQUEST));
+ lcd_putsf(0, 4, "sensi: %d min_dist: %d", (int)sensitivity.value, min_dist);
+ lcd_putsf(0, 5, "gesture: %x", gesture_settings);
+
union
{
unsigned char data[10];
struct
{
- unsigned char absolute_misc;
- unsigned char absolute_z;
- unsigned char absolute_x_msb;
- unsigned char absolute_x_lsb;
- unsigned char absolute_y_msb;
- unsigned char absolute_y_lsb;
- signed char relative_x; /* signed */
- signed char relative_y; /* signed */
- unsigned char gesture_misc;
- unsigned char gesture_flick;
- } __attribute__((packed)) s;
+ struct rmi_2d_absolute_data_t absolute;
+ struct rmi_2d_relative_data_t relative;
+ struct rmi_2d_gesture_data_t gesture;
+ }s;
}u;
- int absolute_x = u.s.absolute_x_msb << 8 | u.s.absolute_x_lsb;
- int absolute_y = u.s.absolute_y_msb << 8 | u.s.absolute_y_lsb;
+ int absolute_x = u.s.absolute.x_msb << 8 | u.s.absolute.x_lsb;
+ int absolute_y = u.s.absolute.y_msb << 8 | u.s.absolute.y_lsb;
+ int nr_fingers = u.s.absolute.misc & 7;
+ bool gesture = (u.s.absolute.misc & 8) == 8;
+ int palm_width = u.s.absolute.misc >> 4;
rmi_read(RMI_DATA_REGISTER(0), 10, u.data);
- lcd_putsf(0, 9, "abs: %d %d", absolute_x, absolute_y);
- lcd_putsf(0, 10, "rel: %d %d", (int)u.s.relative_x, (int)u.s.relative_y);
- lcd_putsf(0, 11, "gesture: %x %x", u.s.gesture_misc, u.s.gesture_flick);
-
+ lcd_putsf(0, 6, "abs: %d %d %d", absolute_x, absolute_y, (int)u.s.absolute.z);
+ lcd_putsf(0, 7, "rel: %d %d", (int)u.s.relative.x, (int)u.s.relative.y);
+ lcd_putsf(0, 8, "gesture: %x %x", u.s.gesture.misc, u.s.gesture.flick);
+ lcd_putsf(0, 9, "misc: w=%d g=%d f=%d", palm_width, gesture, nr_fingers);
+
+ lcd_set_viewport(&report_vp);
+ lcd_set_drawinfo(DRMODE_SOLID, LCD_RGBPACK(0xff, 0, 0), LCD_BLACK);
+ lcd_drawrect(0, 0, zone_w, zone_h);
+ if(nr_fingers == 1)
+ {
+ lcd_set_drawinfo(DRMODE_SOLID, LCD_RGBPACK(0, 0, 0xff), LCD_BLACK);
+ lcd_drawline(DX2SX(absolute_x) - u.s.relative.x,
+ DY2SY(absolute_y) + u.s.relative.y,
+ DX2SX(absolute_x), DY2SY(absolute_y));
+ lcd_set_drawinfo(DRMODE_SOLID, LCD_RGBPACK(0, 0xff, 0), LCD_BLACK);
+ lcd_fillrect(DX2SX(absolute_x) - 1, DY2SY(absolute_y) - 1, 3, 3);
+ }
+ lcd_set_viewport(&gesture_vp);
+ lcd_set_drawinfo(DRMODE_SOLID, LCD_RGBPACK(0xff, 0xff, 0), LCD_BLACK);
+ if(u.s.gesture.misc & RMI_2D_GEST_MISC_CONFIRMED)
+ {
+ switch(u.s.gesture.misc & RMI_2D_GEST_MISC_TAP_CODE_BM)
+ {
+ case RMI_2D_GEST_MISC_NO_TAP: break;
+ case RMI_2D_GEST_MISC_SINGLE_TAP:
+ lcd_putsf(0, 0, "TAP!");
+ break;
+ case RMI_2D_GEST_MISC_DOUBLE_TAP:
+ lcd_putsf(0, 0, "DOUBLE TAP!");
+ break;
+ case RMI_2D_GEST_MISC_TAP_AND_HOLD:
+ lcd_putsf(0, 0, "TAP & HOLD!");
+ break;
+ default: break;
+ }
+
+ if(u.s.gesture.misc & RMI_2D_GEST_MISC_FLICK)
+ {
+ lcd_putsf(0, 1, "FLICK!");
+ int flick_x = u.s.gesture.flick & RMI_2D_GEST_FLICK_X_BM;
+ int flick_y = (u.s.gesture.flick & RMI_2D_GEST_FLICK_Y_BM) >> RMI_2D_GEST_FLICK_Y_BP;
+ #define SIGN4EXT(a) \
+ if(a & 8) a = -((a ^ 0xf) + 1);
+ SIGN4EXT(flick_x);
+ SIGN4EXT(flick_y);
+
+ int center_x = (LCD_WIDTH * 2) / 3;
+ int center_y = 40;
+ lcd_drawline(center_x, center_y, center_x + flick_x * 5, center_y - flick_y * 5);
+ }
+ }
lcd_update();
if(btns & BUTTON_POWER)
break;
+ if(btns & BUTTON_VOL_DOWN || btns & BUTTON_VOL_UP)
+ {
+ if(btns & BUTTON_VOL_UP)
+ sensitivity.value++;
+ if(btns & BUTTON_VOL_DOWN)
+ sensitivity.value--;
+ rmi_write(RMI_2D_SENSITIVITY_ADJ, 1, &sensitivity.data);
+ }
+
yield();
}
}
@@ -159,6 +244,11 @@ void button_init_device(void)
*
* ATTENTION line: B0P27 asserted low
*/
+ rmi_write_single(RMI_2D_SENSITIVITY_ADJ, 5);
+ rmi_write_single(RMI_2D_GESTURE_SETTINGS,
+ RMI_2D_GESTURE_PRESS_TIME_300MS |
+ RMI_2D_GESTURE_FLICK_DIST_4MM << RMI_2D_GESTURE_FLICK_DIST_BP |
+ RMI_2D_GESTURE_FLICK_TIME_700MS << RMI_2D_GESTURE_FLICK_TIME_BP);
}
int button_read_device(void)