VOID HandleDeviceEvent ( WDFDEVICE WdfDevice, DEVICE_EVENT DeviceEvent ) /*++ Routine Description: Function to dispatch device events from the controller. Arguments: WdfDevice - Wdf device object corresponding to the FDO DeviceEvent - Device specific event. --*/ { PCONTROLLER_CONTEXT ControllerContext; TraceEntry(); ControllerContext = DeviceGetControllerContext(WdfDevice); switch (DeviceEvent) { case DeviceEventDisconnect: ControllerContext->Suspended = FALSE; HandleUsbDisconnect(WdfDevice); break; case DeviceEventUSBReset: ControllerContext->Suspended = FALSE; HandleUsbReset(WdfDevice); break; case DeviceEventConnect: HandleUsbConnect(WdfDevice); break; case DeviceEventUSBLinkStateChange: HandleUSBLinkStateChange(WdfDevice); break; case DeviceEventWakeUp: if (ControllerContext->Suspended) { ControllerContext->Suspended = FALSE; UfxDeviceNotifyResume(ControllerContext->UfxDevice); } break; case DeviceEventSuspend: if (!ControllerContext->Suspended) { ControllerContext->Suspended = TRUE; UfxDeviceNotifySuspend(ControllerContext->UfxDevice); } break; default: TraceError("Unknown device event raised by controller"); NT_ASSERT(FALSE); break; } TraceExit(); }
/** USB interrupt handler @todo Get all 11 bits of frame number instead of just 8 Endpoint interrupts are mapped to the slow interrupt */ void USB_IRQHandler(void) { uint32_t dwStatus; uint32_t dwIntBit; uint8_t bEPStat, bDevStat, bStat; int i; uint16_t wFrame; // handle device interrupts dwStatus = LPC_USB->USBDevIntSt; // frame interrupt if (dwStatus & FRAME) { // clear int LPC_USB->USBDevIntClr = FRAME; // call handler if (_pfnFrameHandler != NULL) { wFrame = USBHwCmdRead(CMD_DEV_READ_CUR_FRAME_NR); _pfnFrameHandler(wFrame); } } // device status interrupt if (dwStatus & DEV_STAT) { /* Clear DEV_STAT interrupt before reading DEV_STAT register. This prevents corrupted device status reads, see LPC2148 User manual revision 2, 25 july 2006. */ LPC_USB->USBDevIntClr = DEV_STAT; bDevStat = USBHwCmdRead(CMD_DEV_STATUS); if (bDevStat & (CON_CH | SUS_CH | RST)) { // convert device status into something HW independent bStat = ((bDevStat & CON) ? DEV_STATUS_CONNECT : 0) | ((bDevStat & SUS) ? DEV_STATUS_SUSPEND : 0) | ((bDevStat & RST) ? DEV_STATUS_RESET : 0); // call handler HandleUsbReset(bStat); } } // endpoint interrupt if (dwStatus & EP_SLOW) { // clear EP_SLOW LPC_USB->USBDevIntClr = EP_SLOW; // check all endpoints for (i = 0; i < 32; i++) { dwIntBit = (1 << i); if (LPC_USB->USBEpIntSt & dwIntBit) { // clear int (and retrieve status) LPC_USB->USBEpIntClr = dwIntBit; Wait4DevInt(CDFULL); bEPStat = LPC_USB->USBCmdData; // convert EP pipe stat into something HW independent bStat = ((bEPStat & EPSTAT_FE) ? EP_STATUS_DATA : 0) | ((bEPStat & EPSTAT_ST) ? EP_STATUS_STALLED : 0) | ((bEPStat & EPSTAT_STP) ? EP_STATUS_SETUP : 0) | ((bEPStat & EPSTAT_EPN) ? EP_STATUS_NACKED : 0) | ((bEPStat & EPSTAT_PO) ? EP_STATUS_ERROR : 0); // call handler if (_apfnEPIntHandlers[i / 2] != NULL) { _apfnEPIntHandlers[i / 2](IDX2EP(i), bStat); } } } } }