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

📄 usb.c

📁 有关ARM开发板上的IXP400网络驱动程序的源码以。
💻 C
📖 第 1 页 / 共 5 页
字号:
    if (UDCCS0 & UDC_UDCCS0_SST)    {        REG_SET(&registers->UDCCS0, UDC_UDCCS0_SST);    }    /* decode token */    ixUSBEP0TokenDecode(device);        if (ep0Control->currentToken == SETUP_TOKEN) /* SETUP active */    {        UINT32 offset = 0; /* setup packet offset */               controlWriteError = FALSE; /* reset control write error flag on SETUP token */        /* debug */        IX_USB_TRACE("::> SETUP\n", 0, 0, 0, 0, 0, 0);        /* increment SETUP counter */        context->counters.setup++;         if (ep0Control->state != IDLE)        {	    if (ep0Control->transferType == CONTROL_READ)	    {		crFailed++;		IX_USB_VERBOSE_WARN_TRACE("USB: SETUP token prematurely ended Control Read transaction\n",			  0, 0, 0, 0, 0, 0);            }	    else if (ep0Control->transferType == CONTROL_WRITE)            {		cwFailed++;		IX_USB_VERBOSE_WARN_TRACE("USB: SETUP token prematurely ended Control Write transaction\n",			   0, 0, 0, 0, 0, 0);            }            else if (ep0Control->transferType == CONTROL_NO_DATA)	    {		cnFailed++;		IX_USB_VERBOSE_WARN_TRACE("USB: SETUP token prematurely ended Control No Data transaction\n",			   0, 0, 0, 0, 0, 0);            }            else            {		IX_USB_VERBOSE_WARN_TRACE("USB: SETUP token in an *******>INVALID<******** transaction\n",			   0, 0, 0, 0, 0, 0);            }            /* SETUP occurred in the middle of another transaction, reset endpoint */            ixUSBEP0StateReset(device);            ixUSBEndpointClear(device, ENDPOINT_0);        }	IX_USB_VERBOSE4_TRACE("USB: control packet: ", 0, 0, 0, 0, 0, 0);        /* read packet */                /* tm - workaround for 0x81 sillicon bug (SA = 1, OPR = 1, RNE = 0) */        if ((REG_GET(&registers->UDCCS0) & UDC_UDCCS0_RNE) == 0)        {             /* ignore RNE, forcibly read 8 bytes */             for (offset = 0 ; offset < SETUP_PACKET_SIZE ; offset++)             {                  ep0Control->setupBuffer[offset] = DREG_GET(&registers->UDDR0);                    		          if (offset == 0 && (REG_GET(&registers->UDCCS0) & UDC_UDCCS0_RNE))                  {                      IX_USB_TRACE("USB: Oops, RNE came back up.\n", 0, 0, 0, 0, 0, 0);                  }             }        }        else        {          while (((REG_GET(&registers->UDCCS0) & UDC_UDCCS0_RNE) != 0) /* receive FIFO not empty */                  && (offset < SETUP_PACKET_SIZE))                     /* copy maximum 8 bytes */          {              ep0Control->setupBuffer[offset] = DREG_GET(&registers->UDDR0);              IX_USB_VERBOSE4_TRACE("0x%02x ", (unsigned char) ep0Control->setupBuffer[offset],              		   0, 0, 0, 0, 0);              offset++;          }        }   	/* we should exactly 8 bytes in the FIFO; if we have more then the incoming OUT	   token has rewritten the FIFO with a payload and we have to discard the setup */        if ((REG_GET(&registers->UDCCS0) & UDC_UDCCS0_RNE) != 0)        {            ixOsalLog (IX_OSAL_LOG_LVL_ERROR,                       IX_OSAL_LOG_DEV_STDERR,                         "USB: Control write error, there's still data in the EP0 FIFO:",		       0, 0, 0, 0, 0, 0);	    /* drain and discard FIFO */            while((REG_GET(&registers->UDCCS0) & UDC_UDCCS0_RNE) != 0)            {                 unsigned char extraData = (unsigned char) DREG_GET(&registers->UDDR0);		 ixOsalLog(IX_OSAL_LOG_LVL_WARNING,                           IX_OSAL_LOG_DEV_STDOUT,                           "0x%02x", extraData, 0, 0, 0, 0, 0);            }            /* indicate the error condition further in this transaction */            controlWriteError = TRUE;	}        /* a valid setup packet has exactly 8 bytes */        if (offset != SETUP_PACKET_SIZE)        {            IX_USB_VERBOSE_WARN_TRACE("Warning, did not read a full setup packet (8 expected, %d read)\n",             	      offset, 0, 0, 0, 0, 0);             /* mangled packet, clear OPR and SA, set IPR in case host follows with IN token - tm */            REG_SET(&registers->UDCCS0, (UDC_UDCCS0_OPR | UDC_UDCCS0_SA | UDC_UDCCS0_IPR));            ixUSBEP0StateReset(device);            ixUSBEndpointClear(device, ENDPOINT_0);            ixOsalMutexUnlock(&usbBufferSubmitMutex[0]);
            return;        }	if (controlWriteError)	{	/* we'll discard all incoming payload within this transaction */		ep0Control->expected = 0;		/* erase junk setup buffer to known values */		ep0Control->setupBuffer[0] = (unsigned char) 0xff;		ep0Control->setupBuffer[1] = (unsigned char) 0xff;		ep0Control->setupBuffer[2] = (unsigned char) 0xff;		ep0Control->setupBuffer[3] = (unsigned char) 0xff;		ep0Control->setupBuffer[4] = (unsigned char) 0xff;		ep0Control->setupBuffer[5] = (unsigned char) 0xff;		ep0Control->setupBuffer[6] = (unsigned char) 0xff;		ep0Control->setupBuffer[7] = (unsigned char) 0xff;	}	else	{		/* decode the transfer type and direction from packet */		ixUSBEP0SetupPacketDecode(device);	}	IX_USB_VERBOSE4_TRACE("Read SETUP packet, %d bytes\n", offset, 0, 0, 0, 0, 0);	/* show control stats */	IX_USB_TRACE("USB: Control read (%d/%d/%d)\n",		      crInitiated, crCompleted, crFailed, 0, 0, 0);	IX_USB_TRACE("USB: Control write (%d/%d/%d)\n",		      cwInitiated, cwCompleted, cwFailed, 0, 0, 0);	IX_USB_TRACE("USB: Control nodata (%d/%d)\n",		      cnInitiated, cnFailed, 0, 0, 0, 0);	/* reset transfer counter for data stage */	ep0Control->transferred = 0;	epData->transferAllowed = FALSE;	ixOsalMutexUnlock(&usbBufferSubmitMutex[0]);
	/* dispatch setup buffer */	if (context->eventProcessor.setupCallback != NULL)	{            IX_USB_TRACE("USB: Callback on 8 bytes SETUP packet\n",                          0, 0, 0, 0, 0, 0);	    context->eventProcessor.setupCallback(device, ep0Control->setupBuffer);	}	ixOsalMutexLock(&usbBufferSubmitMutex[0], IX_OSAL_WAIT_FOREVER);        /* clear OPR and SA */	REG_SET(&registers->UDCCS0, UDC_UDCCS0_OPR );	REG_SET(&registers->UDCCS0, UDC_UDCCS0_SA );        /* allow premature STATUS USB_IN on Control Write */        if (ep0Control->transferType == CONTROL_WRITE)        {            /* set IPR */            REG_SET(&registers->UDCCS0, UDC_UDCCS0_IPR);        }    	epData->transferAllowed = TRUE;	ixUSBEP0RequestSend(device);    }    else if (ep0Control->currentToken == OUT_TOKEN) /* USB_OUT token received */    {        /* debug */        IX_USB_TRACE("::> OUT\n", 0, 0, 0, 0, 0, 0);         /* debug sanity check */        if (ep0Control->transferType == CONTROL_READ && ep0Control->state != END_IN_XFER && ep0Control->state != ACTIVE_IN)        {            /* state machine in invalid mode */            IX_USB_TRACE("USB: internal error in state machine (current: %d)\n",                        ep0Control->state,            	       0, 0, 0, 0, 0);        }        if (ep0Control->state == END_IN_XFER)        {            /* consume token and set state machine to IDLE */            ixUSBEP0SendCleanup(device);            IX_USB_VERBOSE5_TRACE("::> UDCCS0 is 0x%02X on EXIT\n", UDCCS0, 0, 0, 0, 0, 0);            /* clear OPR */            REG_SET(&registers->UDCCS0, UDC_UDCCS0_OPR);	    ixOsalMutexUnlock(&usbBufferSubmitMutex[0]);
	    crCompleted++;                    ixUSBDataSendAllow(device);            return;        }        else if (ep0Control->state == ACTIVE_IN)        {            /* premature STATUS, host won't accept more data */            if (ep0Control->transferred == ep0Control->expected)            {                /* transfer was completed but no 0-length                   packet was sent */                ixUSBEP0SendCleanup(device);                crCompleted++;            }            else            {                /* ERROR, STATUS stage entered before transfer completion */                ixUSBEP0StateReset(device);                ixUSBEndpointClear(device, ENDPOINT_0);                crFailed++;            }            /* clear OPR */            REG_SET(&registers->UDCCS0, UDC_UDCCS0_OPR);            UDCCS0 = REG_GET(&registers->UDCCS0);            IX_USB_VERBOSE5_TRACE("::> UDCCS0 is 0x%02X on EXIT\n", UDCCS0, 0, 0, 0, 0, 0);	    ixOsalMutexUnlock(&usbBufferSubmitMutex[0]);
            return;        }        else if (ep0Control->state == IDLE) /* First USB_OUT packet */        {            ep0Control->state = ACTIVE_OUT;            IX_USB_VERBOSE5_TRACE("::> Beginning OUT transaction, %d bytes expected\n", ep0Control->expected, 0, 0, 0, 0, 0);                        /* alloc recv buffer */            epData->currentBuffer = ixUSBBufferAlloc(ep0Control->expected);        }        IX_USB_VERBOSE5_TRACE("::> Reading FIFO at offset %d\n", epData->currentOffset, 0, 0, 0, 0, 0);	if (controlWriteError)	{	    /* invalid transaction, drain FIFO and discard data */	    while ((REG_GET(&registers->UDCCS0) & UDC_UDCCS0_RNE) != 0)	    {	    *((unsigned char *)(IX_USB_MBLK_DATA(epData->currentBuffer) + epData->currentOffset))				= DREG_GET(&registers->UDDR0);	    epData->currentOffset++;	    }	}	else	{            /* read FIFO until RNE == 0, appending to recv buffer */            while ((REG_GET(&registers->UDCCS0) & UDC_UDCCS0_RNE) != 0     /* receive FIFO not empty */                	&& epData->currentOffset < ep0Control->expected) /* stop when all expected data was received */            {                *((unsigned char *)(IX_USB_MBLK_DATA(epData->currentBuffer) + epData->currentOffset)) = DREG_GET(&registers->UDDR0);                epData->currentOffset++;                ep0Control->transferred++;            }	}	IX_USB_TRACE("USB: => Read %d bytes so far in this control write, %d expected\n",		     ep0Control->transferred, ep0Control->expected, 0, 0, 0, 0);        /* check for end of transfer */        if (ep0Control->transferred == ep0Control->expected)        {            ep0Control->state = END_OUT_XFER;        }        /* allow USB_IN STATUS - set IPR */        REG_SET(&registers->UDCCS0, UDC_UDCCS0_IPR);        /* clear OPR */        REG_SET(&registers->UDCCS0, UDC_UDCCS0_OPR);        /* Check for end of transfer and ship data *before* status stage           WHY: Might miss the status stage which is signalled by an IN token */        if (ep0Control->transferred == ep0Control->expected)        {            ixUSBEP0DataDeliver(device);        }    }    else if (ep0Control->currentToken == IN_TOKEN) /* USB_IN token */    {        /* debug */        if (controlWriteError)        {            IX_USB_TRACE("::> IN\n", 0, 0, 0, 0, 0, 0);        }         if (ep0Control->state == ACTIVE_OUT)         {            /* Premature USB_IN stage */;            ixUSBEP0StateReset(device);            ixUSBEndpointClear(device, ENDPOINT_0);            crFailed ++;	    ixOsalMutexUnlock(&usbBufferSubmitMutex[0]);
            return;        }        else if (ep0Control->state == END_OUT_XFER)        {    	    ixOsalMutexUnlock(&usbBufferSubmitMutex[0]);
	    cwCompleted++;            /* Control Write ended, deliver data */            /* ixUSBEP0DataDeliver(device); */            return;        }        /* unlock FIFO for next packet */        epData->transferAllowed = TRUE;        ixUSBEP0RequestSend(device); /* send data, if available */    }    else    {        IX_USB_VERBOSE4_TRACE("::> UNKNOWN TOKEN", 0, 0, 0, 0, 0, 0);    }        ixOsalMutexUnlock(&usbBufferSubmitMutex[0]);
}/** * @fn PRIVATE void ixUSBEP0TokenDecode(USBDevice *device) * * @brief Decode the received USB token * * @param device USBDevice * (in) - structure identifying the device * * @return none * * Decodes the USB token received on endpoint 0 based on the * state of the <b>SA</b> (Setup Active) and <b>OPR</b> (USB_OUT Packet Ready) * bits of <b>UDCCS0</b> (endpoint 0 control/status register).<br> * The decoded value is placed in the <i>ep0ControlData.currentToken</i> * field, component of <i>device->deviceContext</i>. * * @internal */PRIVATE void ixUSBEP0TokenDecode(USBDevice *device){    EP0ControlData *ep0Data = EP0CONTROL(device);    UDCRegisters *registers = REGISTERS(device);    UINT32 UDCCS0           = REG_GET(&registers->UDCCS0);    BOOL SA                 = UDCCS0 & UDC_UDCCS0_SA;    BOOL OPR                = UDCCS0 & UDC_UDCCS0_OPR;    IX_USB_VERBOSE5_TRACE("::> Decode UDCCS0 is 0x%02X\n", UDCCS0, 0, 0, 0, 0, 0);      if (SA && OPR)    {        ep0Data->currentToken = SETUP_TOKEN;    }    else if (OPR) /* || RNE is a hack */    {        ep0Data->currentToken = OUT_TOKEN;    }    else    {        ep0Data->currentToken = IN_TOKEN;    }}/** * @fn PRIVATE void ixUSBEP0SetupPacketDecode(USBDevice *device) * * @brief Decode the received USB SETUP packet * * @param device USBDevice * (in) - structure identifying the device * * @return none * * Decodes the 8-byte SETUP packet received on endpoint 0, extracting * the expected transfer type and length for the data stage of the * ongoing control transaction.<br> * Populates the <i>expected</i> and <i>transferType</i> fields of * the device->deviceContext.ep0ControlData structure. * * @internal */PRIVATE void ixUSBEP0SetupPacketDecode(USBDevice *device){    EP0ControlData *ep0Data = EP0CONTROL(device);    USBSetupPacket *controlPacket;        controlPacket = (USBSetupPacket *) ep0Data->setupBuffer;    IX_USB_VERBOSE4_TRACE("SETUP packet:\n[%02x %02x %02x %02x",        ep0Data->setupBuffer[0],        ep0Data->setupBuffer[1],        ep0Data->setupBuffer[2],        ep0Data->setupBuffer[3],        0, 0);    IX_USB_VERBOSE4_TRACE(" %02x %02x %02x %02x]\n",        ep0Data->setupBuffer[4],        ep0Data->setupBuffer[5],        ep0Data->setupBuffer[6],        ep0Data->setupBuffer[7],        0, 0);    SWAP_USB_WORD(&controlPacket->wIndex);    SWAP_USB_WORD(&controlPacket->wLength);    SWAP_USB_WORD(&controlPacket->wValue);    /* debug */    IX_USB_VERBOSE4_TRACE("SETUP packet decoding:\n  bmRequestType 0x%02X, bRequest %02X, wValue %04X, wIndex %04X, wLength %04X\n",        controlPacket->bmRequestType,         controlPacket->bRequest,         controlPacket->wValue,         controlPacket->wIndex,         controlPacket->wLength,        0);    /* get expected transfer length */    ep0Data->expected = controlPacket->wLength;

⌨️ 快捷键说明

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