📄 usbtcdpdiusbd12evallib.c
字号:
break; } /* Issue command to flush (clear) buffer */ d12ClearBfr (pTarget); }/***************************************************************************** d12WriteBfr - Issues Write Buffer command and writes buffer data** <pEndpoint> must point to the USB_TARG_ENDPOINT_INFO structure for the* endpoint. ** Writes the maximum packet size number of bytes from the next ERP bfrList[]* entry/entries to the indicated <endpoint>.** NOTE: This function automatically invokes d12ValidateBfr() after* writing data to the buffer.** RETURNS: N/A*/LOCAL VOID d12WriteBfr ( pTARGET pTarget, pUSB_TARG_ENDPOINT_INFO pEndpoint, pUSB_ERP pErp, pERP_WORKSPACE pWork ) { pUSB_BFR_LIST pBfrList; UINT16 bfrAvail; UINT16 numWrite; UINT16 i; /* Select the endpoint */ d12SelectEndpoint (pTarget, pEndpoint->endpointId); /* Sum the amount of data available in the bfrList[]. */ bfrAvail = pErp->bfrList [pWork->curBfr].bfrLen - pWork->curBfrOffset; for (i = pWork->curBfr + 1; i < pErp->bfrCount; i++) bfrAvail += pErp->bfrList [i].bfrLen; numWrite = min (pEndpoint->maxPacketSize, bfrAvail); /* Issue write buffer command */ OUT_D12_CMD (D12_CMD_WRITE_BUFFER); OUT_D12_DATA (0); OUT_D12_DATA (numWrite); /* Write buffer data */ pBfrList = &pErp->bfrList [pWork->curBfr]; for (i = 0; i < numWrite; i++) { OUT_D12_DATA (pBfrList->pBfr [pWork->curBfrOffset]); pBfrList->actLen++; if (++pWork->curBfrOffset == pBfrList->bfrLen) { pBfrList = &pErp->bfrList [++pWork->curBfr]; pWork->curBfrOffset = 0; } if (pWork->curBfr == pErp->bfrCount) break; } /* Mark buffer as filled (validate it) */ d12ValidateBfr (pTarget); }/***************************************************************************** d12SetEndpointStatus - Issues Set Endpoint Status command to PDIUSBD12** <endpoint> parameter must be D12_ENDPOINT_xxxx.** RETURNS: N/A*/LOCAL VOID d12SetEndpointStatus ( pTARGET pTarget, UINT16 endpoint, UINT8 status ) { OUT_D12_CMD (D12_CMD_SET_ENDPOINT_STATUS | endpoint); OUT_D12_DATA (status); }#if 0/***************************************************************************** d12ReadEndpointStatus - Issues Read Endpoint Status command to PDIUSBD12** <endpoint> parameter must be D12_ENDPOINT_xxxx.** RETURNS: UINT8 status value*/LOCAL UINT8 d12ReadEndpointStatus ( pTARGET pTarget, UINT16 endpoint ) { OUT_D12_CMD (D12_CMD_READ_ENDPOINT_STATUS | endpoint); return IN_D12_DATA (); }#endif /* #if 0 *//***************************************************************************** d12AckSetup - Issues Acknowledge setup command to PDIUSBD12** <endpoint> parameter must be D12_ENDPOINT_xxxx.** RETURNS: N/A*/LOCAL VOID d12AckSetup ( pTARGET pTarget, UINT16 endpoint ) { d12SelectEndpoint (pTarget, endpoint); OUT_D12_CMD (D12_CMD_ACK_SETUP); }/***************************************************************************** d12SendResume - Issues Send Resume commadn to PDIUSBD12** RETURNS: N/A*/LOCAL VOID d12SendResume ( pTARGET pTarget ) { OUT_D12_CMD (D12_CMD_SEND_RESUME); }/***************************************************************************** d12ReadCurrentFrameNumber - Issues Read Current Frame Number command** RETURNS: Current frame number returned by PDIUSBD12*/LOCAL UINT16 d12ReadCurrentFrameNumber ( pTARGET pTarget ) { UINT8 firstByte; OUT_D12_CMD (D12_CMD_READ_CURRENT_FRAME_NO); firstByte = IN_D12_DATA (); return firstByte | (IN_D12_DATA () << 8); }/***************************************************************************** d12ReadChipId - Issues Read Chip Id command** RETURNS: chip ID returned by PDIUSBD12*/LOCAL UINT16 d12ReadChipId ( pTARGET pTarget ) { UINT8 firstByte; OUT_D12_CMD (D12_CMD_READ_CHIP_ID); firstByte = IN_D12_DATA (); return firstByte | (IN_D12_DATA () << 8); }/***************************************************************************** finishErp - sets ERP result and invokes ERP callback** NOTE: This function also releases any DMA resources used by the ERP.** RETURNS: ERP result*/LOCAL int finishErp ( pTARGET pTarget, pUSB_ERP pErp, int result ) { /* unlink ERP */ usbListUnlink (&pErp->tcdLink); /* store result */ pErp->result = result; /* check/release DMA resources */ if (pTarget->dmaInUse && pTarget->pDmaErp == pErp) { pTarget->dmaInUse = FALSE; /* Disable the D12's DMA and re-enable interrupts for the endpoint */ pTarget->dmaByte &= ~D12_CMD_SD_DMA_ENABLE; if (pErp->endpointId == D12_ENDPOINT_2_OUT) pTarget->dmaByte |= D12_CMD_SD_ENDPT_2_OUT_INTRPT; else pTarget->dmaByte |= D12_CMD_SD_ENDPT_2_IN_INTRPT; d12SetDma (pTarget); } /* invoke callback */ if (pErp->targCallback != NULL) (*pErp->targCallback) (pErp); else if (pErp->userCallback != NULL) (*pErp->userCallback) (pErp); return result; }/***************************************************************************** cancelErp - Attempts to cancel an ERP** RETURNS: OK or S_usbTcdLib_xxxx if unable to cancel ERP*/LOCAL int cancelErp ( pTARGET pTarget, pUSB_ERP pErp ) { /* If the ERP has completed, then we can cancel it. */ if (pErp->result != 0) return S_usbTcdLib_CANNOT_CANCEL; /* Store the ERP completion status. */ finishErp (pTarget, pErp, S_usbTcdLib_ERP_CANCELED); return OK; }/***************************************************************************** stallEndpoint - mark an endpoint as stalled* RETURNS: N/A*/LOCAL VOID stallEndpoint ( pTARGET pTarget, UINT16 endpoint ) { d12SetEndpointStatus (pTarget, endpoint, D12_CMD_SES_STALLED); }/***************************************************************************** checkDma - Check if an ERP/endpoint is serviced by DMA and update accordingly** RETURNS: TRUE if ERP was handled, else FALSE if ERP requires non-DMA processing*/LOCAL BOOL checkDma ( pTARGET pTarget, pUSB_TARG_ENDPOINT_INFO pEndpoint, pUSB_ERP pErp, pERP_WORKSPACE pWork ) {#ifndef D12_USE_DMA return FALSE;#else /* #ifndef D12_USE_DMA */ UINT16 direction; /* Determine transfer direction based on endpoint in use */ direction = (pEndpoint->endpointId == D12_ENDPOINT_2_OUT) ? DMA_MEM_WRITE : DMA_MEM_READ; /* If this ERP/endpoint is using DMA, check for completion of the * ERP operation. */ if (pWork->dmaInUse && pTarget->dmaEot) { /* If this is a write to memory, copy from the temporary buffer. */ if (direction == DMA_MEM_WRITE) { USB_ISA_MEM_INVALIDATE ((char *) sysFdBuf, pWork->dmaXfrLen); memcpy (&pErp->bfrList [pWork->curBfr].pBfr [pWork->curBfrOffset], (char *) sysFdBuf, pWork->dmaXfrLen); } pWork->curBfrOffset += pWork->dmaXfrLen; /* Update the buffer counter. */ pErp->bfrList [pWork->curBfr].actLen += pWork->dmaXfrLen; if (pWork->curBfrOffset == pErp->bfrList [pWork->curBfr].bfrLen) { pWork->curBfr++; pWork->curBfrOffset = 0; } if (pWork->curBfr == pErp->bfrCount) { /* Mark the ERP as complete. */ finishErp (pTarget, pErp, OK); /* Automatically start the next ERP for this endpoint. */ processErpQueue (pTarget, pEndpoint->endpointId); return TRUE; } } /* If DMA has already been started for this ERP/endpoint, then continue * only if we've detected a DMA end-of-transfer */ if (pWork->dmaInUse && !pTarget->dmaEot) return TRUE; /* If this ERP/endpoint should use DMA, then initialize the dma. */ if (pTarget->dma != 0 && (pEndpoint->endpointId == D12_ENDPOINT_2_OUT || pEndpoint->endpointId == D12_ENDPOINT_2_IN) && (!pTarget->dmaInUse || pTarget->dmaEndpointId == pEndpoint->endpointId) && (pTarget->pDmaErp == NULL || pTarget->pDmaErp == pErp)) { /* Initialize DMA controller */ pWork->dmaXfrLen = min (pErp->bfrList [pWork->curBfr].bfrLen - pErp->bfrList [pWork->curBfr].actLen, sysFdBufSize); if (direction == DMA_MEM_READ) { memcpy ((char *) sysFdBuf, &pErp->bfrList [pWork->curBfr].pBfr [pWork->curBfrOffset], pWork->dmaXfrLen); USB_ISA_MEM_FLUSH ((char *) sysFdBuf, pWork->dmaXfrLen); } USB_ISA_DMA_SETUP (direction, sysFdBuf, pWork->dmaXfrLen, pTarget->dma); /* Initialize D12 for DMA operation */ pTarget->dmaByte &= ~D12_CMD_SD_DMA_DIRECTION_MASK; if (pEndpoint->endpointId == D12_ENDPOINT_2_OUT) { pTarget->dmaByte &= ~D12_CMD_SD_ENDPT_2_OUT_INTRPT; pTarget->dmaByte |= D12_CMD_SD_DMA_DIRECTION_READ; } else { pTarget->dmaByte &= ~D12_CMD_SD_ENDPT_2_IN_INTRPT; pTarget->dmaByte |= D12_CMD_SD_DMA_DIRECTION_WRITE; } pTarget->dmaByte |= D12_CMD_SD_DMA_ENABLE; d12SetDma (pTarget); /* Update state variables */ pWork->dmaInUse = TRUE; pTarget->dmaInUse = TRUE; pTarget->dmaEndpointId = pEndpoint->endpointId; pTarget->pDmaErp = pErp; pTarget->dmaEot = FALSE; /* throw away any pending transaction status for this endpoint. */ pTarget->transPending [pEndpoint->endpointId] = FALSE; return TRUE; } return FALSE;#endif /* ifndef D12_USE_DMA */ }/***************************************************************************** processInEndpoint - update an ERP for an IN endpoint** Tries to put data from an ERP to an endpoint. If successful, and if the* ERP is complete, then stores ERP status.** RETURNS: N/A*/LOCAL VOID processInEndpoint ( 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -