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

📄 usb.c

📁 有关ARM开发板上的IXP400网络驱动程序的源码以。
💻 C
📖 第 1 页 / 共 5 页
字号:
                           USBEventCallback eventCallback,                            USBEventMap eventMap){    USBEventProcessor *events;    UDCRegisters *registers;    CHECK_DEVICE(device);    CHECK_EVENT_MASK(device, eventMap);    events    = EVENTS(device);    registers = REGISTERS(device);    if (eventCallback != NULL)    {        UINT32 UFNHR = REG_GET(&registers->UFNHR);        BOOL sofMaskSet     = (UFNHR & UDC_UFNHR_SIM) != 0;        BOOL sofMaskDesired = (eventMap & USB_SOF) == 0;        events->eventCallback = eventCallback;        events->eventMap      = eventMap;        /* check if we need to switch the SOF mask */        if (sofMaskSet != sofMaskDesired)        {            if (sofMaskDesired)            {                /* set mask */                UFNHR = UDC_UFNHR_SIM;            }            else            {                /* unset mask (this will enable SOF interrupts) */                UFNHR = UFNHR & ~UDC_UFNHR_SIM;            }            REG_SET(&registers->UFNHR, UFNHR);        }    }    else    {        events->eventCallback = ixUSBNullEventCallback;        events->eventMap      = USB_DEVICE_EVENTS;        /* mask start of frame interrupts */        REG_SET(&registers->UFNHR, UDC_UFNHR_SIM);    }    RETURN_OK(device);}#ifdef IX_USB_HAS_STATISTICS_SHOWPUBLIC IX_STATUS ixUSBStatisticsShow(USBDevice *device){    USBDeviceCounters *devCounters;    BOOL deviceEnabled;    UDCRegisters *registers;#ifdef IX_USB_STATS_SHOW_PER_ENDPOINT_INFO    UINT16 epIndex;#endif /* IX_USB_STATS_SHOW_PER_ENDPOINT_INFO */    CHECK_DEVICE(device);    devCounters   = COUNTERS(device);    deviceEnabled = CONTEXT(device)->enabled;    registers     = REGISTERS(device);    /* device info */
    printf("USB controller %d (I/O %x, IRQ %d) - %s, %s, %d irqs, %d frames\n",
            device->deviceIndex,
            device->baseIOAddress,
            device->interruptLevel,
            deviceEnabled ? "enabled" : "disabled",
            (REG_GET(&registers->UDCCR) & UDC_UDCCR_UDA) ? "active" : "inactive",
            devCounters->irqCount,
            devCounters->frames);

    /* device stats */
    printf("packets Tx %d, Rx %d, dropped Tx %d, Rx %d - bytes Tx %d, Rx %d - setup %d\n",
            devCounters->Tx,
            devCounters->Rx,
            devCounters->DTx,
            devCounters->DRx,
            devCounters->bytesTx,
            devCounters->bytesRx,
            devCounters->setup);
