📄 usbtcdpdiusbd12evallib.c
字号:
** usbTcdPdiusbd12IntHandler - hardware interrupt handler** This is the actual routine which receives hardware interrupts from the* target controller. This routine immediately reflects the interrupt to * the usbTcdPdiusbd12IntThread. Interrupt handlers have execution * restrictions which are not imposed on normal threads...So, this scheme * gives the usbTcdPdiusbd12IntThread complete flexibility to call other * services and libraries while processing the interrupt condition.** RETURNS: N/A*/LOCAL VOID usbTcdPdiusbd12IntHandler ( pVOID param ) { pTARGET pTarget = (pTARGET) param; /* Is there an interrupt pending in the UHCI status reg? * * NOTE: INT_N is an active low signal. The interrupt is asserted * when INT_N == 0. */ if ((IN_EVAL_GIN () & D12EVAL_INTN) == 0) { pTarget->intCount++; /* A USB interrupt is pending. Disable interrupts until the * interrupt thread can process it. */ pTarget->goutByte &= ~D12EVAL_GOUT_INTENB; OUT_EVAL_GOUT (pTarget->goutByte); /* Signal the interrupt thread to process the interrupt. */ OSS_SEM_GIVE (pTarget->intPending); } }/***************************************************************************** cancelAllErps - Cancels all outstanding ERPs** RETURNS: N/A*/LOCAL VOID cancelAllErps ( pTARGET pTarget ) { UINT16 i; pUSB_ERP pErp; /* Cancel all pending ERPs */ for (i = 0; i < D12_NUM_ENDPOINTS; i++) { while ((pErp = usbListFirst (&pTarget->erps [i])) != NULL) { finishErp (pTarget, pErp, S_usbTcdLib_ERP_CANCELED); } } }/***************************************************************************** doDisable - Disable the target controller** Disables the target controller so it won't appear to be connected to* the USB.** RETURNS: N/A*/LOCAL VOID doDisable ( pTARGET pTarget ) { /* Cancel all outstanding ERPs. */ cancelAllErps (pTarget); /* Disable controller */ pTarget->configByte &= ~D12_CMD_SM_CFG_SOFTCONNECT; d12SetMode (pTarget); pTarget->enableFlag = DISABLE; d12SetAddress (pTarget); pTarget->goutByte &= ~ENABLE_LED; OUT_EVAL_GOUT (pTarget->goutByte); }/***************************************************************************** destroyTarget - tears down a TARGET structure** RETURNS: N/A*/LOCAL VOID destroyTarget ( pTARGET pTarget ) { if (pTarget) { /* Cancel all outstanding ERPs. */ cancelAllErps (pTarget); /* Disable interrupts, turn off LEDs */ if (pTarget->ioBase != 0) OUT_EVAL_GOUT (0); if (pTarget->intInstalled) USB_ISA_INT_RESTORE (usbTcdPdiusbd12IntHandler, pTarget, pTarget->irq); /* Shut down interrupt handler thread */ if (pTarget->intThread != NULL) { pTarget->intThreadExitRequest = TRUE; OSS_SEM_GIVE (pTarget->intPending); OSS_SEM_TAKE (pTarget->intThreadExit, INT_THREAD_EXIT_TIMEOUT); OSS_THREAD_DESTROY (pTarget->intThread); } if (pTarget->intPending != NULL) OSS_SEM_DESTROY (pTarget->intPending); if (pTarget->intThreadExit != NULL) OSS_SEM_DESTROY (pTarget->intThreadExit); /* Release target memory */ if (pTarget->pEndpoints != NULL) OSS_FREE (pTarget->pEndpoints); OSS_FREE (pTarget); } }/***************************************************************************** fncAttach - Executes TCD_FNC_ATTACH** This function initializes the target controller for operation.** RETURNS: OK or S_usbTcdLib_xxxx if an error is detected*/LOCAL int fncAttach ( pTRB_ATTACH pTrb ) { pUSB_TCD_PDIUSBD12_PARAMS pParams; pTARGET pTarget; pUSB_TARG_ENDPOINT_INFO pEndpoint; UINT16 i; /* Validate parameters */ if ((pParams = (pUSB_TCD_PDIUSBD12_PARAMS) pTrb->tcdParam) == NULL || pTrb->mngmtCallback == NULL) return S_usbTcdLib_BAD_PARAM; /* Create a TARGET structure to manage this target controller. */ if ((pTarget = OSS_CALLOC (sizeof (*pTarget))) == NULL || (pTarget->pEndpoints = OSS_CALLOC (sizeof (USB_TARG_ENDPOINT_INFO) * D12_NUM_ENDPOINTS)) == NULL || OSS_MUTEX_CREATE (&pTarget->tcdMutex) != OK || OSS_SEM_CREATE (1, 0, &pTarget->intPending) != OK || OSS_SEM_CREATE (1, 0, &pTarget->intThreadExit) != OK || OSS_THREAD_CREATE (usbTcdPdiusbd12IntThread, pTarget, OSS_PRIORITY_INTERRUPT, INT_THREAD_NAME, &pTarget->intThread) != OK) { destroyTarget (pTarget); return S_usbTcdLib_OUT_OF_RESOURCES; } pTarget->ioBase = pParams->ioBase; pTarget->irq = pParams->irq; pTarget->dma = pParams->dma; pTarget->mngmtCallback = pTrb->mngmtCallback; pTarget->mngmtCallbackParam = pTrb->mngmtCallbackParam; /* Initialize endpoint information */ /* default control OUT endpoint */ pEndpoint = &pTarget->pEndpoints [D12_ENDPOINT_CONTROL_OUT]; pEndpoint->endpointId = D12_ENDPOINT_CONTROL_OUT; pEndpoint->flags = TCD_ENDPOINT_OUT_OK | TCD_ENDPOINT_CTRL_OK; pEndpoint->endpointNumMask = 0x0001; /* endpoint #0 only */ pEndpoint->ctlMaxPacketSize = D12_MAX_PKT_CONTROL; /* default control IN endpoint */ pEndpoint = &pTarget->pEndpoints [D12_ENDPOINT_CONTROL_IN]; pEndpoint->endpointId = D12_ENDPOINT_CONTROL_IN; pEndpoint->flags = TCD_ENDPOINT_IN_OK | TCD_ENDPOINT_CTRL_OK; pEndpoint->endpointNumMask = 0x0001; /* endpoint #0 only */ pEndpoint->ctlMaxPacketSize = D12_MAX_PKT_CONTROL; /* bulk or interrupt OUT endpoint */ pEndpoint = &pTarget->pEndpoints [D12_ENDPOINT_1_OUT]; pEndpoint->endpointId = D12_ENDPOINT_1_OUT; pEndpoint->flags = TCD_ENDPOINT_OUT_OK | TCD_ENDPOINT_BULK_OK | TCD_ENDPOINT_INT_OK; pEndpoint->endpointNumMask = 0x0002; /* endpoint #1 only */ pEndpoint->bulkOutMaxPacketSize = D12_MAX_PKT_ENDPOINT_1; pEndpoint->bulkInOutMaxPacketSize = D12_MAX_PKT_ENDPOINT_1; pEndpoint->intOutMaxPacketSize = D12_MAX_PKT_ENDPOINT_1; pEndpoint->intInOutMaxPacketSize = D12_MAX_PKT_ENDPOINT_1; /* bulk or interrupt IN endpoint */ pEndpoint = &pTarget->pEndpoints [D12_ENDPOINT_1_IN]; pEndpoint->endpointId = D12_ENDPOINT_1_IN; pEndpoint->flags = TCD_ENDPOINT_IN_OK | TCD_ENDPOINT_BULK_OK | TCD_ENDPOINT_INT_OK; pEndpoint->endpointNumMask = 0x0002; /* endpoint #1 only */ pEndpoint->bulkInMaxPacketSize = D12_MAX_PKT_ENDPOINT_1; pEndpoint->bulkInOutMaxPacketSize = D12_MAX_PKT_ENDPOINT_1; pEndpoint->intInMaxPacketSize = D12_MAX_PKT_ENDPOINT_1; pEndpoint->intInOutMaxPacketSize = D12_MAX_PKT_ENDPOINT_1; /* main OUT endpoint: bulk, interrupt, or isochronous */ pEndpoint = &pTarget->pEndpoints [D12_ENDPOINT_2_OUT]; pEndpoint->endpointId = D12_ENDPOINT_2_OUT; pEndpoint->flags = TCD_ENDPOINT_OUT_OK | TCD_ENDPOINT_BULK_OK | TCD_ENDPOINT_INT_OK | TCD_ENDPOINT_ISOCH_OK; pEndpoint->bulkOutMaxPacketSize = D12_MAX_PKT_ENDPOINT_2_NON_ISO; pEndpoint->bulkInOutMaxPacketSize = D12_MAX_PKT_ENDPOINT_2_NON_ISO; pEndpoint->intOutMaxPacketSize = D12_MAX_PKT_ENDPOINT_2_NON_ISO; pEndpoint->intInOutMaxPacketSize = D12_MAX_PKT_ENDPOINT_2_NON_ISO; pEndpoint->isochOutMaxPacketSize = D12_MAX_PKT_ENDPOINT_2_ISO_OUT; pEndpoint->isochInOutMaxPacketSize = D12_MAX_PKT_ENDPOINT_2_ISO_IO; /* main IN endpoint: bulk, interrupt, or isochronous */ pEndpoint = &pTarget->pEndpoints [D12_ENDPOINT_2_IN]; pEndpoint->endpointId = D12_ENDPOINT_2_IN; pEndpoint->flags = TCD_ENDPOINT_IN_OK | TCD_ENDPOINT_BULK_OK | TCD_ENDPOINT_INT_OK | TCD_ENDPOINT_ISOCH_OK; pEndpoint->bulkInMaxPacketSize = D12_MAX_PKT_ENDPOINT_2_NON_ISO; pEndpoint->bulkInOutMaxPacketSize = D12_MAX_PKT_ENDPOINT_2_NON_ISO; pEndpoint->intInMaxPacketSize = D12_MAX_PKT_ENDPOINT_2_NON_ISO; pEndpoint->intInOutMaxPacketSize = D12_MAX_PKT_ENDPOINT_2_NON_ISO; pEndpoint->isochInMaxPacketSize = D12_MAX_PKT_ENDPOINT_2_ISO_IN; pEndpoint->isochInOutMaxPacketSize = D12_MAX_PKT_ENDPOINT_2_ISO_IO; /* Make sure the hardware is present */ if ((d12ReadChipId (pTarget) & D12_CHIP_ID_MASK) != D12_CHIP_ID) { pTarget->ioBase = 0; destroyTarget (pTarget); return S_usbTcdLib_HW_NOT_READY; } /* Initialize hardware */ /* disable eval board and address decoding */ OUT_EVAL_GOUT (0); /* turn OFF LEDs & interrupts */ pTarget->deviceAddress = 0; pTarget->enableFlag = DISABLE; d12SetAddress (pTarget); /* disable device */ d12SetEndpointEnable (pTarget, DISABLE); /* disable endpoints 1 & 2 */ /* Clear pending status. */ for (i = 0; i < D12_NUM_ENDPOINTS; i++) { d12SelectEndpoint (pTarget, i); d12ClearBfr (pTarget); d12ReadLastTransStatus (pTarget, i); d12ReadLastTransStatus (pTarget, i); } d12ReadIntReg (pTarget); /* Hook interrupts */ if (USB_ISA_INT_CONNECT (usbTcdPdiusbd12IntHandler, pTarget, pTarget->irq) != OK) { destroyTarget (pTarget); return S_usbTcdLib_INT_HOOK_FAILED; } pTarget->intInstalled = TRUE; /* continue initializing hardware */ /* set basic operating mode * * NOTE: Setting the "clock running" bit keeps the chip alive even during * suspend in order to facilitate debugging. In a production environment * where power device power consumption may be an issue, this bit should * not be set. */ pTarget->configByte = D12_CMD_SM_CFG_NO_LAZYCLOCK | D12_CMD_SM_CFG_CLOCK_RUNNING | D12_CMD_SM_CFG_MODE0_NON_ISO; pTarget->clkDivByte = D12_CMD_SM_CLK_DIV_DEFAULT | D12_CMD_SM_CLK_SET_TO_ONE; d12SetMode (pTarget); /* Set default DMA mode * * NOTE: Originally when writing this code I set the PDIUSBD12 for * single-cycle DMA mode. However, I noticed that the D12 would stop * asserting DRQ mid-transfer. In examining the Philips evaluation code, * I noticed that they only use "burst 16" DMA mode, and that appears * to work correct. -rcb */ pTarget->dmaByte = D12_CMD_SD_DMA_BURST_16 | D12_CMD_SD_ENDPT_2_OUT_INTRPT | D12_CMD_SD_ENDPT_2_IN_INTRPT; d12SetDma (pTarget); /* The following command enables interrupts. Since we're using an evaluation * board with some debug LEDs, we also turn on an "LED" to indicate that the * board is configured. */ pTarget->goutByte = ATTACH_LED | D12EVAL_GOUT_INTENB; OUT_EVAL_GOUT (pTarget->goutByte); /* Return target information to caller */ pTrb->header.handle = (TCD_HANDLE) pTarget; pTrb->speed = USB_SPEED_FULL; pTrb->numEndpoints = D12_NUM_ENDPOINTS; pTrb->pEndpoints = pTarget->pEndpoints; return OK; }/***************************************************************************** fncDetach - Executes TCD_FNC_DETACH** This function shuts down a target controller previously enabled by* calling fncAttach().** RETURNS: OK or S_usbTcdLib_xxxx if an error is detected*/LOCAL int fncDetach ( pTRB_DETACH pTrb, pTARGET pTarget ) { destroyTarget (pTarget); return OK; }/***************************************************************************** fncEnable - Enables a target channel** After a TCD has been attached/initialized, it still needs to be enabled* before the target controller will appear as a device on the USB. * Separating the enabling of the device into a separate step allows * additional device initialization to be performed before the device is* required to respond to requests from the host.** RETURNS: OK or S_usbTcdLib_xxxx if an error is detected*/LOCAL int fncEnable ( pTRB_ENABLE_DISABLE pTrb, pTARGET pTarget ) { pTarget->enableFlag = ENABLE; d12SetAddress (pTarget); pTarget->configByte |= D12_CMD_SM_CFG_SOFTCONNECT; d12SetMode (pTarget); pTarget->goutByte |= ENABLE_LED; OUT_EVAL_GOUT (pTarget->goutByte); return OK; }/***************************************************************************** fncDisable - Disables a target channel** This function disables the target controller from responding on the* USB as a device. ** RETURNS: OK or S_usbTcdLib_xxxx if an error is detected*/LOCAL int fncDisable ( pTRB_ENABLE_DISABLE pTrb, pTARGET pTarget ) { doDisable (pTarget); return OK; }/***************************************************************************** fncAddressSet - Sets the device (target) address** After fncAttach() the device defaults to USB address 0. This function* is generally invoked in response to a host request to assign a different* address to this device.** RETURNS: OK or S_usbTcdLib_xxxx if an error is detected*/LOCAL int fncAddressSet ( pTRB_ADDRESS_SET pTrb, pTARGET pTarget ) { pTarget->deviceAddress = pTrb->deviceAddress; d12SetAddress (pTarget); return OK; }/***************************************************************************** pickPacketSize - chooses packets size based on direction*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -