📄 usbkeyboardlib.c
字号:
/* Translate alpha keys */ if( ISALPHASCANCODE(scanCode) ) { if( modifiers & MOD_KEY_CTRL ) return( scanCodesShift [scanCode] - CTRL_CASE_OFFSET); if( !!(modifiers & MOD_KEY_SHIFT) ^ !!(pSioChan->capsLock) ) return( scanCodesShift [scanCode] ); else return( scanCodes [scanCode] ); } /* Translate non-alpha keys */ if ((modifiers & (MOD_KEY_SHIFT | MOD_KEY_CTRL)) != 0) return( scanCodesShift [scanCode] ); else return( scanCodes [scanCode] ); } return(NOTKEY); }/***************************************************************************** isKeyPresent - determines if a key is present in an array of keys** RETURNS: TRUE if <key> is present in the <keyArray> passed by the* caller, else returns FALSE.*/LOCAL BOOL isKeyPresent ( pUINT16 pKeyArray, UINT16 key ) { UINT16 i; for (i = 0; i < BOOT_RPT_KEYCOUNT; i++) if (key == pKeyArray [i]) return TRUE; return FALSE; }/***************************************************************************** setLedReport - Issues a SET_REPORT to change a keyboard's LEDs** RETURNS: N/A*/LOCAL VOID setLedReport ( pUSB_KBD_SIO_CHAN pSioChan, UINT8 ledReport ) { usbHidReportSet (usbdHandle, pSioChan->nodeId, pSioChan->interface, USB_HID_RPT_TYPE_OUTPUT, 0, &ledReport, sizeof (ledReport)); }/***************************************************************************** changeKeyState - changes keyboard state** <key> is CAPLOCK, SCRLOCK, or NUMLOCK. If <key> is not already active,* then, toggle the current keyboard state for the corresponding item.** RETURNS: N/A*/LOCAL VOID changeKbdState ( pUSB_KBD_SIO_CHAN pSioChan, UINT16 scanCode, pBOOL pKeyState ) { UINT8 ledReport; /* The scancode is newly active, toggle the corresponding keyboard state. */ *pKeyState = !(*pKeyState); /* Update the keyboard LEDs */ ledReport = (pSioChan->capsLock) ? RPT_LED_CAPS_LOCK : 0; ledReport |= (pSioChan->scrLock) ? RPT_LED_SCROLL_LOCK : 0; ledReport |= (pSioChan->numLock) ? RPT_LED_NUM_LOCK : 0; setLedReport (pSioChan, ledReport); }/***************************************************************************** interpScanCode - interprets keyboard scan code** Interprets the <scanCode> according to the <modifiers>. This function* handles any special requirements, such as turning an LED ON or OFF in* response to a keypress.** RETURNS: N/A.*/LOCAL void interpScanCode ( pUSB_KBD_SIO_CHAN pSioChan, UINT16 scanCode, UINT16 modifiers ) { /* If the key is already active, ignore it. */ if (isKeyPresent (pSioChan->activeScanCodes, scanCode)) return; /* Determine if special handling is required for the key */ switch (scanCode) { case CAPLOCK: /* key is CAPLOCK */ case CAPLOCK_LOCKING: /* key is CAPLOCK */ changeKbdState (pSioChan, scanCode, &pSioChan->capsLock); break; case SCRLOCK: /* key is SCRLOCK */ case SCRLOCK_LOCKING: /* key is SCRLOCK */ changeKbdState (pSioChan, scanCode, &pSioChan->scrLock); break; case NUMLOCK: /* key is NUMLOCK */ case NUMLOCK_LOCKING: /* key is NUMLOCK */ changeKbdState (pSioChan, scanCode, &pSioChan->numLock); break; case NOTKEY: /* no valid scan code mapping */ default: /* an ASCII character */ break; } }/***************************************************************************** putInChar - puts a character into channel's input queue** RETURNS: N/A*/LOCAL VOID putInChar ( pUSB_KBD_SIO_CHAN pSioChan, char putChar ) { if (pSioChan->inQueueCount < KBD_Q_DEPTH) { pSioChan->inQueue [pSioChan->inQueueIn] = putChar; if (++pSioChan->inQueueIn == KBD_Q_DEPTH) pSioChan->inQueueIn = 0; pSioChan->inQueueCount++; } }/***************************************************************************** nextInChar - returns next character from input queue** Returns the next character from the channel's input queue and updates* the queue pointers. The caller must ensure that at least one character* is in the queue prior to calling this function.** RETURNS: next char in queue*/LOCAL char nextInChar ( pUSB_KBD_SIO_CHAN pSioChan ) { char inChar = pSioChan->inQueue [pSioChan->inQueueOut]; if (++pSioChan->inQueueOut == KBD_Q_DEPTH) pSioChan->inQueueOut = 0; pSioChan->inQueueCount--; return inChar; }/***************************************************************************** updateTypematic - generates typematic characters for channel if appropriate** RETURNS: N/A*/LOCAL VOID updateTypematic ( pUSB_KBD_SIO_CHAN pSioChan ) { UINT32 diffTime; UINT32 repeatCount; /* If the given channel is active and a typematic character is * indicated, then update the typematic state. */ if (pSioChan->connected && pSioChan->typematicChar != 0) { diffTime = OSS_TIME () - pSioChan->typematicTime; /* If the typematic delay has passed, then it is time to start * injecting characters into the queue. */ if (diffTime >= TYPEMATIC_DELAY) { diffTime -= TYPEMATIC_DELAY; repeatCount = diffTime / TYPEMATIC_PERIOD + 1; /* Inject characters into the queue. If the queue is * full, putInChar() dumps the character, but we increment * the typematicCount anyway. This keeps the queue from * getting too far ahead of the user. */ while (repeatCount > pSioChan->typematicCount) { if( ISEXTENDEDKEYCODE(pSioChan->typematicChar) ) { if(pSioChan->inQueueCount < KBD_Q_DEPTH-1) { putInChar (pSioChan, (char) 0); putInChar (pSioChan, (char) pSioChan->typematicChar & 0xFF); } } else { putInChar (pSioChan, pSioChan->typematicChar); } pSioChan->typematicCount++; } /* invoke receive callback */ while (pSioChan->inQueueCount > 0 && pSioChan->putRxCharCallback != NULL && pSioChan->mode == SIO_MODE_INT) { (*pSioChan->putRxCharCallback) (pSioChan->putRxCharArg, nextInChar (pSioChan)); } } } }/***************************************************************************** interpKbdReport - interprets USB keyboard BOOT report** Interprets a keyboard boot report and updates channel state as* appropriate.** RETURNS: N/A*/LOCAL VOID interpKbdReport ( pUSB_KBD_SIO_CHAN pSioChan ) { pHID_KBD_BOOT_REPORT pReport = pSioChan->pBootReport; UINT16 keyCode; UINT16 newTypematicChar; UINT16 activeCount; UINT16 i; /* interpret each key position in a keyboard boot report * (handles CAPS/SCROLL/NUM lock). */ for (i = 0; i < BOOT_RPT_KEYCOUNT; i++) interpScanCode (pSioChan, pReport->scanCodes [i], pReport->modifiers); /* insert newly activated keys into the input queue for the keyboard */ newTypematicChar = 0; activeCount = 0; for (i = 0; i < BOOT_RPT_KEYCOUNT; i++) { if (pReport->scanCodes [i]) { keyCode = cvtScanCodeToKeyCode (pSioChan, pReport->scanCodes [i], pReport->modifiers); if (!isKeyPresent (pSioChan->activeScanCodes, pReport->scanCodes [i])) { /* If there is room in the input queue, enqueue the key, * else discard it. * For extended keyCodes, make sure there is room for two * chars - the 0 and the ext key. */ if( ISEXTENDEDKEYCODE(keyCode) ) { if(pSioChan->inQueueCount < KBD_Q_DEPTH-1) { putInChar (pSioChan, (char) 0); putInChar (pSioChan, (char) keyCode & 0xFF); } } else { if(keyCode) putInChar (pSioChan, (char) keyCode & 0xFF); } } newTypematicChar = keyCode; activeCount++; } } /* If newTypematicChar is 0, then no keys were received in this * report - so no keys are being held down. If newTypematicChar * matches the previous typematic char, then allow the typematic * timer to continue. If newTypematicChar is different (but non- * zero), then start a new timer. In all cases, only one key may * be active for typematic repeat to be enabled. */ if (activeCount != 1) newTypematicChar = 0; if (newTypematicChar != pSioChan->typematicChar) { pSioChan->typematicChar = newTypematicChar; if (newTypematicChar != 0) { pSioChan->typematicTime = OSS_TIME (); pSioChan->typematicCount = 0; } } updateTypematic (pSioChan); /* invoke receive callback */ while (pSioChan->inQueueCount > 0 && pSioChan->putRxCharCallback != NULL && pSioChan->mode == SIO_MODE_INT) { (*pSioChan->putRxCharCallback) (pSioChan->putRxCharArg, nextInChar (pSioChan)); } /* Copy the current list of active keys to the channel structure, * overwriting the previous list. */ for (i = 0; i < BOOT_RPT_KEYCOUNT; i++) pSioChan->activeScanCodes [i] = pReport->scanCodes [i]; }/***************************************************************************** usbKeyboardIoctl - special device control** This routine is largely a no-op for the usbKeyboardLib. The only ioctls* which are used by this module are the SIO_AVAIL_MODES_GET and SIO_MODE_SET.** RETURNS: OK on success, ENOSYS on unsupported request, EIO on failed* request.*/LOCAL int usbKeyboardIoctl ( SIO_CHAN *pChan, /* device to control */ int request, /* request code */ void *someArg /* some argument */ ) { pUSB_KBD_SIO_CHAN pSioChan = (pUSB_KBD_SIO_CHAN) pChan; int arg = (int) someArg; switch (request) { case SIO_BAUD_SET: /* baud rate has no meaning for USB. We store the desired * baud rate value and return OK. */ pSioChan->baudRate = arg; return OK; case SIO_BAUD_GET: /* Return baud rate to caller */ *((int *) arg) = pSioChan->baudRate; return OK; case SIO_MODE_SET: /* Set driver operating mode: interrupt or polled */ if (arg != SIO_MODE_POLL && arg != SIO_MODE_INT) return EIO; pSioChan->mode = arg; return OK; case SIO_MODE_GET: /* Return current driver operating mode for channel */ *((int *) arg) = pSioChan->mode; return OK; case SIO_AVAIL_MODES_GET: /* Return modes supported by driver. */ *((int *) arg) = SIO_MODE_INT | SIO_MODE_POLL; return OK; case SIO_OPEN: /* Channel is always open. */ return OK; case SIO_HW_OPTS_SET: /* optional, not supported */ case SIO_HW_OPTS_GET: /* optional, not supported */ case SIO_HUP: /* hang up is not supported */ default: /* unknown/unsupported command. */ return ENOSYS; } }/***************************************************************************** usbKeyboardTxStartup - start the interrupt transmitter** The USB keyboard SIO driver does not support output to the keyboard.** RETURNS: EIO*/LOCAL int usbKeyboardTxStartup ( SIO_CHAN *pChan /* channel to start */ ) { return EIO; }/***************************************************************************** usbKeyboardCallbackInstall - install ISR callbacks to get/put chars** This driver allows interrupt callbacks for transmitting characters* and receiving characters.=** RETURNS: OK on success, or ENOSYS for an unsupported callback type.*/ LOCAL int usbKeyboardCallbackInstall
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -