?? usb.c
字號:
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(®isters->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(®isters->UFNHR, UFNHR); } } else { events->eventCallback = ixUSBNullEventCallback; events->eventMap = USB_DEVICE_EVENTS; /* mask start of frame interrupts */ REG_SET(®isters->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(®isters->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(®isters->UDCCR); USIR0 = REG_GET(®isters->USIR0); USIR1 = REG_GET(®isters->USIR1); UFNHR = REG_GET(®isters->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(®isters->USIR0, UDCEPInterrupt[epPriority[epIndex]]); } } else { REG_SET(®isters->USIR1, UDCEPInterrupt[epPriority[epIndex]]); } } } /* clear serviced interrupts */ REG_SET(®isters->UDCCR, UDCCR); /* REG_SET(®isters->USIR0, USIR0); */ /* REG_SET(®isters->USIR1, USIR1); */ REG_SET(®isters->UFNHR, UFNHR);#ifdef __HWEMU__ /* the emulator allows more time for processing */ if (USIR0 != 0x01)#endif /* __HWEMU__ */ { REG_SET(®isters->USIR0, USIR0); }#ifdef __HWEMU__ if (USIR0 == 0x01) { REG_SET(®isters->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(®isters->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 + -