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

📄 usbkeyboardlib.c

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


/***************************************************************************
*
* initKbdIrp - Initialize IRP to listen for input on interrupt pipe
*
* This function intializes the IRP to listen on the interrupt pipe
*
* RETURNS: TRUE if able to submit IRP successfully, else FALSE
*
* ERRNO: none
*
*\NOMANUAL
*/

LOCAL BOOL initKbdIrp
    (
    pUSB_KBD_SIO_CHAN pSioChan
    )

    {
    pUSB_IRP pIrp = &pSioChan->irp;

    /* Initialize IRP */

    memset (pIrp, 0, sizeof (*pIrp));

    pIrp->userPtr = pSioChan;
    pIrp->irpLen = sizeof (*pIrp);
    pIrp->userCallback = usbKeyboardIrpCallback;
    pIrp->timeout = USB_TIMEOUT_NONE;
    pIrp->transferLen = sizeof (HID_KBD_BOOT_REPORT);

    pIrp->bfrCount = 1;
    pIrp->bfrList [0].pid = USB_PID_IN;
    pIrp->bfrList [0].pBfr = (pUINT8) pSioChan->pBootReport;
    pIrp->bfrList [0].bfrLen = sizeof (HID_KBD_BOOT_REPORT);


    /* Submit IRP */

    if (usbdTransfer (usbdHandle, pSioChan->pipeHandle, pIrp) != OK)
	return FALSE;

    pSioChan->irpInUse = TRUE;


    return TRUE;
    }


/***************************************************************************
*
* usbKeyboardIrpCallback - Invoked upon IRP completion/cancellation
*
* Examines the cause of the IRP completion.  If completion was successful,
* interprets the USB keyboard's boot report and re-submits the IRP.
*
* RETURNS: N/A
*
* ERRNO: none
*
*\NOMANUAL
*/

LOCAL VOID usbKeyboardIrpCallback
    (
    pVOID p	    /* completed IRP */
    )

    {
    pUSB_IRP pIrp = (pUSB_IRP) p;
    pUSB_KBD_SIO_CHAN pSioChan = pIrp->userPtr;


    OSS_MUTEX_TAKE (kbdMutex, OSS_BLOCK);

    /* Was the IRP successful? */

    if (pIrp->result == OK)
	{
	/* Interpret the keyboard report */

	interpKbdReport (pSioChan);
	}


    /* Re-submit the IRP unless it was canceled - which would happen only
     * during pipe shutdown (e.g., the disappearance of the device).
     */

    pSioChan->irpInUse = FALSE;

    if (pIrp->result != S_usbHcdLib_IRP_CANCELED) 
	{
	initKbdIrp (pSioChan);
	}
    else 
        {
        if (!pSioChan->connected)
            {
            /* Release structure. */
            if (pSioChan->pBootReport != NULL)
                OSS_FREE (pSioChan->pBootReport);
	
	    OSS_FREE (pSioChan);
            }           
        }
    
    OSS_MUTEX_RELEASE (kbdMutex);
    }


/***************************************************************************
*
* typematicThread - Updates typematic state for each active channel
*
* Updates typematic state for each active channel
*
* RETURNS: N/A
*
* ERRNO: none
*
*\NOMANUAL
*/

LOCAL VOID typematicThread
    (
    pVOID param 	/* param not used by this thread */
    )

    {
    pUSB_KBD_SIO_CHAN pSioChan;


    while (!killTypematic)
	{
        OSS_MUTEX_TAKE (kbdMutex, OSS_BLOCK);

        /* Walk the list of open channels and update the typematic
         * state for each.
         */

        pSioChan = usbListFirst (&sioList);

        while (pSioChan != NULL)
	    {
	    updateTypematic (pSioChan);
	    pSioChan = usbListNext (&pSioChan->sioLink);
	    }

        OSS_MUTEX_RELEASE (kbdMutex);

        OSS_THREAD_SLEEP (TYPEMATIC_PERIOD);
	}

    typematicExit = TRUE;

    }


