diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2012-12-26 21:37:50 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2012-12-26 21:37:50 +0000 |
commit | 24f3d5c021bfa7d0a99870d363d86e4e17e4ca63 (patch) | |
tree | 65f8b3f30035b51fd347b856ca80d55eead7d277 | |
parent | c034173c00669e4f09c5156a0057446cfef927e5 (diff) | |
download | px4-nuttx-24f3d5c021bfa7d0a99870d363d86e4e17e4ca63.tar.gz px4-nuttx-24f3d5c021bfa7d0a99870d363d86e4e17e4ca63.tar.bz2 px4-nuttx-24f3d5c021bfa7d0a99870d363d86e4e17e4ca63.zip |
Verified USB HID KBD driver encoding of special characters; apps/examples/hidkbd now decodes encoded keyboar characters.
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5463 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r-- | apps/ChangeLog.txt | 2 | ||||
-rw-r--r-- | apps/examples/README.txt | 18 | ||||
-rw-r--r-- | apps/examples/hidkbd/Kconfig | 31 | ||||
-rw-r--r-- | apps/examples/hidkbd/hidkbd_main.c | 106 | ||||
-rwxr-xr-x | nuttx/configs/olimex-lpc1766stk/hidkbd/defconfig | 20 | ||||
-rw-r--r-- | nuttx/drivers/usbhost/Kconfig | 4 | ||||
-rw-r--r-- | nuttx/drivers/usbhost/usbhost_hidkbd.c | 34 | ||||
-rw-r--r-- | nuttx/include/nuttx/input/kbd_codec.h | 5 | ||||
-rw-r--r-- | nuttx/libc/Kconfig | 28 | ||||
-rw-r--r-- | nuttx/libc/math/Kconfig | 2 | ||||
-rw-r--r-- | nuttx/libc/misc/Make.defs | 8 |
11 files changed, 234 insertions, 24 deletions
diff --git a/apps/ChangeLog.txt b/apps/ChangeLog.txt index ea1b247f5..d156b1065 100644 --- a/apps/ChangeLog.txt +++ b/apps/ChangeLog.txt @@ -453,4 +453,6 @@ in place early in the dependency generation phase to avoid warnings. It is not important if they are only stubbed out header files at this build phase. + * apps/examples/hidbkd: Now supports decoding of encoded special keys + if CONFIG_EXAMPLES_HIDKBD_ENCODED is defined. diff --git a/apps/examples/README.txt b/apps/examples/README.txt index e40a63be9..7bfba721a 100644 --- a/apps/examples/README.txt +++ b/apps/examples/README.txt @@ -540,9 +540,21 @@ examples/hidkbd This is a simple test to debug/verify the USB host HID keyboard class driver. - CONFIG_EXAMPLES_HIDKBD_DEFPRIO - Priority of "waiter" thread. - CONFIG_EXAMPLES_HIDKBD_STACKSIZE - Stacksize of "waiter" thread. - + CONFIG_EXAMPLES_HIDKBD_DEFPRIO - Priority of "waiter" thread. Default: + 50 + CONFIG_EXAMPLES_HIDKBD_STACKSIZE - Stacksize of "waiter" thread. Default + 1024 + CONFIG_EXAMPLES_HIDKBD_DEVNAME - Name of keyboard device to be used. + Default: "/dev/kbda" + CONFIG_EXAMPLES_HIDKBD_ENCODED - Decode special key press events in the + user buffer. In this case, the example coded will use the interfaces + defined in include/nuttx/input/kbd_codec.h to decode the returned + keyboard data. These special keys include such things as up/down + arrows, home and end keys, etc. If this not defined, only 7-bit print- + able and control ASCII characters will be provided to the user. + Requires CONFIG_HIDKBD_ENCODED && CONFIG_LIB_KBDCODEC + +endif examples/igmp ^^^^^^^^^^^^^ diff --git a/apps/examples/hidkbd/Kconfig b/apps/examples/hidkbd/Kconfig index 503d9d9d9..81f817ef9 100644 --- a/apps/examples/hidkbd/Kconfig +++ b/apps/examples/hidkbd/Kconfig @@ -10,4 +10,35 @@ config EXAMPLES_HIDKBD Enable the USB HID keyboard example if EXAMPLES_HIDKBD + +config EXAMPLES_HIDKBD_DEFPRIO + int "Waiter Thread Priority" + default 50 + ---help--- + Priority of "waiter" thread. Default: 50 + +config EXAMPLES_HIDKBD_STACKSIZE + int "Waiter Thread Stack Size" + default 1024 + ---help--- + Stacksize of "waiter" thread. Default 1024 + +config EXAMPLES_HIDKBD_DEVNAME + string "Keyboard Device Name" + default "/dev/kbda" + ---help--- + Name of keyboard device to be used. Default: "/dev/kbda" + +config EXAMPLES_HIDKBD_ENCODED + bool "Encode Special Keys" + default y + depends on HIDKBD_ENCODED && LIB_KBDCODEC + ---help--- + Decode special key press events in the user buffer. In this case, + the example coded will use the interfaces defined in + include/nuttx/input/kbd_codec.h to decode the returned keyboard + data. These special keys include such things as up/down arrows, + home and end keys, etc. If this not defined, only 7-bit print-able + and control ASCII characters will be provided to the user. + endif diff --git a/apps/examples/hidkbd/hidkbd_main.c b/apps/examples/hidkbd/hidkbd_main.c index 8c9f6fa95..8a632bab7 100644 --- a/apps/examples/hidkbd/hidkbd_main.c +++ b/apps/examples/hidkbd/hidkbd_main.c @@ -46,10 +46,18 @@ #include <unistd.h> #include <fcntl.h> #include <sched.h> +#include <string.h> +#include <ctype.h> +#include <assert.h> #include <errno.h> #include <nuttx/usb/usbhost.h> +#ifdef CONFIG_EXAMPLES_HIDKBD_ENCODED +# include <nuttx/streams.h> +# include <nuttx/input/kbd_codec.h> +#endif + /**************************************************************************** * Definitions ****************************************************************************/ @@ -83,10 +91,23 @@ # define CONFIG_EXAMPLES_HIDKBD_DEVNAME "/dev/kbda" #endif +#if !defined(CONFIG_HIDKBD_ENCODED) || !defined(CONFIG_LIB_KBDCODEC) +# undef CONFIG_EXAMPLES_HIDKBD_ENCODED +#endif + /**************************************************************************** * Private Types ****************************************************************************/ +#ifdef CONFIG_EXAMPLES_HIDKBD_ENCODED +struct hidbkd_instream_s +{ + struct lib_instream_s stream; + FAR char *buffer; + ssize_t nbytes; +}; +#endif + /**************************************************************************** * Private Data ****************************************************************************/ @@ -98,9 +119,84 @@ static struct usbhost_driver_s *g_drvr; ****************************************************************************/ /**************************************************************************** - * Public Functions + * Name: hidkbd_getstream + * + * Description: + * Get one character from the keyboard. + * ****************************************************************************/ +#ifdef CONFIG_EXAMPLES_HIDKBD_ENCODED +static int hidkbd_getstream(FAR struct lib_instream_s *this) +{ + FAR struct hidbkd_instream_s *kbdstream = (FAR struct hidbkd_instream_s *)this; + + DEBUGASSERT(kbdstream && kbdstream->buffer); + if (kbdstream->nbytes > 0) + { + kbdstream->nbytes--; + kbdstream->stream.nget++; + return (int)*kbdstream->buffer++; + } + + return EOF; +} +#endif + +/**************************************************************************** + * Name: hidkbd_decode + * + * Description: + * Decode encoded keyboard input + * + ****************************************************************************/ + +#ifdef CONFIG_EXAMPLES_HIDKBD_ENCODED +static void hidkbd_decode(FAR char *buffer, ssize_t nbytes) +{ + struct hidbkd_instream_s kbdstream; + struct kbd_getstate_s state; + uint8_t ch; + int ret; + + /* Initialize */ + + memset(&state, 0, sizeof(struct kbd_getstate_s)); + kbdstream.stream.get = hidkbd_getstream; + kbdstream.stream.nget = 0; + kbdstream.buffer = buffer; + kbdstream.nbytes = nbytes; + + /* Loop until all of the bytes have been consumed. We implicitly assume + * that the the escaped sequences do not cross buffer boundaries. That + * might be true if the read buffer were small or the data rates high. + */ + + for (;;) + { + /* Decode the next thing from the buffer */ + + ret = kbd_get((FAR struct lib_instream_s *)&kbdstream, &state, &ch); + if (ret == KBD_ERROR) + { + break; + } + + /* Normal data? Or special key? */ + + if (ret == KBD_NORMAL) + { + printf("Data: %c [%02x]\n", isprint(ch) ? ch : '.', ch); + } + else + { + DEBUGASSERT(ret == KBD_SPECIAL); + printf("Special: %d\n", ch); + } + } +} +#endif + /**************************************************************************** * Name: hidkbd_waiter * @@ -141,6 +237,10 @@ static int hidkbd_waiter(int argc, char *argv[]) } /**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** * Name: hidkbd_main ****************************************************************************/ @@ -217,7 +317,11 @@ int hidkbd_main(int argc, char *argv[]) { /* On success, echo the buffer to stdout */ +#ifdef CONFIG_EXAMPLES_HIDKBD_ENCODED + hidkbd_decode(buffer, nbytes); +#else (void)write(1, buffer, nbytes); +#endif } } while (nbytes > 0); diff --git a/nuttx/configs/olimex-lpc1766stk/hidkbd/defconfig b/nuttx/configs/olimex-lpc1766stk/hidkbd/defconfig index 78e411560..35a7bfc3d 100755 --- a/nuttx/configs/olimex-lpc1766stk/hidkbd/defconfig +++ b/nuttx/configs/olimex-lpc1766stk/hidkbd/defconfig @@ -316,7 +316,10 @@ CONFIG_DEV_NULL=y # CONFIG_WATCHDOG is not set # CONFIG_ANALOG is not set # CONFIG_BCH is not set -# CONFIG_INPUT is not set +CONFIG_INPUT=y +# CONFIG_INPUT_TSC2007 is not set +# CONFIG_INPUT_ADS7843E is not set +# CONFIG_INPUT_STMPE811 is not set # CONFIG_LCD is not set CONFIG_MMCSD=y CONFIG_MMCSD_NSLOTS=1 @@ -364,7 +367,7 @@ CONFIG_HIDKBD_STACKSIZE=1024 CONFIG_HIDKBD_BUFSIZE=64 CONFIG_HIDKBD_NPOLLWAITERS=2 # CONFIG_HIDKBD_RAWSCANCODES is not set -# CONFIG_HIDKBD_ENCODED is not set +CONFIG_HIDKBD_ENCODED=y # CONFIG_HIDKBD_ALLSCANCODES is not set # CONFIG_HIDKBD_NODEBOUNCE is not set # CONFIG_WIRELESS is not set @@ -425,6 +428,10 @@ CONFIG_MM_REGIONS=2 # # Library Routines # + +# +# Standard C Library Options +# CONFIG_STDIO_BUFFER_SIZE=256 CONFIG_STDIO_LINEBUFFER=y CONFIG_NUNGET_CHARS=2 @@ -444,6 +451,11 @@ CONFIG_LIB_SENDFILE_BUFSIZE=512 # CONFIG_ARCH_OPTIMIZED_FUNCTIONS is not set # +# Non-standard Helper Functions +# +CONFIG_LIB_KBDCODEC=y + +# # Basic CXX Support # # CONFIG_C99_BOOL8 is not set @@ -473,6 +485,10 @@ CONFIG_LIB_SENDFILE_BUFSIZE=512 # CONFIG_EXAMPLES_HELLOXX is not set # CONFIG_EXAMPLES_JSON is not set CONFIG_EXAMPLES_HIDKBD=y +CONFIG_EXAMPLES_HIDKBD_DEFPRIO=50 +CONFIG_EXAMPLES_HIDKBD_STACKSIZE=1024 +CONFIG_EXAMPLES_HIDKBD_DEVNAME="/dev/kbda" +CONFIG_EXAMPLES_HIDKBD_ENCODED=y # CONFIG_EXAMPLES_KEYPADTEST is not set # CONFIG_EXAMPLES_IGMP is not set # CONFIG_EXAMPLES_LCDRW is not set diff --git a/nuttx/drivers/usbhost/Kconfig b/nuttx/drivers/usbhost/Kconfig index de8469b41..531e94442 100644 --- a/nuttx/drivers/usbhost/Kconfig +++ b/nuttx/drivers/usbhost/Kconfig @@ -89,10 +89,10 @@ config HIDKBD_RAWSCANCODES config HIDKBD_ENCODED bool "Enocode Special Keys" default n - depends on !HIDKBD_RAWSCANCODES + depends on !HIDKBD_RAWSCANCODES && LIB_KBDCODEC ---help--- Encode special key press events in the user buffer. In this case, - the use end must decode the encoded special key values using the + the user end must decode the encoded special key values using the interfaces defined in include/nuttx/input/kbd_codec.h. These special keys include such things as up/down arrows, home and end keys, etc. If this not defined, only 7-bit print-able and control diff --git a/nuttx/drivers/usbhost/usbhost_hidkbd.c b/nuttx/drivers/usbhost/usbhost_hidkbd.c index 5022793ca..917ebfa3f 100644 --- a/nuttx/drivers/usbhost/usbhost_hidkbd.c +++ b/nuttx/drivers/usbhost/usbhost_hidkbd.c @@ -131,6 +131,14 @@ # endif #endif +/* We cant support encoding of special characters of unless the Keyboard + * CODEC is enabled. + */ + +#ifndef CONFIG_LIB_KBDCODEC +# undef CONFIG_HIDKBD_ENCODED +#endif + /* If we are using raw scancodes, then we cannot support encoding of * special characters either. */ @@ -398,11 +406,11 @@ static struct usbhost_state_s *g_priv; /* Data passed to thread */ /* The first and last scancode values with encode-able values */ -#define FIRST_ENCODING USBHID_KBDUSE_ENTER /* 0x28 Keyboard Return (ENTER) */ -#ifdef CONFIG_HIDKBD_ALLSCANCODES -# define LAST_ENCODING USBHID_KBDUSE_POWER /* 0x66 Keyboard Power */ +#define FIRST_ENCODING USBHID_KBDUSE_ENTER /* 0x28 Keyboard Return (ENTER) */ +#ifndef CONFIG_HIDKBD_ALLSCANCODES +# define LAST_ENCODING USBHID_KBDUSE_POWER /* 0x66 Keyboard Power */ #else -#define LAST_ENCODING USBHID_KBDUSE_KPDHEXADECIMAL /* 0xdd Keypad Hexadecimal */ +# define LAST_ENCODING USBHID_KBDUSE_KPDHEXADECIMAL /* 0xdd Keypad Hexadecimal */ #endif #define USBHID_NUMENCODINGS (LAST_ENCODING - FIRST_ENCODING + 1) @@ -874,10 +882,10 @@ static void usbhost_putbuffer(FAR struct usbhost_state_s *priv, #ifdef CONFIG_HIDKBD_ENCODED static void usbhost_putstream(FAR struct lib_outstream_s *stream, int ch) { - FAR struct usbhost_outstream_s *privstream = (FAR struct lib_outstream_s *)stream; + FAR struct usbhost_outstream_s *privstream = (FAR struct usbhost_outstream_s *)stream; DEBUGASSERT(privstream && privstream->priv); - usbhost_putbuffer(privstream->priv), (uint8_t)ch); + usbhost_putbuffer(privstream->priv, (uint8_t)ch); stream->nput++; } #endif @@ -945,7 +953,6 @@ static inline uint8_t usbhost_mapscancode(uint8_t scancode, uint8_t modifier) static inline void usbhost_encodescancode(FAR struct usbhost_state_s *priv, uint8_t scancode, uint8_t modifier) { - struct usbhost_outstream_s stream; uint8_t encoded; /* Check if the raw scancode is in a valid range */ @@ -954,7 +961,7 @@ static inline void usbhost_encodescancode(FAR struct usbhost_state_s *priv, { /* Yes the value is within range */ - encoded = encoding(scancode - FIRST_ENCODING); + encoded = encoding[scancode - FIRST_ENCODING]; ivdbg(" scancode: %02x modifier: %02x encoded: %d\n", scancode, modifier, encoded); @@ -964,13 +971,14 @@ static inline void usbhost_encodescancode(FAR struct usbhost_state_s *priv, /* And it does correspond to a special function key */ - usbstream->stream.put = usbhost_putstream; - usbstream->stream.nput = 0; - usbstream->priv = priv; + usbstream.stream.put = usbhost_putstream; + usbstream.stream.nput = 0; + usbstream.priv = priv; /* Add the special function value to the user buffer */ - kbd_putspecial((enum kbd_keycode_e)encoded, &usbstream); + kbd_putspecial((enum kbd_keycode_e)encoded, + (FAR struct lib_outstream_s *)&usbstream); } } } @@ -1156,7 +1164,7 @@ static int usbhost_kbdpoll(int argc, char *argv[]) #ifdef CONFIG_HIDKBD_ENCODED else { - usbhost_encodescancode(priv, rpt->key[i], rpt->modifier)); + usbhost_encodescancode(priv, rpt->key[i], rpt->modifier); } #endif } diff --git a/nuttx/include/nuttx/input/kbd_codec.h b/nuttx/include/nuttx/input/kbd_codec.h index d374ed8d3..0a3a54d2d 100644 --- a/nuttx/include/nuttx/input/kbd_codec.h +++ b/nuttx/include/nuttx/input/kbd_codec.h @@ -44,6 +44,8 @@ #include <nuttx/config.h> #include <nuttx/streams.h> +#ifdef CONFIG_LIB_KBDCODEC + /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ @@ -87,7 +89,7 @@ enum kbd_keycode_e KEYCODE_CUT, /* Cut */ KEYCODE_COPY, /* Copy */ KEYCODE_PASTE, /* Paste */ - KEYCODE_FIND , /* Find */ + KEYCODE_FIND, /* Find */ /* Selection codes */ @@ -294,5 +296,6 @@ int kbd_get(FAR struct lib_instream_s *stream, } #endif +#endif /* CONFIG_LIB_KBDCODEC */ #endif /* __INCLUDE_NUTTX_INPUT_KBD_CODEC_H */ diff --git a/nuttx/libc/Kconfig b/nuttx/libc/Kconfig index bd470be7f..a5ff7fd43 100644 --- a/nuttx/libc/Kconfig +++ b/nuttx/libc/Kconfig @@ -3,6 +3,8 @@ # see misc/tools/kconfig-language.txt. # +comment "Standard C Library Options" + config STDIO_BUFFER_SIZE int "C STDIO buffer size" default 64 @@ -273,3 +275,29 @@ config ARCH_BZERO of bzero(). endif + +comment "Non-standard Helper Functions" + +config LIB_KBDCODEC + bool "Keyboard CODEC" + default y + ---help--- + In NuttX, a keyboard/keypad driver is simply a character driver that + may have an (optional) encoding/decoding layer on the data returned + by the character driver. A keyboard may return simple text data + (alphabetic, numeric, and punctuaction) or control characters + (enter, control-C, etc.). We can think about this the normal + "in-band" keyboard data stream. However, in addition, most + keyboards support actions that cannot be represented as text data. + Such actions include things like cursor controls (home, up arrow, + page down, etc.), editing functions (insert, delete, etc.), volume + controls, (mute, volume up, etc.) and other special functions. We + can think about this as special, "out-of-band" keyboard commands. + In this case, some special encoding may be required to multiplex + the in-band text data and out-of-band command streams. + + This option enables the functions that implement the encoding and + decoding of keyboard data. These are the interfaces prototyped in + include/nuttx/input/kbd_codec.h. While not correctly a part of + the C library, it is included here because the decoding side of this + interface must be accessible by end user programs. diff --git a/nuttx/libc/math/Kconfig b/nuttx/libc/math/Kconfig index c24bfd53f..db9dfae63 100644 --- a/nuttx/libc/math/Kconfig +++ b/nuttx/libc/math/Kconfig @@ -4,7 +4,7 @@ # config LIBM - bool "Math library" + bool "Standard Math library" default n depends on !ARCH_MATH_H ---help--- diff --git a/nuttx/libc/misc/Make.defs b/nuttx/libc/misc/Make.defs index c6af5f860..ad0313346 100644 --- a/nuttx/libc/misc/Make.defs +++ b/nuttx/libc/misc/Make.defs @@ -35,7 +35,7 @@ # Add the internal C files to the build -CSRCS += lib_init.c lib_filesem.c lib_kbdencode.c lib_kbddecode.c +CSRCS += lib_init.c lib_filesem.c # Add C files that depend on file OR socket descriptors @@ -63,6 +63,12 @@ CSRCS += lib_match.c CSRCS += lib_crc32.c CSRCS += lib_dbg.c lib_dumpbuffer.c +# Keyboard driver encoder/decoder + +ifneq ($(CONFIG_LIB_KBDCODEC),0) +CSRCS += lib_kbdencode.c lib_kbddecode.c +endif + # Add the misc directory to the build DEPPATH += --dep-path misc |