?? usbtcdnet2280interrupt.c
字號:
{ if (pTarget->setupIntPending) { /* Setup Interrupt Pending */ USB_NET2280_DEBUG ("usbTcdNET2280FncInterruptStatusClear: Clearing \ Setup Interrupt bit\n", 0,0,0,0,0,0); NET2280_CFG_WRITE (pTarget, NET2280_IRQSTAT0_REG, NET2280_IRQENB0_SETUP); } if ((pTarget->endptIntPending) != 0) { /* * Endpoint related event is pending on some endpoint. Clear all * endpoint interrupt on which endpoint related events are pending */ } } USB_NET2280_DEBUG ("usbTcdNET2280FncInterruptStatusClear: Exiting...\n", 0,0,0,0,0,0); return OK; }/********************************************************************************* usbTcdNET2280FncEndpointIntStatusGet - implements TCD_FNC_ENDPOINT_INTERRUPT_STATUS_GET** This function returns the interrupt status on an endpoint.** RETURNS: OK or ERROR, if not able to get the endpoint interrupt status.** ERRNO:* \is* \i S_usbTcdLib_BAD_PARAM.* Bad parameter is passed.* \ie** \NOMANUAL*/LOCAL STATUS usbTcdNET2280FncEndpointIntStatusGet ( pTRB_ENDPOINT_INTERRUPT_STATUS_GET pTrb /* TRB to be executed */ ) { pTRB_HEADER pHeader = (pTRB_HEADER) pTrb; /* TRB_HEADER */ pUSB_TCD_NET2280_TARGET pTarget = NULL; /* USB_TCD_NET2280_TARGET */ pUSB_TCD_NET2280_ENDPOINT pEndpointInfo = NULL;/*USB_TCD_NET2280_ENDPOINT*/ UINT8 endpointIndex = 0; /* endpoint index */ UINT8 direction = 0; /* direction */ UINT32 data32 = 0; /* WindView Instrumentation */ USB_TCD_LOG_EVENT(USB_TCD_NET2280_INTERRUPT, "usbTcdNET2280FncEndpointIntStatusGet entered.", USB_TCD_NET2280_WV_FILTER); USB_NET2280_DEBUG ("usbTcdNET2280FncEndpointIntStatusGet: Entered...\n", 0,0,0,0,0,0); /* Validate Parameters */ if ((pHeader == NULL) || (pHeader->trbLength < sizeof (TRB_HEADER)) || (pHeader->handle == NULL) || (pTrb->pipeHandle == 0)) { /* WindView Instrumentation */ USB_TCD_LOG_EVENT(USB_TCD_NET2280_INTERRUPT, "usbTcdNET2280FncEndpointIntStatusGet exiting:Bad Parameter Received.", USB_TCD_NET2280_WV_FILTER); USB_NET2280_ERROR ("usbTcdNET2280FncEndpointIntStatusGet: \ Bad Parameters...\n",0,0,0,0,0,0); return ossStatus (S_usbTcdLib_BAD_PARAM); } pTarget = (pUSB_TCD_NET2280_TARGET) pHeader->handle; pEndpointInfo = (pUSB_TCD_NET2280_ENDPOINT)pTrb->pipeHandle; /* Determine the endpoint index and direction */ endpointIndex = pEndpointInfo->endpointIndex; direction = pEndpointInfo->direction; /* update TRB :: uEndptInterruptStatus to 0 */ pTrb->uEndptInterruptStatus = 0; if ((endpointIndex == NET2280_ENDPT_0_OUT) && (pTarget->setupIntPending)) { /* setup interrupt */ /* Set bits 0 and bit 1 of TRB :: uEndptInterruptStatus ot 1 */ pTrb->uEndptInterruptStatus |= USBTCD_ENDPOINT_INTERRUPT_PENDING_MASK | USBTCD_ENDPOINT_SETUP_PID_MASK; return OK; }#ifdef NET2280_DMA_SUPPORTED /* Check if an interrupt has occured for dma endpoints A, B, C or D */ if ((endpointIndex == NET2280_ENDPT_A) || (endpointIndex == NET2280_ENDPT_B) || (endpointIndex == NET2280_ENDPT_C) || (endpointIndex == NET2280_ENDPT_D)) { /* Check if there is a dma eot interrupt for this endpoint */ if ((pTarget->dmaEot & (1 << endpointIndex)) != 0) { /* read the direction bit of DMACNT register */ if ((NET2280_CFG_READ (pTarget, NET2280_DMACOUNT_OFFSET (endpointIndex)) & NET2280_DMACOUNT_DIR) != 0) { /* * DMA Transfer occured on IN endpoint, update * TRB :: uEndptInterruptStatus accordingly */ pTrb->uEndptInterruptStatus |= USBTCD_ENDPOINT_INTERRUPT_PENDING_MASK | USBTCD_ENDPOINT_IN_PID_MASK; } else { /* * DMA Transfer occured on OUT endpoint, update * TRB :: uEndptInterruptStatus accordingly */ pTrb->uEndptInterruptStatus |= USBTCD_ENDPOINT_INTERRUPT_PENDING_MASK | USBTCD_ENDPOINT_OUT_PID_MASK; } return OK; } /* * This condition will be successful in the following cases * DMA OUT : short packet is received. * DMA IN : Dma transfer completed before USB data transfer. */ else if (((pTarget->endptIntPending & (1 << endpointIndex)) != 0) && pEndpointInfo->dmaInUse) { if (direction == USB_TCD_ENDPT_OUT) { pTrb->uEndptInterruptStatus = USBTCD_ENDPOINT_INTERRUPT_PENDING_MASK | USBTCD_ENDPOINT_OUT_PID_MASK | USBTCD_ENDPOINT_DATA_UNDERRUN; pTarget->dmaEot |= (1 << endpointIndex); pTarget->endptIntPending &= ~(1 << endpointIndex); /* Read the endpoint interrupt status */ data32 = NET2280_CFG_READ (pTarget, NET2280_EP_STAT_OFFSET(endpointIndex)); /* Short packet will be cleared in copydatafrom() */ data32 &= ~NET2280_EP_STAT_NAKOUT; /* Clear all the interrupts */ NET2280_CFG_WRITE (pTarget, NET2280_EP_STAT_OFFSET(endpointIndex), data32); } else /* Endpoint direction is IN */ { pTrb->uEndptInterruptStatus = USBTCD_ENDPOINT_INTERRUPT_PENDING_MASK | USBTCD_ENDPOINT_IN_PID_MASK; pTarget->dmaEot |= (1 << endpointIndex); pTarget->endptIntPending &= ~(1 << endpointIndex); } return OK; } }#endif if ((pTarget->endptIntPending & (1 << endpointIndex)) != 0) { /* * Check for direction and update TRB :: uEndptInterruptStatus with * proper mask */ if (direction == USB_TCD_ENDPT_IN) { /* IN INTERRUPT on the endpoint */ pTrb->uEndptInterruptStatus |= USBTCD_ENDPOINT_INTERRUPT_PENDING_MASK | USBTCD_ENDPOINT_IN_PID_MASK; /* Clear the endptIntPending bit */ pTarget->endptIntPending &= ~(1 << endpointIndex); /* * Endpoint 0 IN and OUT use the same register. * So update the index to be used for register access. */ if (endpointIndex == NET2280_ENDPT_0_IN) endpointIndex = 0; /* * Read the contents of the EP_STAT register. * Some specific short packet handling is required for OUT endpoints. * This is the reason for reading this register contents here. */ data32 = NET2280_CFG_READ (pTarget, NET2280_EP_STAT_OFFSET(endpointIndex)); /* Clear the data packet received and transmitted interrupts */ data32 &= ~(NET2280_EP_STAT_DPT | NET2280_EP_STAT_DPR); /* Clear all the interrupts */ NET2280_CFG_WRITE (pTarget, NET2280_EP_STAT_OFFSET(endpointIndex), data32); } else if (direction == USB_TCD_ENDPT_OUT) { /* To store temporarily some register values */ UINT32 dataTemp = 0; /* OUT INTERRUPT of the endpoint */ pTrb->uEndptInterruptStatus |= USBTCD_ENDPOINT_INTERRUPT_PENDING_MASK | USBTCD_ENDPOINT_OUT_PID_MASK; /* Clear the endptIntPending bit */ pTarget->endptIntPending &= ~(1 << endpointIndex); /* * Read the contents of the EP_STAT register. * Some specific short packet handling is required for OUT endpoints. * This is the reason for reading this register contents here. */ data32 = NET2280_CFG_READ (pTarget, NET2280_EP_STAT_OFFSET(endpointIndex)); /* * Clear the interrupts other than data packet received * and transmitted interrupts */ data32 &= ~(NET2280_EP_STAT_DPT | NET2280_EP_STAT_DPR);#ifdef NET2280_DMA_SUPPORTED /* Clear all the interrupts other than short packet interrupt */ NET2280_CFG_WRITE (pTarget, NET2280_EP_STAT_OFFSET(endpointIndex), (data32 & ~NET2280_EP_STAT_NAKOUT)); #else /* Clear all the interrupts */ NET2280_CFG_WRITE (pTarget, NET2280_EP_STAT_OFFSET(endpointIndex), data32); #endif /* Read EP_AVAIL register */ dataTemp = NET2280_CFG_READ (pTarget, NET2280_EP_AVAIL_OFFSET (endpointIndex)); /* * Copy the data in the FIFO which is to be copied * to the HAL buffer */ pEndpointInfo->dataLength = dataTemp; /* * There are high chances that between the duration of reading * the EP_STAT register and EP_AVAIL register, there is a short * packet detected. If we do not do the following handling, * there is a chance that we have copied the * entire data, but the HAL does not know that it is the end of * transfer. The following piece of code handles this case. */ /* * We need not indicate to HAL a short packet, if the * data available is less than max packetsize. */ if (pEndpointInfo->dataLength > pEndpointInfo->maxPacketSize) { /* * Check if a short packet is already detected. ie, the EP_STAT * value read earlier indicates a short packet. * Note:NET2280_EP_STAT_NAKOUT mask indicates a short packet * occurance. Once this bit is set, the target controller * cannot accept more data. Only if this bit is cleared by * TCD, it can accept more data. If this bit is set here, * we have already read the complete data length. * If it is not set, read the EP_STAT register again to check if * there is any short packet. */ if ((data32 & NET2280_EP_STAT_NAKOUT) == 0) { dataTemp = NET2280_CFG_READ (pTarget, NET2280_EP_STAT_OFFSET(endpointIndex)); /* * If the NAKOUT bit is set, then we need to copy the * complete size of data for the transfer. */ if ((dataTemp & NET2280_EP_STAT_NAKOUT)!= 0) { pEndpointInfo->dataLength = NET2280_CFG_READ (pTarget, NET2280_EP_AVAIL_OFFSET (endpointIndex)); } /* * Clear the interrupts other than data packet transmitted * and received interrupts. */ dataTemp &= ~(NET2280_EP_STAT_DPT | NET2280_EP_STAT_DPR);#ifdef NET2280_DMA_SUPPORTED /* Clear the contents other than short packet */ NET2280_CFG_WRITE (pTarget, NET2280_EP_STAT_OFFSET(endpointIndex), (dataTemp & ~NET2280_EP_STAT_NAKOUT)); #else /* Clear the contents of the EP_STAT register */ NET2280_CFG_WRITE (pTarget, NET2280_EP_STAT_OFFSET(endpointIndex), dataTemp); #endif /* * As data32 will be used further down the line, * update the data32 value
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -