示例#1
0
//
//  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 ();
}
示例#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 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);
				}
			}
		}
	}
}