diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2014-02-10 11:53:37 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2014-02-10 11:53:37 -0600 |
commit | da2b06fc9b4934db950f8218bb0c17829cd381a9 (patch) | |
tree | 3200388b06c9c4e75b47b0bdce2cd7538fbed1e4 | |
parent | 105f5fbfcbbf411deefddac8039ccb3b03477609 (diff) | |
download | nuttx-da2b06fc9b4934db950f8218bb0c17829cd381a9.tar.gz nuttx-da2b06fc9b4934db950f8218bb0c17829cd381a9.tar.bz2 nuttx-da2b06fc9b4934db950f8218bb0c17829cd381a9.zip |
HID mouse can now support some while mice. Problems with Microsoft mice
-rw-r--r-- | apps/ChangeLog.txt | 2 | ||||
-rw-r--r-- | apps/examples/touchscreen/tc_main.c | 3 | ||||
-rw-r--r-- | nuttx/ChangeLog | 2 | ||||
-rw-r--r-- | nuttx/configs/olimex-lpc1766stk/hidmouse/defconfig | 2 | ||||
-rw-r--r-- | nuttx/drivers/input/Kconfig | 17 | ||||
-rw-r--r-- | nuttx/drivers/usbhost/Kconfig | 49 | ||||
-rw-r--r-- | nuttx/drivers/usbhost/usbhost_hidmouse.c | 184 | ||||
-rw-r--r-- | nuttx/include/nuttx/input/mouse.h | 7 | ||||
-rw-r--r-- | nuttx/include/nuttx/usb/hid.h | 3 |
9 files changed, 211 insertions, 58 deletions
diff --git a/apps/ChangeLog.txt b/apps/ChangeLog.txt index db1afab2c..5f88f72cc 100644 --- a/apps/ChangeLog.txt +++ b/apps/ChangeLog.txt @@ -818,5 +818,5 @@ an option and can be replaces with the EMACX-like CLE (about 2KB) (2014-02-02). * Several changes to restore Windows native build (2014-2-7) - * apps/examples/touchscreen: Can not be configured to work with a mouse + * apps/examples/touchscreen: Can now be configured to work with a mouse interface as well (2014-2-10). diff --git a/apps/examples/touchscreen/tc_main.c b/apps/examples/touchscreen/tc_main.c index 13a192a0d..0eb83ca4e 100644 --- a/apps/examples/touchscreen/tc_main.c +++ b/apps/examples/touchscreen/tc_main.c @@ -197,6 +197,9 @@ int tc_main(int argc, char *argv[]) message(" buttons : %02x\n", sample.buttons); message(" x : %d\n", sample.x); message(" y : %d\n", sample.y); +#ifdef CONFIG_MOUSE_WHEEL + message(" wheel : %d\n", sample.wheel); +#endif } #else /* Read one sample */ diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog index 41a32ca61..ff6ba917d 100644 --- a/nuttx/ChangeLog +++ b/nuttx/ChangeLog @@ -6564,3 +6564,5 @@ touchscreen drivers, mouse drivers need to report positional data with no button is pressed so that the mouse position can drive a cursor (2014-2-10). + * drivers/usbhost/usbhost_hidmouse.c, include/nuttx/input/mouse.h, and + include/nuttx/usb/hid.h: Add support for a mouse wheel (2014-2-10). diff --git a/nuttx/configs/olimex-lpc1766stk/hidmouse/defconfig b/nuttx/configs/olimex-lpc1766stk/hidmouse/defconfig index a5e376f5e..6da409738 100644 --- a/nuttx/configs/olimex-lpc1766stk/hidmouse/defconfig +++ b/nuttx/configs/olimex-lpc1766stk/hidmouse/defconfig @@ -362,6 +362,8 @@ CONFIG_DEV_NULL=y # CONFIG_VIDEO_DEVICES is not set # CONFIG_BCH is not set CONFIG_INPUT=y +CONFIG_MOUSE=y +# CONFIG_MOUSE_WHEEL is not set # CONFIG_INPUT_TSC2007 is not set # CONFIG_INPUT_ADS7843E is not set # CONFIG_INPUT_STMPE811 is not set diff --git a/nuttx/drivers/input/Kconfig b/nuttx/drivers/input/Kconfig index b57aab8a8..d596dfc1c 100644 --- a/nuttx/drivers/input/Kconfig +++ b/nuttx/drivers/input/Kconfig @@ -3,6 +3,23 @@ # see misc/tools/kconfig-language.txt. # +config MOUSE + bool "Enable mouse support" + default n + ---help--- + Enable support for mouse devices. + +if MOUSE + +config MOUSE_WHEEL + bool "Enable mouse wheel support" + default n + ---help--- + Enable support for a 4-button mouse report that includes a while + position. + +endif # MOUSE + config INPUT_TSC2007 bool "TI TSC2007 touchscreen controller" default n diff --git a/nuttx/drivers/usbhost/Kconfig b/nuttx/drivers/usbhost/Kconfig index 5fe08bdc8..56ba022ac 100644 --- a/nuttx/drivers/usbhost/Kconfig +++ b/nuttx/drivers/usbhost/Kconfig @@ -120,11 +120,16 @@ config USBHOST_HIDMOUSE default n depends on !INT_DISABLE select INPUT + select MOUSE ---help--- Enable support for the mouse class driver. This also depends on SCHED_WORKQUEUE && !DISABLE_SIGNALS -if USBHOST_HIDMOUSE + NOTE: This driver checks out on a Labtec and an AOpen mouse, but + does not work correctly on a Microsoft mouse. A little more work + would be needed to support the Microsoft mouse. + +if USBHOST_HIDMOUSE config HIDMOUSE_TSCIF bool "Touchscreen Emulation" @@ -226,7 +231,7 @@ config HIDMOUSE_XTHRESH default 12 ---help--- New mouse positions will only be reported when the X or Y data changes by these - thresholds. This trades reduces data rate for some loss in dragging accuracy. + thresholds. This tradeoff reduces data rate for some loss in dragging accuracy. Both X and Y axis thresholding can be disabled by setting this value to zero. Default: 12 @@ -236,12 +241,48 @@ config HIDMOUSE_THRESHY default 12 ---help--- New touch positions will only be reported when the X or Y data changes by these - thresholds. This trades reduces data rate for some loss in dragging accuracy. + thresholds. This tradeoff reduces data rate for some loss in dragging accuracy. Both X and Y axis thresholding can be disabled by setting this value to zero. Default: 12 -endif +if MOUSE_WHEEL + +config HIDMOUSE_WMAX + int "Maximum wheel position" + default 320 + range 0 32767 + ---help--- + This is the maximum value of the wheel position that will be + reported. Default: 320 + +config HIDMOUSE_WSCALE + hex "Wheel scaling factor" + default 0x00010000 + ---help--- + Mouse wheel position are accumulated from wheel displacements + reported by the mouse device. This setting provides a scaling + value for the wheel displacement. This is a fixed precision + floating point number with 16 bits of fraction. So a value of + 0x00010000 is 1.0, 0x00018000 is 1.5, 0x00024000 is 2.25, etc. + + NOTE that a negative value of HIDMOUSE_XSCALE such as 0xffff0000 + (-1.0) can be used to change the direction of wheel output. + + Default: 0x00010000 (1.0) + +config HIDMOUSE_WTHRESH + int "Wheel threshold" + default 1 + ---help--- + New wheel positions will only be reported when the wheel position + changes by these thresholds. This tradeoff reduces data rate for some + loss in wheel responsiveness. + + Default: 1 + +endif # MOUSE_WHEEL +endif # USBHOST_HIDMOUSE config USBHOST_TRACE bool "Enable USB HCD tracing for debug" diff --git a/nuttx/drivers/usbhost/usbhost_hidmouse.c b/nuttx/drivers/usbhost/usbhost_hidmouse.c index 2ceccccac..cbd11f92d 100644 --- a/nuttx/drivers/usbhost/usbhost_hidmouse.c +++ b/nuttx/drivers/usbhost/usbhost_hidmouse.c @@ -127,6 +127,30 @@ #define HIDMOUSE_YTHRESH_B16 (CONFIG_HIDMOUSE_YTHRESH << 16) +#ifdef CONFIG_HIDMOUSE_TSCIF +# undef CONFIG_MOUSE_WHEEL +#endif + +#ifdef CONFIG_MOUSE_WHEEL + +# ifndef CONFIG_HIDMOUSE_WMAX +# define CONFIG_HIDMOUSE_WMAX 100 +# endif + +# define HIDMOUSE_WMAX_B16 (CONFIG_HIDMOUSE_WMAX << 16) + +# ifndef CONFIG_HIDMOUSE_WSCALE +# define CONFIG_HIDMOUSE_WSCALE 0x00010000 +# endif + +# ifndef CONFIG_HIDMOUSE_WTHRESH +# define CONFIG_HIDMOUSE_WTHRESH 1 +# endif + +# define HIDMOUSE_WTHRESH_B16 (CONFIG_HIDMOUSE_WTHRESH << 16) + +#endif /* CONFIG_MOUSE_WHEEL */ + #ifndef CONFIG_HIDMOUSE_DEFPRIO # define CONFIG_HIDMOUSE_DEFPRIO 50 #endif @@ -217,8 +241,11 @@ struct mouse_sample_s struct mouse_sample_s { uint8_t buttons; /* Button state (see MOUSE_BUTTON_* definitions) */ - uint16_t x; /* Measured X position */ - uint16_t y; /* Measured Y position */ + uint16_t x; /* Accumulated X position */ + uint16_t y; /* Accumulated Y position */ +#ifdef CONFIG_MOUSE_WHEEL + uint16_t wheel; /* Reported wheel position */ +#endif }; #endif @@ -257,6 +284,10 @@ struct usbhost_state_s b16_t yaccum; /* Current integrated Y position */ b16_t xlast; /* Last reported X position */ b16_t ylast; /* Last reported Y position */ +#ifdef CONFIG_MOUSE_WHEEL + b16_t waccum; /* Current integrated while position */ + b16_t wlast; /* Last reported wheel position */ +#endif size_t tbuflen; /* Size of the allocated transfer buffer */ pid_t pollpid; /* PID of the poll task */ struct work_s work; /* For cornercase error handling by the worker thread */ @@ -299,7 +330,8 @@ static inline void usbhost_freeclass(FAR struct usbhost_state_s *class); static int usbhost_allocdevno(FAR struct usbhost_state_s *priv); static void usbhost_freedevno(FAR struct usbhost_state_s *priv); -static inline void usbhost_mkdevname(FAR struct usbhost_state_s *priv, char *devname); +static inline void usbhost_mkdevname(FAR struct usbhost_state_s *priv, + FAR char *devname); /* Mouse polling thread */ @@ -311,8 +343,7 @@ static void usbhost_position(FAR struct usbhost_state_s *priv, static bool usbhost_touchscreen(FAR struct usbhost_state_s *priv, FAR struct usbhid_mousereport_s *rpt); #endif -static bool usbhost_threshold(FAR struct usbhost_state_s *priv, - b16_t xpos, b16_t ypos); +static bool usbhost_threshold(FAR struct usbhost_state_s *priv); static int usbhost_mouse_poll(int argc, char *argv[]); static int usbhost_sample(FAR struct usbhost_state_s *priv, FAR struct mouse_sample_s *sample); @@ -322,8 +353,8 @@ static int usbhost_waitsample(FAR struct usbhost_state_s *priv, /* Helpers for usbhost_connect() */ static inline int usbhost_cfgdesc(FAR struct usbhost_state_s *priv, - FAR const uint8_t *configdesc, int desclen, - uint8_t funcaddr); + FAR const uint8_t *configdesc, + int desclen, uint8_t funcaddr); static inline int usbhost_devinit(FAR struct usbhost_state_s *priv); /* (Little Endian) Data helpers */ @@ -563,7 +594,8 @@ static void usbhost_freedevno(FAR struct usbhost_state_s *priv) } } -static inline void usbhost_mkdevname(FAR struct usbhost_state_s *priv, char *devname) +static inline void usbhost_mkdevname(FAR struct usbhost_state_s *priv, + FAR char *devname) { (void)snprintf(devname, DEV_NAMELEN, DEV_FORMAT, priv->devno); } @@ -699,10 +731,8 @@ static void usbhost_notify(FAR struct usbhost_state_s *priv) static void usbhost_position(FAR struct usbhost_state_s *priv, FAR struct usbhid_mousereport_s *rpt) { - int32_t xdisp; - int32_t ydisp; - b16_t xpos; - b16_t ypos; + int32_t disp; + b16_t pos; /* The following logic performs an constant integration of the mouse X/Y * displacement data in order to keep the X/Y positional data current. @@ -714,68 +744,91 @@ static void usbhost_position(FAR struct usbhost_state_s *priv, */ #ifdef CONFIG_HIDMOUSE_SWAPXY - xdisp = rpt->ydisp; + disp = rpt->ydisp; if ((rpt->ydisp & 0x80) != 0) { - xdisp |= 0xffffff00; + disp |= 0xffffff00; } #else - xdisp = rpt->xdisp; + disp = rpt->xdisp; if ((rpt->xdisp & 0x80) != 0) { - xdisp |= 0xffffff00; + disp |= 0xffffff00; } #endif /* Scale the X displacement and determine the new X position */ - xpos = priv->xaccum + CONFIG_HIDMOUSE_XSCALE * xdisp; + pos = priv->xaccum + CONFIG_HIDMOUSE_XSCALE * disp; /* Make sure that the scaled X position does not become negative or exceed * the maximum. */ - if (xpos > HIDMOUSE_XMAX_B16) + if (pos > HIDMOUSE_XMAX_B16) { - xpos = HIDMOUSE_XMAX_B16; + pos = HIDMOUSE_XMAX_B16; } - else if (xpos < 0) + else if (pos < 0) { - xpos = 0; + pos = 0; } /* Save the updated X position */ - priv->xaccum = xpos; + priv->xaccum = pos; /* Do the same for the Y position */ #ifdef CONFIG_HIDMOUSE_SWAPXY - ydisp = rpt->xdisp; + disp = rpt->xdisp; if ((rpt->xdisp & 0x80) != 0) { - ydisp |= 0xffffff00; + disp |= 0xffffff00; } #else - ydisp = rpt->ydisp; + disp = rpt->ydisp; if ((rpt->ydisp & 0x80) != 0) { - ydisp |= 0xffffff00; + disp |= 0xffffff00; } #endif - ypos = priv->yaccum + CONFIG_HIDMOUSE_YSCALE * ydisp; + pos = priv->yaccum + CONFIG_HIDMOUSE_YSCALE * disp; - if (ypos > HIDMOUSE_YMAX_B16) + if (pos > HIDMOUSE_YMAX_B16) { - ypos = HIDMOUSE_YMAX_B16; + pos = HIDMOUSE_YMAX_B16; } - else if (ypos < 0) + else if (pos < 0) + { + pos = 0; + } + + priv->yaccum = pos; + +#ifdef CONFIG_MOUSE_WHEEL + /* Do the same for the wheel position */ + + disp = rpt->wdisp; + if ((rpt->wdisp & 0x80) != 0) { - ypos = 0; + disp |= 0xffffff00; } - priv->yaccum = ypos; + pos = priv->waccum + CONFIG_HIDMOUSE_WSCALE * disp; + + if (pos > HIDMOUSE_WMAX_B16) + { + pos = HIDMOUSE_WMAX_B16; + } + else if (pos < 0) + { + pos = 0; + } + + priv->waccum = pos; +#endif } /**************************************************************************** @@ -862,7 +915,7 @@ static bool usbhost_touchscreen(FAR struct usbhost_state_s *priv, * small, then ignore the event. */ - else if (!usbhost_threshold(priv, priv->xaccum, priv->yaccum)) + else if (!usbhost_xythreshold(priv)) { return false; } @@ -889,8 +942,6 @@ static bool usbhost_touchscreen(FAR struct usbhost_state_s *priv, * * Input Parameters: * priv - A reference to the mouse state structure. - * xpos - The current mouse X position - * ypos - The current mouse Y position * * Returned Value: * True if the mouse position is significantly different from the last @@ -898,47 +949,69 @@ static bool usbhost_touchscreen(FAR struct usbhost_state_s *priv, * ****************************************************************************/ -static bool usbhost_threshold(FAR struct usbhost_state_s *priv, - b16_t xpos, b16_t ypos) +static bool usbhost_threshold(FAR struct usbhost_state_s *priv) { #if CONFIG_HIDMOUSE_XTHRESH > 0 && CONFIG_HIDMOUSE_YTHRESH > 0 - b16_t xdiff; - b16_t ydiff; + b16_t pos; + b16_t diff; /* Get the difference in the X position from the last report */ - if (xpos > priv->xlast) + pos = priv->xaccum; + if (pos > priv->xlast) { - xdiff = xpos - priv->xlast; + diff = pos - priv->xlast; } else { - xdiff = priv->xlast - xpos; + diff = priv->xlast - pos; } /* Check if the X difference exceeds the report threshold */ - if (xdiff >= HIDMOUSE_XTHRESH_B16) + if (diff >= HIDMOUSE_XTHRESH_B16) { return true; } /* Little or no change in the X direction, check the Y direction. */ - if (ypos > priv->ylast) + pos = priv->yaccum; + if (pos > priv->ylast) { - ydiff = ypos - priv->ylast; + diff = pos - priv->ylast; } else { - ydiff = priv->ylast - ypos; + diff = priv->ylast - pos; } - if (ydiff >= HIDMOUSE_YTHRESH_B16) + if (diff >= HIDMOUSE_YTHRESH_B16) { return true; } +#ifdef CONFIG_MOUSE_WHEEL + /* Get the difference in the wheel position from the last report */ + + pos = priv->waccum; + if (pos > priv->wlast) + { + diff = pos - priv->wlast; + } + else + { + diff = priv->wlast - pos; + } + + /* Check if the X difference exceeds the report threshold */ + + if (diff >= HIDMOUSE_WTHRESH_B16) + { + return true; + } +#endif + /* Little or no change in either direction... don't report anything. */ return false; @@ -1057,8 +1130,7 @@ static int usbhost_mouse_poll(int argc, char *argv[]) */ buttons = rpt->buttons & USBHID_MOUSEIN_BUTTON_MASK; - if (buttons != priv->buttons || - usbhost_threshold(priv, priv->xaccum, priv->yaccum)) + if (buttons != priv->buttons || usbhost_threshold(priv)) #endif { /* We get here when either there is a meaning button change @@ -1070,11 +1142,16 @@ static int usbhost_mouse_poll(int argc, char *argv[]) priv->xlast = priv->xaccum; priv->ylast = priv->yaccum; - +#ifdef CONFIG_MOUSE_WHEEL + priv->wlast = priv->waccum; +#endif /* Update the sample X/Y positions */ priv->sample.x = b16toi(priv->xaccum); priv->sample.y = b16toi(priv->yaccum); +#ifdef CONFIG_MOUSE_WHEEL + priv->sample.wheel = b16toi(priv->waccum); +#endif #ifdef CONFIG_HIDMOUSE_TSCIF /* The X/Y positional data is now valid */ @@ -2046,7 +2123,9 @@ static int usbhost_open(FAR struct file *filep) priv->xlast = INVALID_POSITION_B16; priv->ylast = INVALID_POSITION_B16; - +#ifdef CONFIG_MOUSE_WHEEL + priv->wlast = INVALID_POSITION_B16; +#endif /* Set the reported position to the center of the range */ priv->xaccum = (HIDMOUSE_XMAX_B16 >> 1); @@ -2261,6 +2340,9 @@ static ssize_t usbhost_read(FAR struct file *filep, FAR char *buffer, size_t len report->buttons = sample.buttons; report->x = sample.x; report->y = sample.y; +#ifdef CONFIG_MOUSE_WHEEL + report->wheel = sample.wheel; +#endif ret = sizeof(struct mouse_report_s); #endif diff --git a/nuttx/include/nuttx/input/mouse.h b/nuttx/include/nuttx/input/mouse.h index f0907175b..da92e8fc7 100644 --- a/nuttx/include/nuttx/input/mouse.h +++ b/nuttx/include/nuttx/input/mouse.h @@ -59,8 +59,8 @@ */ #define MOUSE_BUTTON_1 (1 << 0) /* True: Left mouse button pressed */ -#define MOUSE_BUTTON_2 (1 << 1) /* True: Middle mouse button pressed */ -#define MOUSE_BUTTON_3 (1 << 2) /* True: Right mouse button pressed */ +#define MOUSE_BUTTON_2 (1 << 1) /* True: Right mouse button pressed */ +#define MOUSE_BUTTON_3 (1 << 2) /* True: Middle mouse button pressed */ /************************************************************************************ * Public Types @@ -76,6 +76,9 @@ struct mouse_report_s uint8_t buttons; /* See TOUCH_* definitions above */ int16_t x; /* X coordinate of the mouse position */ int16_t y; /* Y coordinate of the mouse position */ +#ifdef CONFIG_MOUSE_WHEEL + int16_t wheel; /* Mouse wheel position */ +#endif }; /************************************************************************************ diff --git a/nuttx/include/nuttx/usb/hid.h b/nuttx/include/nuttx/usb/hid.h index 99229da63..c2c635c8d 100644 --- a/nuttx/include/nuttx/usb/hid.h +++ b/nuttx/include/nuttx/usb/hid.h @@ -662,6 +662,9 @@ struct usbhid_mousereport_s uint8_t xdisp; /* X displacement */ uint8_t ydisp; /* y displacement */ /* Device specific additional bytes may follow */ +#ifdef CONFIG_MOUSE_WHEEL + uint8_t wdisp; /* Wheel displacement */ +#endif }; /* Joystick input report (1 bytes) (HID D.1) */ |