#ifdef IX_USB_STATS_SHOW_PER_ENDPOINT_INFO

    printf("\n");

    /* endpoint stats - table header */    printf("ep |   packets |   dropped |     bytes | irqs | flags   | FIFO o/u\n");
    printf("   |  Tx    Rx |  Tx    Rx |   Tx   Rx |      |         |\n");
    /* endpoint info */    for (epIndex = ENDPOINT_0 ; epIndex < NUM_ENDPOINTS ; epIndex++)    {        USBEndpointCounters *epCounters = EPCOUNTERS(device, epIndex);        BOOL stallState;        ixUSBIsEndpointStalled(device, epIndex, &stallState);

        printf("%2d | %3d%s %3d%s | %3d%s %3d%s | %3d%s %3d%s | %4d | %s | %3d%s %3d%s\n",
                epIndex,
                SHOW_NUMBER(epCounters->Tx), SHOW_METRIC(epCounters->Tx),
                SHOW_NUMBER(epCounters->Rx), SHOW_METRIC(epCounters->Rx),
                SHOW_NUMBER(epCounters->DTx), SHOW_METRIC(epCounters->DTx),
                SHOW_NUMBER(epCounters->DRx), SHOW_METRIC(epCounters->DRx),
                SHOW_NUMBER(epCounters->bytesTx), SHOW_METRIC(epCounters->bytesTx),
                SHOW_NUMBER(epCounters->bytesRx),  SHOW_METRIC(epCounters->bytesRx),                epCounters->irqCount,
                EP_TYPE(EPDescriptorTable[epIndex]) == USB_ISOCHRONOUS ? "    N/A" : stallState ? "stalled" : " active",
                SHOW_NUMBER(epCounters->fifoOverflows), SHOW_METRIC(epCounters->fifoOverflows),                SHOW_NUMBER(epCounters->fifoUnderruns), SHOW_METRIC(epCounters->fifoUnderruns));
    }#endif /* IX_USB_STATS_SHOW_PER_ENDPOINT_INFO */    RETURN_OK(device);}#endif /* IX_USB_HAS_STATISTICS_SHOW */PRIVATE UINT32 ixUSBIrqRead(void){    UINT32 intPending;    if(ixUSBIrqCtrlRegVirtAddr == 0)    {        ixOsalLog(IX_OSAL_LOG_LVL_ERROR,                  IX_OSAL_LOG_DEV_STDERR,                  "Irq Control Registers is not mem map\n",                  0, 0, 0 ,0 ,0 ,0);        return 0;    }        /**     * Get the interrupt control register content.      * The register is mem map in ixUSBDriverInit.      */    intPending = IX_OSAL_READ_LONG(ixUSBIrqCtrlRegVirtAddr);    return intPending;}/** * @} addtogroup USBDriver *//** * @addtogroup SupportAPI * @{ */PRIVATE void ixUSBInterruptHandlerWrapper(USBDevice *device){    UINT32 intPend     = 0;    UINT32 maxCount    = 0xFF;    UINT32 ep0Activity = 0;    intPend = ixUSBIrqRead();    if (! (intPend & (1 << IX_OSAL_IXP400_INT_LVL_USB)))    {        IX_USB_VERBOSE_WARN_TRACE("Arrived in ixUSBInterruptHandlerWrapper but no interrupt\n",   		  0, 0, 0, 0, 0, 0);        return;    }    while ((intPend & (1 << IX_OSAL_IXP400_INT_LVL_USB)) && maxCount)    {        ep0Activity = ixUSBInterruptHandler(device);        --maxCount;        intPend = ixUSBIrqRead();        intPend = ixUSBIrqRead();        intPend = ixUSBIrqRead();    }    if (maxCount == 0)    {        IX_USB_VERBOSE2_TRACE("Leaving ixUSBInterruptHandlerWrapper after 0xffff iterations\n", 	             0, 0, 0, 0, 0, 0);    }}/** * @fn PRIVATE UINT32 ixUSBInterruptHandler(USBDevice *device) * * @brief Main interrupt handler * * @param device USBDevice * (in) - structure identifying the device * * Takes a snapshot of the USB status registers and analyzes the * source of the interrupt, calling the appropriate handler. * Depending on the event that caused the interrupt this can be * the endpoint 0 interrupt handler, USB_IN/USB_OUT interrupt handlers * or the client event callback.<br> * UDC interrupts are disabled during the execution of this function * as the handler and its support functions are not reentrant. * * @return none * * @internal */ /*Note:         UDCCR     - UDC Control Register    USIR0     - UDC Interrupt and Status Register 0    USIR1     - UDC Interrupt and Status Register 1    UFNHR     - UDC Frame Number High Register */static INT32 ixUSBIPRset = 0;PRIVATE UINT32 ixUSBInterruptHandler(USBDevice *device){    UINT16 epIndex;    UINT32 eventSet    = USB_NO_EVENT;    UINT32 ep0Activity = 0;    USBDeviceContext *context      = CONTEXT(device);    UDCRegisters *registers        = context->registers;    USBEventCallback eventCallback = context->eventProcessor.eventCallback;    USBEventMap eventMap           = context->eventProcessor.eventMap;    UINT32 UDCCR; /* device control/status register */    UINT32 USIR0; /* endpoints 0..7 interrupt status */    UINT32 USIR1; /* endpoints 8..15 interrupt status */    UINT32 UFNHR; /* device frame number high register (contains SOF IRQ) */#ifdef IX_USB_HAS_CRITICAL_DATA_LOCKS    /* disable interrupts */    UINT32 irqStatus;    irqStatus = IX_USB_IRQ_LOCK;#endif /* IX_USB_HAS_CRITICAL_DATA_LOCKS */    /* read UDCCR, UISR0, UISR1, UFNHR */    UDCCR = REG_GET(&registers->UDCCR);    USIR0 = REG_GET(&registers->USIR0);    USIR1 = REG_GET(&registers->USIR1);    UFNHR = REG_GET(&registers->UFNHR);    ixUSBIPRset = 0;    if ((UDCCR | USIR0 | USIR1) == 0)    {        IX_USB_VERBOSE2_TRACE("USB: Oops, servicing interrupt with no events\n",                   0, 0, 0, 0, 0, 0);    }    /* debug */    IX_USB_VERBOSE3_TRACE("Int handler: UDCCR %2X, USIR0 %2X, USIR1 %2X, UFNHR %2X\n",                  UDCCR, USIR0, USIR1, UFNHR, 0, 0);    /* device IRQ counter */    context->counters.irqCount++;    /* Reset? */    if (UDCCR & UDC_UDCCR_RSTIR)    {        eventSet |= USB_RESET;        /* perform driver reset */                /* clear endpoint information */        for (epIndex = ENDPOINT_0 ; epIndex < NUM_ENDPOINTS ; epIndex++)        {            ixUSBEndpointClear(device, epIndex);        }        /* reset endpoint 0 state */        ixUSBEP0StateReset(device);    }    /* Suspend? */    if (UDCCR & UDC_UDCCR_SUSIR)    {        eventSet |= USB_SUSPEND;    }    /* Resume? */    if (UDCCR & UDC_UDCCR_RESIR)    {        eventSet |= USB_RESUME;    }    /* Start of frame? */    if (UFNHR & UDC_UFNHR_SIR)    {        eventSet |= USB_SOF;        /* device frame counter */        context->counters.frames++;    }    if ((eventCallback != NULL) && ((eventMap & eventSet) != 0))    {        eventCallback(device, eventSet);    }    /* Endpoint interrupt handling */    for (epIndex = ENDPOINT_0 ; epIndex < NUM_ENDPOINTS ; epIndex++)    {        UINT32 intReg = (epPriority[epIndex] < ENDPOINT_8) ? USIR0 : USIR1;                if (((intReg & UDCEPInterrupt[epPriority[epIndex]]) != 0))        {            EPStatusData *epData = &(context->epStatusData[epPriority[epIndex]]);            ep0Activity = (epPriority[epIndex] == 0);            /* endpoint IRQ count */            epData->counters.irqCount++;            /* debug */            IX_HWEMU_TRACE("USB::ixUSBInterruptHandler(): servicing endpoint %d\n",                   epIndex, 0, 0, 0, 0, 0);            /* service endpoint */            EPInterruptHandlerTable[epPriority[epIndex]](epData);            /* clear endpoint interrupt bit */            if (epPriority[epIndex] < ENDPOINT_8  )            {                if (epPriority[epIndex] != 0 || ixUSBIPRset == 0)                {                    REG_SET(&registers->USIR0, UDCEPInterrupt[epPriority[epIndex]]);                }            }            else            {                REG_SET(&registers->USIR1, UDCEPInterrupt[epPriority[epIndex]]);            }            ixUSBIPRset = 0;        }    }    /* clear serviced interrupts */    REG_SET(&registers->UDCCR, UDCCR);    /* REG_SET(&registers->USIR0, USIR0); */    /* REG_SET(&registers->USIR1, USIR1); */    REG_SET(&registers->UFNHR, UFNHR);#ifdef __HWEMU__ /* the emulator allows more time for processing */    if (USIR0 != 0x01)#endif /* __HWEMU__ */    {        REG_SET(&registers->USIR0, USIR0);    }#ifdef __HWEMU__    if (USIR0 == 0x01)     {        REG_SET(&registers->USIR0, USIR0);    }#endif /* __HWEMU__ */#ifdef IX_USB_HAS_CRITICAL_DATA_LOCKS    IX_USB_IRQ_UNLOCK(irqStatus);#endif /* IX_USB_HAS_CRITICAL_DATA_LOCKS */    return ep0Activity;}/** * @fn PRIVATE void ixUSBINInterruptHandler(EPStatusData *epData) * * @brief Interrupt handler for USB_IN endpoints * * @param epData EPStatusData * (in) - structure identifying the endpoint * * Interrupt handler for USB_IN endpoints. Is is called after a packet was * sent to the host. Calls ixUSBSendCleanup() to release outgoing * buffers and service the next transfer. * * @return none * * @internal */PRIVATE void ixUSBINInterruptHandler(EPStatusData *epData){    ixUSBSendCleanup(epData);}/** * @fn PRIVATE void ixUSBOUTInterruptHandler(EPStatusData *epData) * * @brief Interrupt handler for USB_OUT endpoints * * @param epData EPStatusData * (in) - structure identifying the endpoint * * @return none * * Interrupt handler for USB_OUT endpoints. Services Rx host requests by calling * ixUSBReceiveProcess(). * * @internal */PRIVATE void ixUSBOUTInterruptHandler(EPStatusData *epData){    ixUSBReceiveProcess(epData);}/** * @fn PRIVATE void ixUSBEP0InterruptHandler(EPStatusData *epData) * * @brief Interrupt handler for endpoint 0 * * @param epData EPStatusData * (in) - structure identifying the endpoint * * @return none * * The endpoint 0 interrupt handler analyzes and updates the endpoint 0 * state machine while taking appropriate actions to ensure Tx/Rx * on the control endpoint.<br> * Interacts with client code by calling the <i>setup receive</i> callback. * * @internal */PRIVATE void ixUSBEP0InterruptHandler(EPStatusData *epData){    USBDevice *device          = epData->device;    USBDeviceContext *context  = CONTEXT(device);    UDCRegisters *registers    = context->registers;    EP0ControlData *ep0Control = &context->ep0ControlData;    UINT32 UDCCS0              = REG_GET(&registers->UDCCS0);    static UINT32 controlWriteError = FALSE;    IX_HWEMU_TRACE("Ep0 handler: UDCCS0 is 0x%08X\n", UDCCS0, 0, 0, 0, 0, 0);    IX_USB_VERBOSE3_TRACE("::> UDCCS0 is 0x%02X\n", UDCCS0, 0, 0, 0, 0, 0);    ixOsalMutexLock(&usbBufferSubmitMutex[0], IX_OSAL_WAIT_FOREVER);        /* clear sent stall bit unless endpoint 0 doesn't unstall itself */

⌨️ 快捷键说明

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