Example #1
0
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();
}
Example #2
0
/**
    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);
                }
            }
        }
    }
}