Verified USB HID KBD driver encoding of special characters; apps/examples/hidkbd now decodes encoded keyboar characters.

git-svn-id: http://svn.code.sf.net/p/nuttx/code/trunk@5463 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2012-12-26 21:37:50 +00:00
parent 8ed19bb07d
commit 88bccb641e
11 changed files with 233 additions and 23 deletions

View File

@ -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.

View File

@ -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
^^^^^^^^^^^^^

View File

@ -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

View File

@ -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
*
@ -140,6 +236,10 @@ static int hidkbd_waiter(int argc, char *argv[])
return 0;
}
/****************************************************************************
* 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);

View File

@ -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
@ -443,6 +450,11 @@ CONFIG_LIB_SENDFILE_BUFSIZE=512
# CONFIG_ARCH_ROMGETC is not set
# CONFIG_ARCH_OPTIMIZED_FUNCTIONS is not set
#
# Non-standard Helper Functions
#
CONFIG_LIB_KBDCODEC=y
#
# Basic CXX Support
#
@ -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

View File

@ -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

View File

@ -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
}

View File

@ -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 */

View File

@ -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.

View File

@ -4,7 +4,7 @@
#
config LIBM
bool "Math library"
bool "Standard Math library"
default n
depends on !ARCH_MATH_H
---help---

View File

@ -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