summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2014-02-10 11:53:37 -0600
committerGregory Nutt <gnutt@nuttx.org>2014-02-10 11:53:37 -0600
commitda2b06fc9b4934db950f8218bb0c17829cd381a9 (patch)
tree3200388b06c9c4e75b47b0bdce2cd7538fbed1e4
parent105f5fbfcbbf411deefddac8039ccb3b03477609 (diff)
downloadnuttx-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.txt2
-rw-r--r--apps/examples/touchscreen/tc_main.c3
-rw-r--r--nuttx/ChangeLog2
-rw-r--r--nuttx/configs/olimex-lpc1766stk/hidmouse/defconfig2
-rw-r--r--nuttx/drivers/input/Kconfig17
-rw-r--r--nuttx/drivers/usbhost/Kconfig49
-rw-r--r--nuttx/drivers/usbhost/usbhost_hidmouse.c184
-rw-r--r--nuttx/include/nuttx/input/mouse.h7
-rw-r--r--nuttx/include/nuttx/usb/hid.h3
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) */