Add logic to map keyboard scancodes

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3257 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2011-01-18 02:17:49 +00:00
parent f0f2c61a53
commit 57ca7d1157
3 changed files with 288 additions and 70 deletions

View File

@ -952,7 +952,7 @@ static inline int lpc17_addinted(struct lpc17_usbhost_s *priv,
/* Re-enabled periodic list processing */ /* Re-enabled periodic list processing */
regval = lpc17_getreg(LPC17_USBHOST_CTRL); regval = lpc17_getreg(LPC17_USBHOST_CTRL);
regval &= ~OHCI_CTRL_PLE; regval |= OHCI_CTRL_PLE;
lpc17_putreg(regval, LPC17_USBHOST_CTRL); lpc17_putreg(regval, LPC17_USBHOST_CTRL);
return OK; return OK;
#else #else
@ -1089,7 +1089,7 @@ static inline int lpc17_reminted(struct lpc17_usbhost_s *priv,
if (head != NULL) if (head != NULL)
{ {
regval = lpc17_getreg(LPC17_USBHOST_CTRL); regval = lpc17_getreg(LPC17_USBHOST_CTRL);
regval &= ~OHCI_CTRL_PLE; regval |= OHCI_CTRL_PLE;
lpc17_putreg(regval, LPC17_USBHOST_CTRL); lpc17_putreg(regval, LPC17_USBHOST_CTRL);
} }

View File

@ -91,10 +91,25 @@
#ifndef CONFIG_HIDKBD_DEFPRIO #ifndef CONFIG_HIDKBD_DEFPRIO
# define CONFIG_HIDKBD_DEFPRIO 50 # define CONFIG_HIDKBD_DEFPRIO 50
#endif #endif
#ifndef CONFIG_HIDKBD_STACKSIZE #ifndef CONFIG_HIDKBD_STACKSIZE
# define CONFIG_HIDKBD_STACKSIZE 1024 # define CONFIG_HIDKBD_STACKSIZE 1024
#endif #endif
#ifndef CONFIG_USBHID_BUFSIZE
# define CONFIG_USBHID_BUFSIZE 64
#endif
/* The default is to support 104 key keyboard. CONFIG_USBHID_ALLSCANCODES
* will enable all scancodes.
*/
#ifdef CONFIG_USBHID_ALLSCANCODES
# define USBHID_NUMSCANCODES (USBHID_KBDUSE_MAX+1)
#else
# define USBHID_NUMSCANCODES 104
#endif
/* Driver support ***********************************************************/ /* Driver support ***********************************************************/
/* This format is used to construct the /dev/kbd[n] device driver path. It /* This format is used to construct the /dev/kbd[n] device driver path. It
* defined here so that it will be used consistently in all places. * defined here so that it will be used consistently in all places.
@ -136,6 +151,7 @@ struct usbhost_state_s
char devchar; /* Character identifying the /dev/kbd[n] device */ char devchar; /* Character identifying the /dev/kbd[n] device */
volatile bool disconnected; /* TRUE: Device has been disconnected */ volatile bool disconnected; /* TRUE: Device has been disconnected */
volatile bool polling; /* TRUE: Poll thread is running */ volatile bool polling; /* TRUE: Poll thread is running */
bool open; /* TRUE: The keyboard device is open */
uint8_t ifno; /* Interface number */ uint8_t ifno; /* Interface number */
int16_t crefs; /* Reference count on the driver instance */ int16_t crefs; /* Reference count on the driver instance */
sem_t exclsem; /* Used to maintain mutual exclusive access */ sem_t exclsem; /* Used to maintain mutual exclusive access */
@ -158,6 +174,12 @@ struct usbhost_state_s
usbhost_ep_t epin; /* Interrupt IN endpoint */ usbhost_ep_t epin; /* Interrupt IN endpoint */
usbhost_ep_t epout; /* Optional interrupt OUT endpoint */ usbhost_ep_t epout; /* Optional interrupt OUT endpoint */
/* Buffer used to collect and buffer incoming keyboard characters */
uint16_t headndx; /* Buffer head index */
uint16_t tailndx; /* Buffer tail index */
uint8_t buffer[CONFIG_USBHID_BUFSIZE];
}; };
/**************************************************************************** /****************************************************************************
@ -183,6 +205,7 @@ static inline void usbhost_mkdevname(FAR struct usbhost_state_s *priv, char *dev
/* Keyboard polling thread */ /* Keyboard polling thread */
static void usbhost_destroy(FAR void *arg); static void usbhost_destroy(FAR void *arg);
static uint8_t usbhost_mapscancode(uint8_t scancode, uint8_t modifier);
static int usbhost_kbdpoll(int argc, char *argv[]); static int usbhost_kbdpoll(int argc, char *argv[]);
/* Helpers for usbhost_connect() */ /* Helpers for usbhost_connect() */
@ -280,6 +303,81 @@ static sem_t g_exclsem; /* For mutually exclusive thread creat
static sem_t g_syncsem; /* Thread data passing interlock */ static sem_t g_syncsem; /* Thread data passing interlock */
static struct usbhost_state_s *g_priv; /* Data passed to thread */ static struct usbhost_state_s *g_priv; /* Data passed to thread */
/* The following tables map keyboard scan codes to printable ASIC
* characters. There is no support here for function keys or cursor
* controls.
*/
static const uint8_t ucmap[USBHID_NUMSCANCODES] =
{
0, 0, 0, 0, 'A', 'B', 'C', 'D', /* 0x00-0x07: Reserved, errors, A-D */
'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', /* 0x08-0x0f: E-L */
'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', /* 0x10-0x17: M-T */
'U', 'V', 'W', 'X', 'Y', 'Z', '!', '@', /* 0x18-0x1f: U-Z,!,@ */
'#', '$', '%', '^', '&', '*', '(', ')', /* 0x20-0x27: #,$,%,^,&,*,(,) */
'\n', '\033', '\177', 0, ' ', '_', '+', '{', /* 0x28-0x2f: Enter,escape,del,back-tab,space,_,+,{ */
'}', '|', 0, ':', '"', 0, '<', '>', /* 0x30-0x37: },|,Non-US tilde,:,",grave tidle,<,> */
'?', 0, 0, 0, 0, 0, 0, 0, /* 0x38-0x3f: /,CapsLock,F1,F2,F3,F4,F5,F6 */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x40-0x47: F7,F8,F9,F10,F11,F12,PrtScn,sScrollLock */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x48-0x4f: Pause,Insert,Home,PageUp,DeleteForward,End,PageDown,RightArrow */
0, 0, 0, 0, '/', '*', '-', '+', /* 0x50-0x57: LeftArrow,DownArrow,UpArrow,Num Lock,/,*,-,+ */
'\n', '1', '2', '3', '4', '4', '6', '7', /* 0x58-0x5f: Enter,1-7 */
'8', '9', '0', '.', 0, 0, 0, '=', /* 0x60-0x67: 8-9,0,.,Non-US \,Application,Power,= */
#ifdef CONFIG_USBHID_ALLSCANCODES
0, 0, 0, 0, 0, 0, 0, 0, /* 0x68-0x6f: F13,F14,F15,F16,F17,F18,F19,F20 */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x77: F21,F22,F23,F24,Execute,Help,Menu,Select */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x78-0x7f: Stop,Again,Undo,Cut,Copy,Paste,Find,Mute */
0, 0, 0, 0, 0, ',', 0, 0, /* 0x80-0x87: VolUp,VolDown,LCapsLock,lNumLock,LScrollLock,,,=,International1 */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x88-0x8f: International 2-9 */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x97: LAN 1-8 */
0, 0, 0, 0, 0, 0, '\n', 0, /* 0x98-0x9f: LAN 9,Ease,SysReq,Cancel,Clear,Prior,Return,Separator */
0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0-0xa7: Out,Oper,Clear,CrSel,Excel,(reserved) */
0, 0, 0, 0, 0, 0, 0, 0, /* 0xa8-0xaf: (reserved) */
0, 0, 0, 0, 0, 0, '(', ')', /* 0xb0-0xb7: 00,000,ThouSeparator,DecSeparator,CurrencyUnit,SubUnit,(,) */
'{', '}', '\t', \177, 'A', 'B', 'C', 'D', /* 0xb8-0xbf: {,},tab,backspace,A-D */
'F', 'F', 0, '^', '%', '<', '>', '&', /* 0xc0-0xc7: E-F,XOR,^,%,<,>,& */
0, '|', 0, ':', '%', ' ', '@', '!', /* 0xc8-0xcf: &&,|,||,:,#, ,@,! */
0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0-0xd7: Memory Store,Recall,Clear,Add,Subtract,Muliply,Divide,+/- */
0, 0, 0, 0, 0, 0, 0, 0, /* 0xd8-0xdf: Clear,ClearEntry,Binary,Octal,Decimal,Hexadecimal */
0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0-0xe7: Left Ctrl,Shift,Alt,GUI, Right Ctrl,Shift,Alt,GUI */
#endif
};
static const uint8_t lcmap[USBHID_NUMSCANCODES] =
{
0, 0, 0, 0, 'a', 'b', 'c', 'd', /* 0x00-0x07: Reserved, errors, a-d */
'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', /* 0x08-0x0f: e-l */
'm', 'n', 'o', 'p', 'q', 'r', 's', 't', /* 0x10-0x17: m-t */
'u', 'v', 'w', 'x', 'y', 'z', '1', '2', /* 0x18-0x1f: u-z,1-2 */
'3', '4', '5', '6', '7', '8', '9', '0', /* 0x20-0x27: 3-9,0 */
'\n', '\033', '\177', '\t', ' ', '-', '=', '[', /* 0x28-0x2f: Enter,escape,del,tab,space,-,=,[ */
']', '\\', '\234', ';', '\'', 0, ',', '.', /* 0x30-0x37: ],\,Non-US pound,;,',grave accent,,,. */
'/', 0, 0, 0, 0, 0, 0, 0, /* 0x38-0x3f: /,CapsLock,F1,F2,F3,F4,F5,F6 */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x40-0x47: F7,F8,F9,F10,F11,F12,PrtScn,ScrollLock */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x48-0x4f: Pause,Insert,Home,PageUp,DeleteForward,End,PageDown,RightArrow */
0, 0, 0, 0, '/', '*', '-', '+', /* 0x50-0x57: LeftArrow,DownArrow,UpArrow,Num Lock,/,*,-,+ */
'\n', '1', '2', '3', '4', '4', '6', '7', /* 0x58-0x5f: Enter,1-7 */
'8', '9', '0', '.', 0, 0, 0, '=', /* 0x60-0x67: 8-9,0,.,Non-US \,Application,Power,= */
#ifdef CONFIG_USBHID_ALLSCANCODES
0, 0, 0, 0, 0, 0, 0, 0, /* 0x68-0x6f: F13,F14,F15,F16,F17,F18,F19,F20 */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x77: F21,F22,F23,F24,Execute,Help,Menu,Select */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x78-0x7f: Stop,Again,Undo,Cut,Copy,Paste,Find,Mute */
0, 0, 0, 0, 0, ',', 0, 0, /* 0x80-0x87: VolUp,VolDown,LCapsLock,lNumLock,LScrollLock,,,=,International1 */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x88-0x8f: International 2-9 */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x97: LAN 1-8 */
0, 0, 0, 0, 0, 0, '\n', 0, /* 0x98-0x9f: LAN 9,Ease,SysReq,Cancel,Clear,Prior,Return,Separator */
0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0-0xa7: Out,Oper,Clear,CrSel,Excel,(reserved) */
0, 0, 0, 0, 0, 0, 0, 0, /* 0xa8-0xaf: (reserved) */
0, 0, 0, 0, 0, 0, '(', ')', /* 0xb0-0xb7: 00,000,ThouSeparator,DecSeparator,CurrencyUnit,SubUnit,(,) */
'{', '}', '\t', '\177', 'A', 'B', 'C', 'D', /* 0xb8-0xbf: {,},tab,backspace,A-D */
'F', 'F', 0, '^', '%', '<', '>', '&', /* 0xc0-0xc7: E-F,XOR,^,%,<,>,& */
0, '|', 0, ':', '%', ' ', '@', '!', /* 0xc8-0xcf: &&,|,||,:,#, ,@,! */
0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0-0xd7: Memory Store,Recall,Clear,Add,Subtract,Muliply,Divide,+/- */
0, 0, 0, 0, 0, 0, 0, 0, /* 0xd8-0xdf: Clear,ClearEntry,Binary,Octal,Decimal,Hexadecimal */
0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0-0xe7: Left Ctrl,Shift,Alt,GUI, Right Ctrl,Shift,Alt,GUI */
#endif
};
/**************************************************************************** /****************************************************************************
* Private Functions * Private Functions
****************************************************************************/ ****************************************************************************/
@ -477,36 +575,42 @@ static void usbhost_destroy(FAR void *arg)
} }
/**************************************************************************** /****************************************************************************
* Name: usbhost_dumprpt * Name: usbhost_mapscancode
* *
* Description: * Description:
* Dump the interesting context of the keyboard report that we just * Map a keyboard scancode to a printable ASCII character. There is no
* received. * support here for function keys or cursor controls in this version of
* the driver.
* *
* Input Parameters: * Input Parameters:
* arg - A reference to the class instance to be destroyed. * scancode - Scan code to be mapped.
* modifier - Ctrl,Alt,Shift,GUI modifier bits
* *
* Returned Values: * Returned Values:
* None * None
* *
****************************************************************************/ ****************************************************************************/
#if defined(CONFIG_DEBUG_USB) && defined(CONFIG_DEBUG_VERBOSE) static uint8_t usbhost_mapscancode(uint8_t scancode, uint8_t modifier)
static inline void usbhost_dumprpt(uint8_t *buffer)
{ {
struct usbhid_kbdreport_s *rpt = (struct usbhid_kbdreport_s *)buffer; /* Range check */
int i;
for (i = 0; i < 6; i++) if (scancode >= USBHID_NUMSCANCODES)
{ {
if (rpt->key[i]) return 0;
}
/* Is either shift key pressed? */
if ((modifier & (USBHID_MODIFER_LSHIFT|USBHID_MODIFER_RSHIFT)) != 0)
{ {
uvdbg("Key %d: %08x modifier: %08x\n", rpt->key[i], rpt->modifier); return ucmap[scancode];
}
else
{
return lcmap[scancode];
} }
} }
}
#else
# define usbhost_dumprpt(buffer)
#endif
/**************************************************************************** /****************************************************************************
* Name: usbhost_kbdpoll * Name: usbhost_kbdpoll
@ -527,9 +631,9 @@ static int usbhost_kbdpoll(int argc, char *argv[])
FAR struct usbhost_state_s *priv; FAR struct usbhost_state_s *priv;
FAR struct usb_ctrlreq_s *ctrlreq; FAR struct usb_ctrlreq_s *ctrlreq;
#ifdef CONFIG_DEBUG_USB #ifdef CONFIG_DEBUG_USB
static unsigned int npolls = 0; unsigned int npolls = 0;
#endif #endif
static unsigned int nerrors; unsigned int nerrors;
int ret; int ret;
uvdbg("Started\n"); uvdbg("Started\n");
@ -563,7 +667,7 @@ static int usbhost_kbdpoll(int argc, char *argv[])
usbhost_takesem(&priv->exclsem); usbhost_takesem(&priv->exclsem);
/* Format the hid report request: /* Format the HID report request:
* *
* bmRequestType 10000001 * bmRequestType 10000001
* bRequest GET_DESCRIPTOR (0x06) * bRequest GET_DESCRIPTOR (0x06)
@ -574,39 +678,119 @@ static int usbhost_kbdpoll(int argc, char *argv[])
*/ */
ctrlreq = (struct usb_ctrlreq_s *)priv->tbuffer; ctrlreq = (struct usb_ctrlreq_s *)priv->tbuffer;
ctrlreq->type = USB_REQ_DIR_IN|USB_REQ_RECIPIENT_INTERFACE; ctrlreq->type = USB_REQ_DIR_IN|USB_REQ_TYPE_CLASS|USB_REQ_RECIPIENT_INTERFACE;
ctrlreq->req = USB_REQ_GETDESCRIPTOR; ctrlreq->req = USBHID_REQUEST_GETREPORT;
usbhost_putle16(ctrlreq->value, (USBHID_DESCTYPE_REPORT << 8));
usbhost_putle16(ctrlreq->index, priv->ifno);
usbhost_putle16(ctrlreq->len, 8);
/* Send the report */ usbhost_putle16(ctrlreq->value, (USBHID_REPORTTYPE_INPUT << 8));
usbhost_putle16(ctrlreq->index, priv->ifno);
usbhost_putle16(ctrlreq->len, sizeof(struct usbhid_kbdreport_s));
/* Send HID report request */
ret = DRVR_CTRLIN(priv->drvr, ctrlreq, priv->tbuffer); ret = DRVR_CTRLIN(priv->drvr, ctrlreq, priv->tbuffer);
usbhost_givesem(&priv->exclsem); usbhost_givesem(&priv->exclsem);
/* Check for errors -- Bail if an excessive number of errors
* are encountered.
*/
if (ret != OK) if (ret != OK)
{ {
nerrors++; nerrors++;
udbg("ERROR: GETDESCRIPTOR/REPORT, DRVR_CTRLIN returned: %d/%d\n", udbg("ERROR: GETREPORT/INPUT, DRVR_CTRLIN returned: %d/%d\n",
ret, nerrors); ret, nerrors);
if (nerrors > 200) if (nerrors > 200)
{ {
udbg("Too man errors... aborting: %d\n", nerrors); udbg("Too many errors... aborting: %d\n", nerrors);
break; break;
} }
} }
else
{ /* The report was received correctly. But ignore the keystrokes if no
/* If debug is enabled, then dump the interesting poarts of the * task has opened the driver.
* report that we just received.
*/ */
usbhost_dumprpt(priv->tbuffer); else if (priv->open)
{
struct usbhid_kbdreport_s *rpt = (struct usbhid_kbdreport_s *)priv->buffer;
unsigned int head;
unsigned int tail;
uint8_t ascii;
int i;
/* Add the newly recevied keystrokes to our internal buffer */ /* Add the newly received keystrokes to our internal buffer */
#warning "Missing logic"
usbhost_takesem(&priv->exclsem);
head = priv->headndx;
tail = priv->tailndx;
for (i = 0; i < 6; i++)
{
/* Is this key pressed? */
if (rpt->key[i] == USBHID_KBDUSE_NONE)
{
/* Yes.. Add it to the buffer. */
/* Map the keyboard scancode to a printable ASCII
* character. There is no support here for function keys
* or cursor controls in this version of the driver.
*/
ascii = usbhost_mapscancode(rpt->key[i], rpt->modifier);
uvdbg("Key %d: %02x ASCII:%c modifier: %02x\n",
i, rpt->key[i], ascii ? ascii : ' ', rpt->modifier);
/* Zero at this point means that the key does not map to a
* printable character.
*/
if (ascii != 0)
{
/* Handle control characters. Zero after this means
* a valid, NUL character.
*/
if ((rpt->modifier & (USBHID_MODIFER_LSHIFT|USBHID_MODIFER_RSHIFT)) != 0)
{
ascii &= 0x1f;
}
/* Copy the next keyboard character into the user
* buffer.
*/
priv->buffer[head] = ascii;
/* Increment the head index */
if (++head >= CONFIG_USBHID_BUFSIZE)
{
head = 0;
}
/* If the buffer is full, then increment the tail
* index to make space. Is it better to lose old
* keystrokes or new?
*/
if (tail == head)
{
if (++tail >= CONFIG_USBHID_BUFSIZE)
{
tail = 0;
}
}
}
}
}
/* Update the head/tail indices */
priv->headndx = head;
priv->tailndx = tail;
usbhost_givesem(&priv->exclsem);
} }
/* If USB debug is on, then provide some periodic indication that /* If USB debug is on, then provide some periodic indication that
@ -1411,6 +1595,7 @@ static int usbhost_open(FAR struct file *filep)
/* Otherwise, just increment the reference count on the driver */ /* Otherwise, just increment the reference count on the driver */
priv->crefs++; priv->crefs++;
priv->open = true;
ret = OK; ret = OK;
} }
irqrestore(flags); irqrestore(flags);
@ -1431,7 +1616,6 @@ static int usbhost_close(FAR struct file *filep)
{ {
FAR struct inode *inode; FAR struct inode *inode;
FAR struct usbhost_state_s *priv; FAR struct usbhost_state_s *priv;
irqstate_t flags;
uvdbg("Entry\n"); uvdbg("Entry\n");
DEBUGASSERT(filep && filep->f_inode); DEBUGASSERT(filep && filep->f_inode);
@ -1444,12 +1628,19 @@ static int usbhost_close(FAR struct file *filep)
usbhost_takesem(&priv->exclsem); usbhost_takesem(&priv->exclsem);
priv->crefs--; priv->crefs--;
/* Release the semaphore. The following operations when crefs == 1 are /* Is this the last reference (other than the one held by the USB host
* safe because we know that there is no outstanding open references to * controller driver)
* the driver.
*/ */
usbhost_givesem(&priv->exclsem); if (priv->crefs <= 1)
{
irqstate_t flags;
/* Yes.. then the driver is no longer open */
priv->open = false;
priv->headndx = 0;
priv->tailndx = 0;
/* We need to disable interrupts momentarily to assure that there are /* We need to disable interrupts momentarily to assure that there are
* no asynchronous disconnect events. * no asynchronous disconnect events.
@ -1458,18 +1649,24 @@ static int usbhost_close(FAR struct file *filep)
flags = irqsave(); flags = irqsave();
/* Check if the USB keyboard device is still connected. If the device is /* Check if the USB keyboard device is still connected. If the device is
* not connected and the reference count just decremented to one, then * no longer connected, then unregister the driver and free the driver
* unregister then free the driver class instance. * class instance.
*/ */
if (priv->crefs <= 1 && priv->disconnected) if (priv->disconnected)
{ {
/* Destroy the class instance */ /* Destroy the class instance (we can't use priv after this; we can't
* 'give' the semapore)
*/
usbhost_destroy(priv); usbhost_destroy(priv);
irqrestore(flags);
return OK;
}
irqrestore(flags);
} }
irqrestore(flags); usbhost_givesem(&priv->exclsem);
return OK; return OK;
} }
@ -1485,7 +1682,8 @@ static ssize_t usbhost_read(FAR struct file *filep, FAR char *buffer, size_t len
{ {
FAR struct inode *inode; FAR struct inode *inode;
FAR struct usbhost_state_s *priv; FAR struct usbhost_state_s *priv;
irqstate_t flags; size_t remaining;
unsigned int tail;
int ret; int ret;
uvdbg("Entry\n"); uvdbg("Entry\n");
@ -1502,7 +1700,6 @@ static ssize_t usbhost_read(FAR struct file *filep, FAR char *buffer, size_t len
* momentarily to assure that there are no asynchronous disconnect events. * momentarily to assure that there are no asynchronous disconnect events.
*/ */
flags = irqsave();
if (priv->disconnected) if (priv->disconnected)
{ {
/* No... the driver is no longer bound to the class. That means that /* No... the driver is no longer bound to the class. That means that
@ -1515,9 +1712,28 @@ static ssize_t usbhost_read(FAR struct file *filep, FAR char *buffer, size_t len
else else
{ {
/* Read data from our internal buffer of received characters */ /* Read data from our internal buffer of received characters */
#warning "Missing logic"
for (tail = priv->tailndx;
tail != priv->headndx && remaining > 0;
tail++, remaining--)
{
/* Handle wrap-around of the tail index */
if (tail >= CONFIG_USBHID_BUFSIZE)
{
tail = 0;
}
/* Copy the next keyboard character into the user buffer */
*buffer += priv->buffer[tail];
remaining--;
}
/* Update the tail index (pehaps marking the buffer empty) */
priv->tailndx = tail;
} }
irqrestore(flags);
usbhost_givesem(&priv->exclsem); usbhost_givesem(&priv->exclsem);
return 0; /* Return EOF for now */ return 0; /* Return EOF for now */

View File

@ -115,10 +115,10 @@
#define USBHID_REQUEST_GETREPORT 0x01 #define USBHID_REQUEST_GETREPORT 0x01
#define USBHID_REQUEST_GETIDLE 0x02 #define USBHID_REQUEST_GETIDLE 0x02
#define USBHID_REQUEST_GET_PROTOCOL 0x03 #define USBHID_REQUEST_GETPROTOCOL 0x03
#define USBHID_REQUEST_SET_REPORT 0x09 #define USBHID_REQUEST_SETREPORT 0x09
#define USBHID_REQUEST_SET_IDLE 0x0a #define USBHID_REQUEST_SETIDLE 0x0a
#define USBHID_REQUEST_SET_PROTOCOL 0x0b #define USBHID_REQUEST_SETPROTOCOL 0x0b
/* Report Type (MS byte of wValue for GET_REPORT) (HID 7.2.1) */ /* Report Type (MS byte of wValue for GET_REPORT) (HID 7.2.1) */
@ -414,7 +414,7 @@
#define USBHID_KBDUSE_CLEAR 0x9c /* Keyboard Clear */ #define USBHID_KBDUSE_CLEAR 0x9c /* Keyboard Clear */
#define USBHID_KBDUSE_PRIOR 0x9d /* Keyboard Prior */ #define USBHID_KBDUSE_PRIOR 0x9d /* Keyboard Prior */
#define USBHID_KBDUSE_RETURN 0x9e /* Keyboard Return */ #define USBHID_KBDUSE_RETURN 0x9e /* Keyboard Return */
#define USBHID_KBDUSE_SEPARATRO 0x9f /* Keyboard Separator */ #define USBHID_KBDUSE_SEPARATOR 0x9f /* Keyboard Separator */
#define USBHID_KBDUSE_OUT 0xa0 /* Keyboard Out */ #define USBHID_KBDUSE_OUT 0xa0 /* Keyboard Out */
#define USBHID_KBDUSE_OPER 0xa1 /* Keyboard Oper */ #define USBHID_KBDUSE_OPER 0xa1 /* Keyboard Oper */
#define USBHID_KBDUSE_CLEARAGAIN 0xa2 /* Keyboard Clear/Again */ #define USBHID_KBDUSE_CLEARAGAIN 0xa2 /* Keyboard Clear/Again */
@ -470,6 +470,8 @@
#define USBHID_KBDUSE_RALT 0xe6 /* Keyboard RightAlt */ #define USBHID_KBDUSE_RALT 0xe6 /* Keyboard RightAlt */
#define USBHID_KBDUSE_RGUI 0xe7 /* Keyboard Right GUI*/ #define USBHID_KBDUSE_RGUI 0xe7 /* Keyboard Right GUI*/
#define USBHID_KBDUSE_MAX 0xe7
/* Mouse input report (HID B.2) */ /* Mouse input report (HID B.2) */
#define USBHID_MOUSEIN_BUTTON1 (1 << 0) #define USBHID_MOUSEIN_BUTTON1 (1 << 0)