From a43509cc99a11665902ef8bba44c4ba2c9553236 Mon Sep 17 00:00:00 2001 From: Amaury Pouly Date: Fri, 13 May 2011 16:40:22 +0000 Subject: 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 --- firmware/export/synaptics-rmi.h | 68 ++++++++++ .../arm/imx233/sansa-fuzeplus/button-fuzeplus.c | 146 +++++++++++++++++---- 2 files changed, 186 insertions(+), 28 deletions(-) (limited to 'firmware') 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) -- cgit v1.2.3