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

📄 usb.c

📁 有关ARM开发板上的IXP400网络驱动程序的源码以。
💻 C
📖 第 1 页 / 共 5 页
字号:
    /* get transfer type */    if (ep0Data->expected == 0)    {        /* no data stage */        ep0Data->transferType = CONTROL_NO_DATA;        cnInitiated++;    }    else    {        /* there's data, check direction */        if ((controlPacket->bmRequestType & UDC_DIRECTION_MASK) == USB_REQ_DIR_DEVICE_TO_HOST)        {            /* USB_IN transfer */            ep0Data->transferType = CONTROL_READ;            crInitiated++;        }        else        {            /* USB_OUT transfer */            ep0Data->transferType = CONTROL_WRITE;            cwInitiated++;                    }    }}/** * @fn PRIVATE void ixUSBEP0StateReset(USBDevice *device) * * @brief Reset the state of endpoint 0 * * @param device USBDevice * (in) - structure identifying the device * * @return none * * Resets the state of endpoint 0: *      - resets the endpoint 0 state machine *      - resets the current transfer indicators and buffers * * @internal */PRIVATE void ixUSBEP0StateReset(USBDevice *device){    EP0ControlData *ep0Control = EP0CONTROL(device);    /* reset state machine */    ep0Control->state = IDLE;    /* clear control transfer traffic counters */    ep0Control->transferred = 0;    ep0Control->expected    = 0;    /* clear transfer type */    ep0Control->transferType = UNKNOWN_TRANSFER;    /* clear active token type */    ep0Control->currentToken = UNKNOWN_TOKEN;    /* clear current SETUP packet */    ixOsalMemSet(ep0Control->setupBuffer, 0, SETUP_PACKET_SIZE);}/** * @fn PRIVATE void ixUSBEP0RequestSend(USBDevice *device) * * @brief Service send requests for endpoint 0 * * @param device USBDevice * (in) - structure identifying the device * * @return none * * Fills the endpoint 0 FIFO, triggers device Tx, updates counters and * the endpoint 0 state machine when servicing send requests. * * @internal */PRIVATE void ixUSBEP0RequestSend(USBDevice *device){    USBDeviceContext *context       = CONTEXT(device);    EPStatusData *epData            = &context->epStatusData[ENDPOINT_0];    UDCRegisters *registers         = context->registers;    EP0ControlData *ep0Control      = &context->ep0ControlData;#ifdef IX_USB_HAS_CRITICAL_DATA_LOCKS    UINT32 irqStatus;#endif /* IX_USB_HAS_CRITICAL_DATA_LOCKS */#ifdef IX_USB_HAS_CRITICAL_DATA_LOCKS	/* EnterCriticalSection(&device->usbCriticalSection); */     irqStatus = IX_USB_IRQ_LOCK;#endif /* IX_USB_HAS_CRITICAL_DATA_LOCKS */	if (epData->currentBuffer == NULL)	{		if (ixUSBBufferDequeue(epData))		{			/* set state machine status */			ep0Control->state = ACTIVE_IN;		}		else		{#ifdef IX_USB_HAS_CRITICAL_DATA_LOCKS			/* queue is empty */ 			IX_USB_IRQ_UNLOCK(irqStatus);#endif /* IX_USB_HAS_CRITICAL_DATA_LOCKS */			return;		}	}    if (epData->transferAllowed && epData->currentBuffer != NULL)    {        unsigned int sendIndex;        /* disable FIFO filling until the packet is shipped */        epData->transferAllowed = FALSE;#ifdef IX_USB_HAS_CRITICAL_DATA_LOCKS        IX_USB_IRQ_UNLOCK(irqStatus);#endif /* IX_USB_HAS_CRITICAL_DATA_LOCKS */        epData->currentTransferSize = MIN(epData->fifoSize, IX_USB_MBLK_LEN(epData->currentBuffer) - epData->currentOffset);        /* fill FIFO from send buffer */        for (sendIndex = 0 ; sendIndex < epData->currentTransferSize ; sendIndex++)        {            UCHAR fifoData   = *(UCHAR *)(IX_USB_MBLK_DATA(epData->currentBuffer) + epData->currentOffset);            UINT32 fifoWData = fifoData;            DREG_SET(&registers->UDDR0, fifoWData);            epData->currentOffset++;            ep0Control->transferred++;        }        if (epData->currentTransferSize < epData->fifoSize) /* short packet? */        {            ep0Control->state = END_IN_XFER;        }        /* set IPR */        REG_SET(&registers->UDCCS0, UDC_UDCCS0_IPR);        		{		UINT32 IPR = REG_GET(&registers->UDCCS0) & UDC_UDCCS0_IPR;		do		{			IPR = REG_GET(&registers->UDCCS0) & UDC_UDCCS0_IPR;		} while (IPR);		REG_SET(&registers->USIR0, 1);		ixUSBIPRset = 1;	}	IX_USB_VERBOSE4_TRACE("USB:=>Wrote %d so far in this read transaction out of %d [buffer 0x%08x offset %d]\n",		   ep0Control->transferred,		   IX_USB_MBLK_LEN(epData->currentBuffer),		   (UINT32)epData->currentBuffer,		   epData->currentOffset,                    0, 0);    }    else    {#ifdef IX_USB_HAS_CRITICAL_DATA_LOCKS        IX_USB_IRQ_UNLOCK(irqStatus);#endif /* IX_USB_HAS_CRITICAL_DATA_LOCKS */    }}/** * @fn PRIVATE void ixUSBEP0SendCleanup(USBDevice *device) * * @brief Finalize and clean up Tx transactions on endpoint 0 * * @param device USBDevice * (in) - structure identifying the device * * @return none * * Finalizes a control transfer: *      - sets endpoint 0 state machine to <b>IDLE</b> *      - increments Tx counters *      - frees sent buffer * * @internal */PRIVATE void ixUSBEP0SendCleanup(USBDevice *device){    USBDeviceContext *context = CONTEXT(device);    EPStatusData *epData      = &context->epStatusData[ENDPOINT_0];    /* increment sent counters */    epData->counters.Tx++;     epData->counters.bytesTx += IX_USB_MBLK_LEN(epData->currentBuffer);    context->counters.Tx++;    context->counters.bytesTx += IX_USB_MBLK_LEN(epData->currentBuffer);    /* free send buffer */    IX_USB_MBLK_FREE(context->epStatusData[ENDPOINT_0].currentBuffer);    /* reset transfer data */    epData->currentBuffer       = NULL;    epData->currentOffset       = 0;    epData->currentTransferSize = 0;    /* reset endpoint 0 state */    ixUSBEP0StateReset(device);    /* unlock FIFO */    epData->transferAllowed = TRUE;}/** * @fn PRIVATE void ixUSBEP0DataDeliver(USBDevice *device) * * @brief Finalize and dispatch data for Rx transactions on endpoint 0 * * @param device USBDevice * (in) - structure identifying the device * * @return none * * Sets the endpoint 0 state machine to IDLE, updates counters * and delivers incoming data by calling the registered client Rx callback. * * @internal */PRIVATE void ixUSBEP0DataDeliver(USBDevice *device){    USBDeviceContext *context = CONTEXT(device);    EPStatusData *epData      = &context->epStatusData[ENDPOINT_0];    context->ep0ControlData.state = IDLE; /* set state machine to idle */    /* increment receive counters */    epData->counters.Rx++;     epData->counters.bytesRx += IX_USB_MBLK_LEN(epData->currentBuffer);    context->counters.Rx++;    context->counters.bytesRx += IX_USB_MBLK_LEN(epData->currentBuffer);    if (IX_USB_MBLK_LEN(epData->currentBuffer))    {	/* dispatch data - client is required to free buffer */        IX_USB_VERBOSE4_TRACE("USB: Build 1003: Callback on EP0, %d bytes\n",                   IX_USB_MBLK_LEN(epData->currentBuffer),                   0, 0, 0, 0, 0);    	context->eventProcessor.receiveCallback(device, ENDPOINT_0, epData->currentBuffer);    }    else    {        IX_USB_VERBOSE4_TRACE("USB: Build 1003: Ignoring 0 bytes payload\n",                    0, 0, 0, 0, 0, 0);        IX_USB_MBLK_FREE(epData->currentBuffer);    }    /* reset transfer data */    epData->currentBuffer       = NULL;    epData->currentOffset       = 0;    epData->currentTransferSize = 0;}/** * @fn PRIVATE void ixUSBQueueDiscard(EPStatusData *epData) * * @brief Discard and free the data queue of an endpoint * * @param epData EPStatusData * (in) - structure identifying the endpoint * * @return none * * Frees the endpoint data queue (used only for Tx) and updates the * endpoint counters. * * @internal */PRIVATE voidixUSBQueueDiscard(EPStatusData *epData){    USBDataQueue *queue = &(epData->queue);    UINT32 local_index;#ifdef IX_USB_HAS_CRITICAL_DATA_LOCKS    UINT32 irqStatus;    /* USBDevice *device = epData->device; */    irqStatus = IX_USB_LOCK;#endif /* IX_USB_HAS_CRITICAL_DATA_LOCKS */    for (local_index = 0 ; local_index < queue->len ; local_index++)    {        UINT32 offset = QUEUE_WRAP(queue->head + local_index);        IX_USB_MBLK_FREE(queue->base[offset]);        queue->base[offset] = NULL;    }    /* update counters - queues are actually used only for Tx */    epData->counters.DTx += epData->queue.len;    COUNTERS(epData->device)->DTx += epData->queue.len;    queue->head = 0;    queue->len  = 0;#ifdef IX_USB_HAS_CRITICAL_DATA_LOCKS    IX_USB_UNLOCK(irqStatus);#endif /* IX_USB_HAS_CRITICAL_DATA_LOCKS */}/** * @fn PRIVATE void ixUSBQueueInit(EPStatusData *epData) * * @brief Initialize the data queue of an endpoint * * @param epData EPStatusData * (in) - structure identifying the endpoint * * @return none * * @internal */PRIVATE voidixUSBQueueInit(EPStatusData *epData){    epData->queue.head = 0;    epData->queue.len  = 0;    ixOsalMemSet(epData->queue.base, 0, MAX_QUEUE_SIZE * sizeof (IX_USB_MBLK *));}/** * @fn PRIVATE BOOL ixUSBBufferEnqueue(EPStatusData *epData, IX_USB_MBLK *buf) * * @brief Add a buffer to an endpoint data queue * * @param epData EPStatusData * (in) - structure identifying the endpoint * @param buf IX_USB_MBLK * (in) - buffer to enqueue * * @return <b>TRUE</b> if the buffer was successfully queued and  * <b>FALSE</b> otherwise (if the queue is full) * * @internal */PRIVATE BOOL ixUSBBufferEnqueue(EPStatusData *epData, IX_USB_MBLK *buf){    USBDataQueue *queue = &(epData->queue);    BOOL result;#ifdef IX_USB_HAS_CRITICAL_DATA_LOCKS    /* lock section */    /* USBDevice *device = epData->device; */    UINT32 irqStatus = IX_USB_LOCK;#endif /* IX_USB_HAS_CRITICAL_DATA_LOCKS */    if (queue->len < MAX_QUEUE_SIZE)    {        UINT32 tail = QUEUE_WRAP(queue->head + queue->len);        queue->base[tail] = buf;        queue->len++;        result = TRUE;    }    else    {        result = FALSE; /* queue is full */    }#ifdef IX_USB_HAS_CRITICAL_DATA_LOCKS    IX_USB_UNLOCK(irqStatus);#endif /* IX_USB_HAS_CRITICAL_DATA_LOCKS */    return result;}/** * @fn PRIVATE BOOL ixUSBBufferDequeue(EPStatusData *epData) * * @brief Moves the top buffer from the endpoint queue into the * current transaction slot * * @param epData EPStatusData * (in) - structure identifying the endpoint * * @return <b>TRUE</b> if the dequeueing was completed successfully and * <b>FALSE</b> otherwise (if the queue is empty) * * @internal */PRIVATE BOOL ixUSBBufferDequeue(EPStatusData *epData){    USBDataQueue *queue = &(epData->queue);    UINT32 lock;    lock = IX_USB_LOCK;    /* NULL buffer pointers can exist in the queue if buffers are cancelled */    /* retry until a non-NULL buffer pointer is extracted or queue becomes empty */    while (TRUE)    {        if (queue->len > 0)        {            epData->currentBuffer = queue->base[queue->head];            /* remove entry from queue */            queue->base[queue->head] = NULL;            queue->len--;            queue->head = QUEUE_WRAP(queue->head + 1);            if (epData->currentBuffer != NULL)            {               epData->currentOffset = 0;  	         	       IX_USB_UNLOCK(lock);               return TRUE;            }        }        else        {	    IX_USB_UNLOCK(lock);        	            return FALSE; /* queue is empty */        }    }     IX_USB_UNLOCK(lock);}/** * @fn PRIVATE void ixUSBRequestSend(EPStatusData *epData) * * @brief Service send requests for USB_IN endpoints * * @param epData EPStatusData * (in) - structure identifying the endpoint * * @return none * * Fills the endpoint FIFO and triggers UDC send.<br> * If transactioning is enabled it also automatically sends  * end-of-transfer short packets.<br> * Checks transaction timeouts if compiled with <b>IX_USB_HAS_TIMESTAMP_CHECKS</b>. * * @internal

⌨️ 快捷键说明

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