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

📄 usbtcdpdiusbd12evallib.c

📁 T2.0 USB driver.rar T2.0 USB driver.rar
💻 C
📖 第 1 页 / 共 5 页
字号:
    /* If this ERP is awaiting status, check the status.  If the ERP     * is not awaiting status, then the status must be stale, so     * discard it.      */    if (pTarget->transPending [pEndpoint->endpointId])	{	/* "consume" the last status read for this endpoint */	tStatus = pTarget->transStatus [pEndpoint->endpointId];	pTarget->transPending [pEndpoint->endpointId] = FALSE;	if (pWork->inStatusPending)	    {	    /* If the last transaction failed, fail the ERP. */#ifdef D12_CHECK_DATA_SUCCESS_BIT	    if ((tStatus & D12_CMD_RLTS_DATA_SUCCESS) == 0)		{		finishErp (pTarget, pErp, S_usbTcdLib_COMM_FAULT);		return;		}#endif /* #ifdef D12_CHECK_DATA_SUCCESS_BIT */	    pWork->inStatusPending = FALSE;	    /* Is the ERP complete? */	    if (pWork->curBfr == pErp->bfrCount ||		(pErp->bfrList [0].pBfr == NULL && pErp->bfrList [0].bfrLen == 0))		{		finishErp (pTarget, pErp, OK);		return;		}	    }	}    /* If the endpoint can accept data, put data into it now. */    if ((d12SelectEndpoint (pTarget, pErp->endpointId) &	D12_CMD_SE_FULL_EMPTY) != 0)	return;    d12WriteBfr (pTarget, pEndpoint, pErp, pWork);    pWork->inStatusPending = TRUE;    }/***************************************************************************** processOutEndpoint - update an ERP for an OUT endpoint** Validates data received by the device on an OUT endpoint and puts the* data into the indicated ERP.	If the ERP completes (successfully or with* an error), this function sets the ERP status.** RETURNS: N/A*/LOCAL VOID processOutEndpoint    (    pTARGET pTarget,    pUSB_TARG_ENDPOINT_INFO pEndpoint,    pUSB_ERP pErp,    pERP_WORKSPACE pWork    )    {    UINT8 tStatus;    /* Check if this ERP/endpoint is handled via DMA */    if (checkDma (pTarget, pEndpoint, pErp, pWork))	return;    /* Is there a pending transaction for this endpoint? */    if (!pTarget->transPending [pEndpoint->endpointId])	return;    /* Pick up the last status read for this endpoint */    tStatus = pTarget->transStatus [pEndpoint->endpointId];    /* Check the incoming data against the expected PID. */    if (pErp->transferType == USB_XFRTYPE_CONTROL)	{	if (((tStatus & D12_CMD_RLTS_SETUP_PACKET) != 0 &&	    pErp->bfrList [0].pid != USB_PID_SETUP) ||	    ((tStatus & D12_CMD_RLTS_SETUP_PACKET) == 0 && 	    pErp->bfrList [0].pid != USB_PID_OUT))	    {	    /* PID mismatch */	    stallEndpoint (pTarget, pEndpoint->endpointId);	    finishErp (pTarget, pErp, S_usbTcdLib_PID_MISMATCH);	    return;	    }	}        /* Now that we're sure we're processing the expected kind of packet,     * "consume" the endpoint status.     */    pTarget->transPending [pEndpoint->endpointId] = FALSE;    /* If this was a setup packet, let the D12 know we acknowledge it. */    if ((tStatus & D12_CMD_RLTS_SETUP_PACKET) != 0)	{	d12AckSetup (pTarget, D12_ENDPOINT_CONTROL_IN);	d12AckSetup (pTarget, D12_ENDPOINT_CONTROL_OUT);	}    /* Was the last transaction successful?  If not, fail the ERP. */#ifdef D12_CHECK_DATA_SUCCESS_BIT    if ((tStatus & D12_CMD_RLTS_DATA_SUCCESS) == 0)	{	finishErp (pTarget, pErp, S_usbTcdLib_COMM_FAULT);	return;	}#endif /* #ifdef D12_CHECK_DATA_SUCCESS_BIT */    /* Check the DATA0/DATA1 flag against the expected flag */    if (((tStatus & D12_CMD_RLTS_DATA1) == 0) != (pErp->dataToggle == USB_DATA0))	{	/* Data toggle mismatch */	stallEndpoint (pTarget, pEndpoint->endpointId);	finishErp (pTarget, pErp, S_usbTcdLib_DATA_TOGGLE_FAULT);	return;	}    pErp->dataToggle = (pErp->dataToggle == USB_DATA0) ? USB_DATA1 : USB_DATA0;    /* Read data into the ERP. */    d12ReadBfr (pTarget, pEndpoint, pErp, pWork);    /* Is the ERP complete? */    if (pWork->curBfr == pErp->bfrCount ||	(pErp->bfrList [0].pBfr == NULL && pErp->bfrList [0].bfrLen == 0))	{	finishErp (pTarget, pErp, OK);	}    }/***************************************************************************** processErpQueue - See if we can update the queue for an endpoint** This function examines the ERP queue for the specified <endpointId>.* If the queue can be updated - that is, if data can be transferred to/* from the queue or an error condition can be logged - then we update* the queue.** RETURNS: N/A*/LOCAL VOID processErpQueue    (    pTARGET pTarget,    UINT16 endpointId    )    {    pUSB_TARG_ENDPOINT_INFO pEndpoint = &pTarget->pEndpoints [endpointId];    pUSB_ERP pErp;    pERP_WORKSPACE pWork;        /* Process the next ERP */    if ((pErp = usbListFirst (&pTarget->erps [endpointId])) != NULL)	{	/* Get ERP_WORKSPACE for this ERP/endpoint. */	pWork = &pTarget->workspace [endpointId];    	if (!((BOOL) pErp->tcdPtr))	    {	    pErp->tcdPtr = (pVOID) TRUE;	    memset (pWork, 0, sizeof (*pWork));	    }	/* Fan-out based on OUT or IN endpoint. */	switch (pErp->endpointId)	    {	    case D12_ENDPOINT_CONTROL_OUT:	    case D12_ENDPOINT_1_OUT:	    case D12_ENDPOINT_2_OUT:		processOutEndpoint (pTarget, pEndpoint, pErp, pWork);		break;	    case D12_ENDPOINT_CONTROL_IN:	    case D12_ENDPOINT_1_IN:	    case D12_ENDPOINT_2_IN:		processInEndpoint (pTarget, pEndpoint, pErp, pWork);		break;	    }	}    else	{	/* There is an interrupt pending, but the ERP queue is empty.  If	 * this is the default control OUT pipe, and if the newly received	 * packet is a setup packet, then we need to abort any pending	 * transfers on the default control IN pipe.	 */	if (endpointId == D12_ENDPOINT_CONTROL_OUT &&	    pTarget->transPending [endpointId] &&	    (pTarget->transStatus [endpointId] & D12_CMD_RLTS_SETUP_PACKET) != 0 &&	    (pErp = usbListFirst (&pTarget->erps [D12_ENDPOINT_CONTROL_IN])) != NULL)	    {	    finishErp (pTarget, pErp, S_usbTcdLib_NEW_SETUP_PACKET);	    }	}    }/***************************************************************************** processErpQueueInt - Reads interrupt status and invokes processErpQueue()** RETURNS: N/A*/LOCAL VOID processErpQueueInt    (    pTARGET pTarget,    UINT16 endpointId    )    {    /* Select the endpoint and read the last transaction status.     *     * NOTE: Reading the transaction status clears the interrupt condition     * associated with a pipe.      */    pTarget->transStatus [endpointId] = 	d12ReadLastTransStatus (pTarget, endpointId);    pTarget->transPending [endpointId] = TRUE;    processErpQueue (pTarget, endpointId);    }/***************************************************************************** processBusReset - Processes a bus reset event** RETURNS: N/A*/LOCAL VOID processBusReset    (    pTARGET pTarget    )    {    UINT8 ginByte = IN_EVAL_GIN ();    /* The D12 has reported a bus reset. */    pTarget->deviceAddress = 0;     /* reverts to power-ON default */    /* Report the bus reset to our caller. */    MNGMT_CALLBACK (pTarget, TCD_MNGMT_BUS_RESET);    /* Follow-up by determining if Vbus is present or not */    if ((ginByte & D12EVAL_BUS_POWER) == 0)	MNGMT_CALLBACK (pTarget, TCD_MNGMT_VBUS_LOST);    else	MNGMT_CALLBACK (pTarget, TCD_MNGMT_VBUS_DETECT);    }/***************************************************************************** processSuspendChange - Interprets a change in the bus SUSPEND state** RETURNS: N/A*/LOCAL VOID processSuspendChange    (    pTARGET pTarget    )    {    UINT8 ginByte = IN_EVAL_GIN ();    /* The D12 has reported a change in the suspend state.  Reflect the     * current suspend state to the caller.     */    if ((ginByte & D12EVAL_SUSPEND) == 0)	MNGMT_CALLBACK (pTarget, TCD_MNGMT_RESUME);    else	MNGMT_CALLBACK (pTarget, TCD_MNGMT_SUSPEND);    }/***************************************************************************** processDmaEot - Handles a DMA end-of-transfer** RETURNS: N/A*/LOCAL VOID processDmaEot    (    pTARGET pTarget    )    {    /* The D12 reports that a DMA operation has completed. */    if (pTarget->dmaInUse)	{	pTarget->dmaEot = TRUE;	processErpQueue (pTarget, pTarget->dmaEndpointId);	}    }/***************************************************************************** processD12Int - evaluate and process an interrupt from the PDIUSBD12** RETURNS: N/A*/LOCAL VOID processD12Int    (    pTARGET pTarget    )    {    UINT16 intStatus;    /* Read interrupt status.     *     * NOTE: Reading the interrupt status clears interrupt conditions     * which are not associated with a specific pipe.     */    intStatus = d12ReadIntReg (pTarget);    /* Examine interrupt conditions.     *     * NOTE: Examine control endpoint last...at the end of a transaction,     * it is possible for a new setup packet to come in before we've     * handled the interrupt associated with the just-ended transaction.     */    if ((intStatus & D12_CMD_RIR_ENDPOINT_2_IN) != 0)	processErpQueueInt (pTarget, D12_ENDPOINT_2_IN);    if ((intStatus & D12_CMD_RIR_ENDPOINT_2_OUT) != 0)	processErpQueueInt (pTarget, D12_ENDPOINT_2_OUT);    if ((intStatus & D12_CMD_RIR_ENDPOINT_1_IN) != 0)	processErpQueueInt (pTarget, D12_ENDPOINT_1_IN);    if ((intStatus & D12_CMD_RIR_ENDPOINT_1_OUT) != 0)	processErpQueueInt (pTarget, D12_ENDPOINT_1_OUT);    if ((intStatus & D12_CMD_RIR_CONTROL_IN) != 0)	processErpQueueInt (pTarget, D12_ENDPOINT_CONTROL_IN);    if ((intStatus & D12_CMD_RIR_CONTROL_OUT) != 0)	processErpQueueInt (pTarget, D12_ENDPOINT_CONTROL_OUT);    if ((intStatus & D12_CMD_RIR_BUS_RESET) != 0)	processBusReset (pTarget);    if ((intStatus & D12_CMD_RIR_SUSPEND) != 0)	processSuspendChange (pTarget);    if ((intStatus & D12_CMD_RIR_DMA_EOT) != 0)	processDmaEot (pTarget);    }/***************************************************************************** usbTcdPdiusbd12IntThread - Handles PDIUSBD12 interrupts** This thread normally waits on the TARGET.intPending semaphore.  When* the semaphore is signalled, this thread interrogates the target controller* to determine the cause of the interrupt and serives it.** By convention, the <param> to this thread is a pointer to the TARGET* structure for this target controller.** When this thread exits, it signals the TARGET.intThreadExit semaphore* so the foreground thread can no that the thread has terminated successully.** RETURNS: N/A*/LOCAL VOID usbTcdPdiusbd12IntThread    (    pVOID param    )    {    pTARGET pTarget = (pTARGET) param;    UINT16 i;    do	{	/* Wait for an interrupt to be signalled. */	if (OSS_SEM_TAKE (pTarget->intPending, OSS_BLOCK) == OK)	    {	    if (!pTarget->intThreadExitRequest)		{		OSS_MUTEX_TAKE (pTarget->tcdMutex, OSS_BLOCK);		/* Light LED to indicate we're processing an interrupt */		pTarget->goutByte |= INT_THREAD_LED;		OUT_EVAL_GOUT (pTarget->goutByte);		/* Process the interrupt */		processD12Int (pTarget);		/* See if any queued ERPs need processing. */		for (i = 0; i < D12_NUM_ENDPOINTS; i++)		    {		    if (pTarget->endpointNeedsService [i])			{			pTarget->endpointNeedsService [i] = FALSE;			processErpQueue (pTarget, i);			}		    }		/* Re-enable interrupts. */		pTarget->goutByte &= ~INT_THREAD_LED;		pTarget->goutByte |= D12EVAL_GOUT_INTENB;		OUT_EVAL_GOUT (pTarget->goutByte);		OSS_MUTEX_RELEASE (pTarget->tcdMutex);		}	    }	}    while (!pTarget->intThreadExitRequest);    OSS_SEM_GIVE (pTarget->intThreadExit);    }/***************************************************************************

⌨️ 快捷键说明

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