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

📄 usbkeyboardlib.c

📁 cpc-1631的BSP包for VxWorks操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:

    {
    pHID_KBD_BOOT_REPORT pReport = pSioChan->pBootReport;
    UINT16               keyCode;
    UINT16               newTypematicChar = 0;
    UINT16               activeCount = 0;
    UINT16               i = 0;
    BOOL                 validScanCode = FALSE;

    /*
     * 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);

	/* determine if the scan codes are valid */

	for (i = 0; i < BOOT_RPT_KEYCOUNT; i++)
	    {
	    if (pReport->scanCodes [i] != 0)
	         validScanCode = TRUE;
	    }

	if (validScanCode)
	    {

	    for (i = 0; i < BOOT_RPT_KEYCOUNT; i++)
                {
                if (pReport->scanCodes [i] > KBD_ERROR_UNDEFINED)
                    {

                    /* determine if this key is present in the active scancode */

                    if (!isKeyPresent (pSioChan->activeScanCodes,
                        pReport->scanCodes [i]))

                        /* put the data into scancode into the queue */

                        putInChar (pSioChan, pReport->scanCodes [i]);

                    /*
                     * update the newTypematicChar for auto repeat. The first byte
                     * will be modifier byte and the second byte is for scan code
                     */

                    newTypematicChar = (pReport->modifiers << 0x8) |
                                       (pReport->scanCodes [i]);
	            activeCount++;

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

	for (i = 0; i < BOOT_RPT_KEYCOUNT; i++)
	    {
            /*
             * According to the specification, scan code 0x00 is reserved
             * scan code 0x01, 0x02, 0x03 specify the keyboard status and error
             * conditions. Therefore interpret the scan code only when it is
             * greater than 0x03
             */
            if(pReport->scanCodes[i] > KBD_ERROR_UNDEFINED)
		{
		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 == 0)
        newTypematicChar = 0;

    if (newTypematicChar != pSioChan->typematicChar)
        {
        pSioChan->typematicChar = newTypematicChar;

        if (newTypematicChar != 0)
            {
            pSioChan->typematicTime = OSS_TIME ();
            pSioChan->typematicCount = 0;
            }
        }
    /* call the typematic function */

    updateTypematic (pSioChan);

    /* invoke receive callback */

    while (pSioChan->inQueueCount > 0 &&
           pSioChan->putRxCharCallback != NULL &&
           pSioChan->mode == SIO_MODE_INT)
	{
        (*pSioChan->putRxCharCallback) (pSioChan->putRxCharArg, 
					nextInChar (pSioChan));
	}

    /*
     * the active scan codes array is only to be updated when no error condition
     * is encountered. According to specification the scan codes 0x01, 0x02 and
     * 0x03 report the condition of the keyboard. Hence return if any of the scan
     * codes received matches these scan codes.
     */

    for (i = 0; i < BOOT_RPT_KEYCOUNT; i++)
       {
       if ( pReport->scanCodes[i] == KBD_ERROR_ROLLOVER ||
            pReport->scanCodes[i] == KBD_POST_FAIL      ||
            pReport->scanCodes[i] == KBD_ERROR_UNDEFINED )
           {
           /*
            * error occured at keyboard end
            * do not change the active scan codes
            */
           return;
           }
       }
    for (i = 0; i < BOOT_RPT_KEYCOUNT; i++)
	pSioChan->activeScanCodes [i] = pReport->scanCodes [i];

    return;
    }


/***************************************************************************
*
* 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
*
* ERRNO: none
*
*\NOMANUAL
*/

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 equivalent.
	     */

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


/***************************************************************************
*
* usbKeyboardTxStartup - start the interrupt transmitter
*
* The USB keyboard SIO driver does not support output to the keyboard.
*
* RETURNS: EIO
*
* ERRNO: none
*
*\NOMANUAL
*/

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
*
* ERRNO: none
*
*\NOMANUAL
*/ 

LOCAL int usbKeyboardCallbackInstall
    (
    SIO_CHAN *pChan,	    /* channel */
    int callbackType,	    /* type of callback */
    STATUS (*callback) (void *tmp, ...),  /* callback */
    void *callbackArg	    /* parameter to callback */
    )

    {
    pUSB_KBD_SIO_CHAN pSioChan = (pUSB_KBD_SIO_CHAN) pChan;

    switch (callbackType)
	{
	case SIO_CALLBACK_GET_TX_CHAR:
	    pSioChan->getTxCharCallback = (callback);
	    pSioChan->getTxCharArg = callbackArg;
	    return OK;

	case SIO_CALLBACK_PUT_RCV_CHAR:
	    pSioChan->putRxCharCallback = (callback);
	    pSioChan->putRxCharArg = callbackArg;
	    return OK;

	default:
	    return ENOSYS;
	}
    }


/***************************************************************************
*
* usbKeyboardPollOutput - output a character in polled mode
*
* The USB keyboard SIO driver does not support output to the keyboard.
*
* RETURNS: EIO
*
* ERRNO: none
*
*\NOMANUAL
*/

LOCAL int usbKeyboardPollOutput
    (
    SIO_CHAN *pChan,
    char outChar
    )

    {
    return EIO;
    }


/***************************************************************************
*
* usbKeyboardPollInput - poll the device for input
*
* This function polls the keyboard device for input.
*
* RETURNS: OK if a character arrived, EIO on device error, EAGAIN
* if the input buffer if empty, ENOSYS if the device is interrupt-only.
*
* ERRNO: none
*
*\NOMANUAL 
*/

LOCAL int usbKeyboardPollInput
    (
    SIO_CHAN *pChan,
    char *thisChar
    )

    {
    pUSB_KBD_SIO_CHAN pSioChan = (pUSB_KBD_SIO_CHAN) pChan;
    int status = OK;


    /* validate parameters */

    if (thisChar == NULL)
        return EIO;


    OSS_MUTEX_TAKE (kbdMutex, OSS_BLOCK);

    /* Check if the input queue is empty. */

    if (pSioChan->inQueueCount == 0)
        status = EAGAIN;
    else
	{
	/* Return a character from the input queue. */

	*thisChar = nextInChar (pSioChan);
	}

    OSS_MUTEX_RELEASE (kbdMutex);

⌨️ 快捷键说明

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