⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbkeyboardlib.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 4 页
字号:
** 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    )    {    UINT8 * pLedReport = OSS_CALLOC (sizeof (UINT8));    if (pLedReport == NULL)	return;    *pLedReport = ledReport;    usbHidReportSet (usbdHandle, 		     pSioChan->nodeId, 		     pSioChan->interface, 		     USB_HID_RPT_TYPE_OUTPUT,      		     0, 		     pLedReport, 		     sizeof (ledReport));    OSS_FREE (pLedReport);    }/***************************************************************************** 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, 			/* not used */    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.  Operates in one of two modes: ASCII or RAW.  In ASCII mode* it inserts the ascii character into the character buffer and implements* typematic repeat.  In RAW mode it always inserts the modifier byte* regardless of change, it inserts any keypresses that are currently active* and it inserts a terminating byte of 0xff into the charater buffer.** 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);    /* Raw mode has been set, handle accordingly */    if (pSioChan->scanMode == SIO_KYBD_MODE_RAW)	{	/* The first byte is any modifier keys, CTRL, SHIFT, ALT, GUI */	putInChar (pSioChan, pReport->modifiers);	for (i = 0; i < BOOT_RPT_KEYCOUNT; i++)	    if (pReport->scanCodes [i])		    /* Any depressed keys */		    putInChar (pSioChan, pReport->scanCodes [i]);	/* trailing byte */	putInChar (pSioChan, 0xff);    	}    /* then pSioChan->scanMode must = SIO_KYBD_MODE_ASCII */    else 	{	/* 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_KYBD_MODE_SET:             switch (arg)                 {                 case SIO_KYBD_MODE_RAW:                 case SIO_KYBD_MODE_ASCII:                     break;                 case SIO_KYBD_MODE_UNICODE:                     return ENOSYS; /* usb doesn't support unicode */                 }             pSioChan->scanMode = arg;             return OK;         case SIO_KYBD_MODE_GET:             *(int *)someArg = pSioChan->scanMode;             return OK;         case SIO_KYBD_LED_SET:	    {	    UINT8 ledReport; 	    /*  update the channel's information about the LED state */		    pSioChan->numLock = (arg & SIO_KYBD_LED_NUM) ? SIO_KYBD_LED_NUM : 0;	    pSioChan->capsLock = (arg & SIO_KYBD_LED_CAP) ? 					SIO_KYBD_LED_CAP : 0;	    pSioChan->scrLock = (arg & SIO_KYBD_LED_SCR) ? 					SIO_KYBD_LED_SCR : 0;	    /* 	     * We are relying on the SIO_KYBD_LED_X macros matching the USB	     * LED equivelants.	     */	    ledReport = arg;	    /* set the LED's */	    setLedReport (pSioChan, ledReport);	     	    return OK;	    }         case SIO_KYBD_LED_GET:	     {	     int tempArg;	    	     tempArg = (pSioChan->capsLock) ? SIO_KYBD_LED_CAP : 0;    	     tempArg |= (pSioChan->scrLock) ? SIO_KYBD_LED_SCR : 0;    	     tempArg |= (pSioChan->numLock) ? SIO_KYBD_LED_NUM : 0;	     *(int *) someArg = tempArg;             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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -