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

📄 usbtarglib.c

📁 VxWorks下USB驱动的源代码!
💻 C
📖 第 1 页 / 共 5 页
字号:
     * provided a statusGet handler.     */    if (pTcd->pCallbacks->statusGet == NULL)        return ERROR;    if ((*pTcd->pCallbacks->statusGet)        (pTcd->callbackParam, pTcd->targChannel,         pSetup->requestType, index,         min (length, sizeof (pTcd->dataBfr)), pTcd->dataBfr, &actLen) != OK) {        return ERROR;    }    /* Transmit the descriptor back to the host */    return initDataErpForResponse (pTcd, actLen);}/***************************************************************************** requestSetAddress - processes a SET_ADDRESS setup packet** RETURNS: OK if setup packet valid, else ERROR if invalid*/LOCAL STATUS requestSetAddress (pTARG_TCD pTcd, pUSB_SETUP pSetup){    UINT16 deviceAddress = FROM_LITTLEW (pSetup->value);    /* If the target application has provided a SetAddress callback,     * then invoke it now.     */    if (pTcd->pCallbacks->addressSet != NULL)        (*pTcd->pCallbacks->addressSet)            (pTcd->callbackParam, pTcd->targChannel, deviceAddress);    /* The new address goes into effect after the Status phase, if any. */    pTcd->deviceAddress = deviceAddress;    usbTcdAddressSet (&pTcd->tcdNexus, pTcd->deviceAddress);    return initStatusErp (pTcd, USB_PID_IN);}/***************************************************************************** requestGetSynchFrame - processes a GET_SYNCH_FRAME setup packet** RETURNS: OK if setup packet valid, else ERROR if invalid*/LOCAL STATUS requestGetSynchFrame (pTARG_TCD pTcd, pUSB_SETUP pSetup){    UINT16 endpoint = FROM_LITTLEW (pSetup->index);    /* This request isn't supported unless the target application has     * provided a synchFrameGet handler.     */    if (pTcd->pCallbacks->synchFrameGet == NULL)        return ERROR;    /* Get the synch frame from the target application. */    if ((*pTcd->pCallbacks->synchFrameGet)        (pTcd->callbackParam, pTcd->targChannel, endpoint, (pUINT16) pTcd->dataBfr) != OK)        return ERROR;    /* Transmit the synch frame back to the host */    return initDataErpForResponse (pTcd, sizeof (UINT16));}/***************************************************************************** requestVendorSpecific - processes a "vendor specific" setup packet** RETURNS: OK if setup packet valid, else ERROR if invalid*/LOCAL STATUS requestVendorSpecific (pTARG_TCD pTcd, pUSB_SETUP pSetup){    /* This request isn't supported unless the target application has     * provided a vendorSpecific handler.     */    if (pTcd->pCallbacks->vendorSpecific == NULL)        return ERROR;    return (*pTcd->pCallbacks->vendorSpecific)        (pTcd->callbackParam, pTcd->targChannel,         pSetup->requestType, pSetup->request, FROM_LITTLEW (pSetup->value),         FROM_LITTLEW (pSetup->index), FROM_LITTLEW (pSetup->length));}/***************************************************************************** parseSetupPacket - parse/execute a control pipe request** The TARGET.setupBfr should contain a setup packet.  Validate it.  If* valid, parse and execute it.** RETURNS: OK if setup packet valid, else ERROR if invalid*/LOCAL STATUS parseSetupPacket (pTARG_TCD pTcd){    pUSB_SETUP pSetup;    /* Validate the setup packet */    if (pTcd->setupErp.bfrList[0].actLen != sizeof (USB_SETUP))        return ERROR;    pSetup = (pUSB_SETUP) pTcd->setupBfr;    /* Execute based on the type of request. */    if ((pSetup->requestType & USB_RT_CATEGORY_MASK) == USB_RT_STANDARD) {        switch (pSetup->request) {        case USB_REQ_CLEAR_FEATURE:            return requestClearFeature (pTcd, pSetup);        case USB_REQ_SET_FEATURE:            return requestSetFeature (pTcd, pSetup);        case USB_REQ_GET_CONFIGURATION:            return requestGetConfiguration (pTcd, pSetup);        case USB_REQ_SET_CONFIGURATION:            return requestSetConfiguration (pTcd, pSetup);        case USB_REQ_GET_DESCRIPTOR:            return requestGetDescriptor (pTcd, pSetup);        case USB_REQ_SET_DESCRIPTOR:            return requestSetDescriptor (pTcd, pSetup);        case USB_REQ_GET_INTERFACE:            return requestGetInterface (pTcd, pSetup);        case USB_REQ_SET_INTERFACE:            return requestSetInterface (pTcd, pSetup);        case USB_REQ_GET_STATUS:            return requestGetStatus (pTcd, pSetup);        case USB_REQ_SET_ADDRESS:            return requestSetAddress (pTcd, pSetup);        case USB_REQ_GET_SYNCH_FRAME:            return requestGetSynchFrame (pTcd, pSetup);        default:            break;        }    }    return requestVendorSpecific (pTcd, pSetup);}/***************************************************************************** setupErpCallback - invoked when Setup ERP completes** This function receives control when a Setup ERP completes.  Examines the* reason for completion, possibly invoking additional control request* handling.** RETURNS: N/A*/LOCAL VOID setupErpCallback (pVOID p    /* ptr to ERP */    ){    pUSB_ERP pErp = (pUSB_ERP) p;    pTARG_TCD pTcd = (pTARG_TCD) pErp->userPtr;    pTcd->setupErpPending = FALSE;    /* Completion of a setup ERP, whether successful or not, implies that     * any previous control pipe request must be terminated. */    if (pTcd->dataErpPending)        cancelErp ((pTARG_PIPE) pTcd->dataErp.targPtr, &pTcd->dataErp);    if (pTcd->statusErpPending)        cancelErp ((pTARG_PIPE) pTcd->dataErp.targPtr, &pTcd->statusErp);    /* Was the ERP successful? */    if (pErp->result == OK) {        /* The ERP was successful.  Parse the setup packet. */        if (parseSetupPacket (pTcd) == OK) {            /* The packet can be parsed successfully.  Other code will             * take care of resubmitting the Setup ERP, so we do nothing.             */            return;        } else {            /* We cannot process the indicated command.  Stall the             * control pipe.             */            usbTargPipeStatusSet (pTcd->targChannel, pTcd->controlPipe, TCD_ENDPOINT_STALL);        }    }    /* Re-submit the ERP unless it was canceled - which indicates that     * the pipe is probably being torn down.     */    if (pErp->result != S_usbTcdLib_ERP_CANCELED)        initSetupErp (pTcd);}/***************************************************************************** responseErpCallback - invoked when control pipe response ERP completes** This function receives control after the data IN phase of a control pipe* request has completed.** RETURNS: N/A*/LOCAL VOID responseErpCallback (pVOID p /* ptr to ERP */    ){    pUSB_ERP pErp = (pUSB_ERP) p;    pTARG_TCD pTcd = (pTARG_TCD) pErp->userPtr;    pTcd->dataErpPending = FALSE;    /* If the ERP was successful, then we prepare the status phase.  The     * status phase is always in the oppposite direction to the data phase.     * Since this callback handles only "responses" (from device to host),     * then the status phase will always be an OUT (from host to device).     *     * If the data phase failed for some reason other than being canceled,     * then we resubmit the Setup phase ERP to ensure that the target     * continues to be responsive on the control pipe.     */    if (pErp->result == OK) {        initStatusErp (pTcd, USB_PID_OUT);        return;    }    if (pErp->result != S_usbTcdLib_ERP_CANCELED)        initSetupErp (pTcd);}/***************************************************************************** statusErpCallback - invoked when control pipe status packet completes** This function receives control after the status phase of a control pipe* request has completed.** RETURNS: N/A*/LOCAL VOID statusErpCallback (pVOID p   /* ptr to ERP */    ){    pUSB_ERP pErp = (pUSB_ERP) p;    pTARG_TCD pTcd = (pTARG_TCD) pErp->userPtr;    pTcd->statusErpPending = FALSE;    /* Re-submit the Setup ERP. */    if (pErp->result != S_usbTcdLib_ERP_CANCELED)        initSetupErp (pTcd);}/***************************************************************************** usbTargManagementCallback - invoked when TCD detects management event** This function is invoked by a TCD when the TCD detects a "management"* event on a target channel.  Examples of management events include* bus resets, detection of a new or lost connection, etc.** RETURNS: N/A*/LOCAL VOID usbTargManagementCallback (pVOID mngmtCallbackParam, /* caller-defined param */                                      TCD_HANDLE handle,    /* channel */                                      UINT16 mngmtCode  /* management code */    ){    pTARG_TCD pTcd = (pTARG_TCD) mngmtCallbackParam;    switch (mngmtCode) {    case TCD_MNGMT_VBUS_LOST:    case TCD_MNGMT_BUS_RESET:        /* Reset the device configuration to the power-on state. */        pTcd->deviceAddress = 0;        /* code falls through into following case */    case TCD_MNGMT_VBUS_DETECT:    case TCD_MNGMT_SUSPEND:    case TCD_MNGMT_RESUME:        /* reflect the management event to the target application */        mngmtFunc (pTcd, mngmtCode);        break;    }}/***************************************************************************** usbTargErpCallback - invoked when ERP completes** The TCD invokes this callback when an ERP completes.	This gives us the* opportunity to monitor ERP execution.  We reflect the callback to the* calling application after we finish our processing.** NOTE: By convention, the targPtr field of the ERP has been initialized* to point to the TARG_PIPE for this ERP.** RETURNS: N/A*/LOCAL VOID usbTargErpCallback (pVOID p  /* ptr to ERP */    ){    pUSB_ERP pErp = (pUSB_ERP) p;    pTARG_PIPE pPipe = (pTARG_PIPE) pErp->targPtr;    UINT16 packets;    UINT16 i;    OSS_MUTEX_TAKE (targMutex, OSS_BLOCK);    /* Unlink the ERP */    usbListUnlink (&pErp->targLink);    /* Check if this ERP is being deleted.  If so, let the foreground     * thread know the callback has been invoked.     */    if (pErp == pPipe->erpBeingDeleted)        pPipe->erpDeleted = TRUE;    /* Update data toggle for pipe.  Control and isochronous transfers     * always begin with DATA0, which is set at pipe initialization -     * so we don't change it here.  Bulk and interrupt pipes alternate     * between DATA0 and DATA1, and we need to keep a running track of     * the state across ERPs.     */    if (pErp->transferType == USB_XFRTYPE_INTERRUPT || pErp->transferType == USB_XFRTYPE_BULK) {        /* Calculate the number of packets exchanged to determine the         * next data toggle value.  If the count of packets is odd, then         * the data toggle needs to switch.         *         * NOTE: If the ERP is successful, then at least one packet MUST         * have been transferred.  However, it may have been a 0-length         * packet.  This case is handled after the following "for" loop.         */        packets = 0;        for (i = 0; i < pErp->bfrCount; i++) {            packets +=                (pErp->bfrList[i].actLen + pPipe->pEndpoint->maxPacketSize - 1) /                pPipe->pEndpoint->maxPacketSize;        }        if (pErp->result == OK)            packets = max (packets, 1);        if ((packets & 1) != 0)            pPipe->dataToggle = (pPipe->dataToggle == USB_DATA0) ? USB_DATA1 : USB_DATA0;    }    /* Invoke the user's callback routine */    if (pErp->userCallback != NULL)        (*pErp->userCallback) (pErp);    OSS_MUTEX_RELEASE (targMutex);}/***************************************************************************** usbTargVersionGet - Retrieve usbTargLib version** This function returns the usbTargLib version.  If <pVersion> is not NULL, the * usbTargLib returns its version in BCD in <pVersion>.	For example, version * "1.02" would be coded as 01h in the high byte and 02h in the low byte.** If <pMfg> is not NULL it must point to a buffer of at least USBT_NAME_LEN * bytes in length in which the USBD will store the NULL terminated name of* the usbTargLib manufacturer (e.g., "Wind River Systems" + \0).** RETURNS: OK*/STATUS usbTargVersionGet (pUINT16 pVersion, /* usbTargLib version */

⌨️ 快捷键说明

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