// // USB interrupt handler // static void usbISR_Handler (void) { U32 dwStatus; U32 dwIntBit; U32 dwEpIntSt, dwIntMask; U8 bEPStat, bDevStat, bStat; U16 wFrame; int i; portBASE_TYPE higherPriorityTaskWoken = pdFALSE; dwStatus = USB_DevIntSt; if (dwStatus & USB_DevIntSt_FRAME) { USB_DevIntClr = USB_DevIntClr_FRAME; if (_pfnFrameHandler != NULL) { wFrame = usbHardwareCommandRead (CMD_DEV_READ_CUR_FRAME_NR); _pfnFrameHandler (wFrame); } } if (dwStatus & USB_DevIntSt_DEVSTAT) { USB_DevIntClr = USB_DevIntClr_DEVSTAT; bDevStat = usbHardwareCommandRead (CMD_DEV_STATUS); if (bDevStat & (CON_CH | SUS_CH | RST)) { bStat = ((bDevStat & CON) ? DEV_STATUS_CONNECT : 0) | ((bDevStat & SUS) ? DEV_STATUS_SUSPEND : 0) | ((bDevStat & RST) ? DEV_STATUS_RESET : 0); if (_pfnDevIntHandler != NULL) _pfnDevIntHandler (bStat); } } if (dwStatus & USB_DevIntSt_EPSLOW) { USB_DevIntClr = USB_DevIntClr_EPSLOW; dwIntMask = 0xffffffff; for (i = 0; i < 32; i++) { dwIntBit = (1 << i); dwIntMask <<= 1; dwEpIntSt = USB_EpIntSt; if (dwEpIntSt & dwIntBit) { USB_EpIntClr = dwIntBit; usbWaitForDeviceInterrupt (USB_DevIntSt_CDFULL); bEPStat = USB_CmdData; 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); if (_apfnEPIntHandlers [i / 2]) higherPriorityTaskWoken |= _apfnEPIntHandlers [i / 2] (IDX2EP (i), bStat); } if (!(dwEpIntSt & dwIntMask)) break; } } VIC_VectAddr = (unsigned portLONG) 0; if (higherPriorityTaskWoken) portYIELD_FROM_ISR (); }
/** USB interrupt handler @todo Get all 11 bits of frame number instead of just 8 Endpoint interrupts are mapped to the slow interrupt */ void USBHwISR(void) { unsigned long dwStatus; unsigned long dwIntBit; unsigned char bEPStat, bDevStat, bStat; int i; unsigned short 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 if (_pfnDevIntHandler != NULL) { _pfnDevIntHandler(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); } } } } }