/***************************************************************************
*
* configureSioChan - configure USB keyboard for operation
*
* Selects the configuration/interface specified in the <pSioChan>
* structure.  These values come from the USBD dynamic attach callback,
* which in turn retrieved them from the configuration/interface
* descriptors which reported the device to be a keyboard.
*
* RETURNS: TRUE if successful, else FALSE if failed to configure channel
*
* ERRNO: none
*
*\NOMANUAL
*/

LOCAL BOOL configureSioChan
    (
    pUSB_KBD_SIO_CHAN pSioChan
    )

    {
    pUSB_CONFIG_DESCR pCfgDescr;
    pUSB_INTERFACE_DESCR pIfDescr;
    pUSB_ENDPOINT_DESCR pEpDescr;
    UINT8 * pBfr;
    UINT8 * pScratchBfr;
    UINT16 actLen;
    UINT16 ifNo;
    UINT16 maxPacketSize;

    if ((pBfr = OSS_MALLOC (USB_MAX_DESCR_LEN)) == NULL)
	return FALSE;

    /* Read the configuration descriptor to get the configuration selection
     * value and to determine the device's power requirements.
     */

    if (usbdDescriptorGet (usbdHandle, 
			   pSioChan->nodeId,
			   USB_RT_STANDARD | USB_RT_DEVICE, 
			   USB_DESCR_CONFIGURATION, 
			   0, 
			   0,
			   USB_MAX_DESCR_LEN, 
			   pBfr, 
			   &actLen) 
			 != OK)
	{
	OSS_FREE (pBfr);
	return FALSE;
	}


    if ((pCfgDescr = usbDescrParse (pBfr, 
				    actLen, 
				    USB_DESCR_CONFIGURATION)) 
				== NULL)
        {
        OSS_FREE (pBfr);
	return FALSE;
	}

    /* Look for the interface indicated in the pSioChan structure. */

    ifNo = 0;

    /* 
     * usbDescrParseSkip() modifies the value of the pointer it receives
     * so we pass it a copy of our buffer pointer
     */

    pScratchBfr = pBfr;

    while ((pIfDescr = usbDescrParseSkip (&pScratchBfr,
					  &actLen,
					  USB_DESCR_INTERFACE)) 
				    != NULL)
	{
	if (ifNo == pSioChan->interface)
	    break;
	ifNo++;
	}

    if (pIfDescr == NULL)
        {
        OSS_FREE (pBfr);
	return FALSE;
	}


    /* Retrieve the endpoint descriptor following the identified interface
     * descriptor.
     */

    if ((pEpDescr = usbDescrParseSkip (&pScratchBfr, 
				       &actLen, 
				       USB_DESCR_ENDPOINT))
	 			== NULL)
	{
	OSS_FREE (pBfr);
	return FALSE;
	}


    /* Select the configuration. */

    if (usbdConfigurationSet (usbdHandle, 
			      pSioChan->nodeId,
			      pCfgDescr->configurationValue, 
			      pCfgDescr->maxPower * USB_POWER_MA_PER_UNIT) 
			    != OK)
        {
        OSS_FREE (pBfr);
        return FALSE;
        }

    /* Select interface 
     * 
     * NOTE: Some devices may reject this command, and this does not represent
     * a fatal error.  Therefore, we ignore the return status.
     */

    usbdInterfaceSet (usbdHandle, 
		      pSioChan->nodeId, 
		      pSioChan->interface, 
		      pIfDescr->alternateSetting);


    /* Select the keyboard boot protocol. */

    if (usbHidProtocolSet (usbdHandle, 
			   pSioChan->nodeId,
			   pSioChan->interface, 
			   USB_HID_PROTOCOL_BOOT) 
			 != OK)
        {
        OSS_FREE (pBfr);
        return FALSE;
        }



    /* Set the keyboard idle time to infinite. */

    if (usbHidIdleSet (usbdHandle, 
		       pSioChan->nodeId,
		       pSioChan->interface, 
		       0 /* no report ID */, 
		       0 /* infinite */) 
		    != OK)
        {
        OSS_FREE (pBfr);
        return FALSE;
        }



    /* Turn off LEDs. */

    setLedReport (pSioChan, 0);


    /* Create a pipe to monitor input reports from the keyboard. */

    maxPacketSize = *((pUINT8) &pEpDescr->maxPacketSize) |
		    (*(((pUINT8) &pEpDescr->maxPacketSize) + 1) << 8);

    if (usbdPipeCreate (usbdHandle, 
			pSioChan->nodeId,     
			pEpDescr->endpointAddress, 
			pCfgDescr->configurationValue,    
			pSioChan->interface, 
			USB_XFRTYPE_INTERRUPT, 
			USB_DIR_IN,    
			maxPacketSize, 
			sizeof (HID_KBD_BOOT_REPORT), 
			pEpDescr->interval, 
			&pSioChan->pipeHandle) 
		     != OK)
        {
        OSS_FREE (pBfr);
        return FALSE;
        }



    /* Initiate IRP to listen for input on interrupt pipe */

    if (!initKbdIrp (pSioChan))
        {
        OSS_FREE (pBfr);
        return FALSE;
        }

    OSS_FREE (pBfr);


    return TRUE;
    }


/***************************************************************************
*
* destroyAttachRequest - disposes of an ATTACH_REQUEST structure
*
* This function disposes of an ATTACH_REQUEST structure.
*
* RETURNS: N/A
*
* ERRNO: none
*
*\NOMANUAL
*/

LOCAL VOID destroyAttachRequest
    (
    pATTACH_REQUEST pRequest
    )

    {
    /* Unlink request */

    usbListUnlinkProt (&pRequest->reqLink,kbdMutex);

    /* Dispose of structure */

    OSS_FREE (pRequest);
    }


/***************************************************************************
*
* destroySioChan - disposes of a USB_KBD_SIO_CHAN structure
*
* Unlinks the indicated USB_KBD_SIO_CHAN structure and de-allocates
* resources associated with the channel.
*
* RETURNS: N/A
*
* ERRNO: none
*
*\NOMANUAL
*/

LOCAL VOID destroySioChan
    (
    pUSB_KBD_SIO_CHAN pSioChan
    )

    {
    /* Unlink the structure. */

    usbListUnlinkProt (&pSioChan->sioLink,kbdMutex);


    /* Release pipe if one has been allocated.	Wait for the IRP to be
     * cancelled if necessary.
     */

    if (pSioChan->pipeHandle != NULL)
	usbdPipeDestroy (usbdHandle, pSioChan->pipeHandle);

    /* Release structure. */
    if (!pSioChan->irpInUse)
         {
         if (pSioChan->pBootReport != NULL)
	    OSS_FREE (pSioChan->pBootReport);

	    OSS_FREE (pSioChan);
         }

    }


/***************************************************************************
*
* createSioChan - creates a new USB_KBD_SIO_CHAN structure
*
* Creates a new USB_KBD_SIO_CHAN structure for the indicated <nodeId>.
* If successful, the new structure is linked into the sioList upon 
* return.
*
* <configuration> and <interface> identify the configuration/interface
* that first reported itself as a keyboard for this device.
*
* RETURNS: pointer to newly created structure, or NULL if failure
*
* ERRNO: none
*
*\NOMANUAL
*/

LOCAL pUSB_KBD_SIO_CHAN createSioChan
    (
    USBD_NODE_ID nodeId,
    UINT16 configuration,
    UINT16 interface
    )

    {
    pUSB_KBD_SIO_CHAN pSioChan;
    UINT16 i;


⌨️ 快捷键说明

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