__interrupt VOID iUsbInterruptHandler(VOID) { BYTE bWakeUp = FALSE; //Check if the setup interrupt is pending. //We need to check it before other interrupts, //to work around that the Setup Int has lower priority then Input Endpoint 0 if (USBIFG & SETUPIFG) { bWakeUp = SetupPacketInterruptHandler(); USBIFG &= ~SETUPIFG; // clear the interrupt bit } switch (__even_in_range(USBVECINT & 0x3f, USBVECINT_OUTPUT_ENDPOINT7)) { case USBVECINT_NONE: break; case USBVECINT_PWR_DROP: __no_operation(); break; case USBVECINT_PLL_LOCK: break; case USBVECINT_PLL_SIGNAL: break; case USBVECINT_PLL_RANGE: if (wUsbEventMask & kUSB_clockFaultEvent) { bWakeUp = USB_handleClockEvent(); } break; case USBVECINT_PWR_VBUSOn: PWRVBUSonHandler(); if (wUsbEventMask & kUSB_VbusOnEvent) { bWakeUp = USB_handleVbusOnEvent(); } break; case USBVECINT_PWR_VBUSOff: PWRVBUSoffHandler(); if (wUsbEventMask & kUSB_VbusOffEvent) { bWakeUp = USB_handleVbusOffEvent(); } break; case USBVECINT_USB_TIMESTAMP: break; case USBVECINT_INPUT_ENDPOINT0: IEP0InterruptHandler(); break; case USBVECINT_OUTPUT_ENDPOINT0: OEP0InterruptHandler(); break; case USBVECINT_RSTR: USB_reset(); if (wUsbEventMask & kUSB_UsbResetEvent) { bWakeUp = USB_handleResetEvent(); } break; case USBVECINT_SUSR: USB_suspend(); if (wUsbEventMask & kUSB_UsbSuspendEvent) { bWakeUp = USB_handleSuspendEvent(); } break; case USBVECINT_RESR: USB_resume(); if (wUsbEventMask & kUSB_UsbResumeEvent) { bWakeUp = USB_handleResumeEvent(); } //-- after resume we will wake up! Independ what event handler says. bWakeUp = TRUE; break; case USBVECINT_SETUP_PACKET_RECEIVED: // NAK both IEP and OEP enpoints tEndPoint0DescriptorBlock.bIEPBCNT = EPBCNT_NAK; tEndPoint0DescriptorBlock.bOEPBCNT = EPBCNT_NAK; SetupPacketInterruptHandler(); break; case USBVECINT_STPOW_PACKET_RECEIVED: break; case USBVECINT_INPUT_ENDPOINT1: break; case USBVECINT_INPUT_ENDPOINT2: //send saved bytes from buffer... bWakeUp = CdcToHostFromBuffer(CDC0_INTFNUM); break; case USBVECINT_INPUT_ENDPOINT3: break; case USBVECINT_INPUT_ENDPOINT4: break; case USBVECINT_INPUT_ENDPOINT5: break; case USBVECINT_INPUT_ENDPOINT6: break; case USBVECINT_INPUT_ENDPOINT7: break; case USBVECINT_OUTPUT_ENDPOINT1: break; case USBVECINT_OUTPUT_ENDPOINT2: //call callback function if no receive operation is underway if (!CdcIsReceiveInProgress(CDC0_INTFNUM) && USBCDC_bytesInUSBBuffer(CDC0_INTFNUM)) { if (wUsbEventMask & kUSB_dataReceivedEvent) { bWakeUp = USBCDC_handleDataReceived(CDC0_INTFNUM); } } else { //complete receive opereation - copy data to user buffer bWakeUp = CdcToBufferFromHost(CDC0_INTFNUM); } break; case USBVECINT_OUTPUT_ENDPOINT3: break; case USBVECINT_OUTPUT_ENDPOINT4: break; case USBVECINT_OUTPUT_ENDPOINT5: break; case USBVECINT_OUTPUT_ENDPOINT6: break; case USBVECINT_OUTPUT_ENDPOINT7: break; default: break; } if (bWakeUp) { __bic_SR_register_on_exit(LPM3_bits); // Exit LPM0-3 __no_operation(); // Required for debugger } }
//this function is used only by USB interrupt. //It fills user receiving buffer with received data BOOL CdcToBufferFromHost (BYTE intfNum) { BYTE * pEP1; BYTE nTmp1; BYTE bWakeUp = FALSE; //per default we do not wake up after interrupt BYTE edbIndex; edbIndex = stUsbHandle[intfNum].edb_Index; if (CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft == 0){ //do we have somtething to receive? CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer = NULL; //no more receiving pending return (bWakeUp); } //No data to receive... if (!((tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX | tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY) & 0x80)){ return (bWakeUp); } if (CdcReadCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY == X_BUFFER){ //X is current buffer //this is the active EP buffer pEP1 = (BYTE*)stUsbHandle[intfNum].oep_X_Buffer; CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX; //second EP buffer CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pEP2 = (BYTE*)stUsbHandle[intfNum].oep_Y_Buffer; CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY; } else { //this is the active EP buffer pEP1 = (BYTE*)stUsbHandle[intfNum].oep_Y_Buffer; CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY; //second EP buffer CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pEP2 = (BYTE*)stUsbHandle[intfNum].oep_X_Buffer; CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX; } //how many byte we can get from one endpoint buffer nTmp1 = *CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1; if (nTmp1 & EPBCNT_NAK){ nTmp1 = nTmp1 & 0x7f; //clear NAK bit CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = nTmp1; //holds how many valid bytes in the EP buffer CopyUsbToBuff(pEP1, CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1, intfNum); nTmp1 = *CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2; //try read data from second buffer if ((CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft > 0) && //do we have more data to send? (nTmp1 & EPBCNT_NAK)){ //if the second buffer has received data? nTmp1 = nTmp1 & 0x7f; //clear NAK bit CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = nTmp1; //holds how many valid bytes in the EP buffer CopyUsbToBuff(CdcReadCtrl[INTFNUM_OFFSET( intfNum)].pEP2, CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2, intfNum); CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 = CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2; } } if (CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft == 0){ //the Receive opereation is completed CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer = NULL; //no more receiving pending if (wUsbEventMask & kUSB_receiveCompletedEvent){ bWakeUp |= USBCDC_handleReceiveCompleted(intfNum); } if (CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp){ //Is not read data still available in the EP? if (wUsbEventMask & kUSB_dataReceivedEvent){ bWakeUp |= USBCDC_handleDataReceived(intfNum); } } } return (bWakeUp); }
//this function is used only by USB interrupt. //It fills user receiving buffer with received data BOOL CdcToBufferFromHost() { BYTE * pEP1; BYTE nTmp1; BYTE bWakeUp = FALSE; // per default we do not wake up after interrupt if (CdcReadCtrl.nBytesToReceiveLeft == 0) // do we have somtething to receive? { CdcReadCtrl.pUserBuffer = NULL; // no more receiving pending return bWakeUp; } // No data to receive... if (!((tOutputEndPointDescriptorBlock[EDB(CDC_OUTEP_ADDR)].bEPBCTX | tOutputEndPointDescriptorBlock[EDB(CDC_OUTEP_ADDR)].bEPBCTY) & 0x80)) { return bWakeUp; } if (CdcReadCtrl.bCurrentBufferXY == X_BUFFER) //X is current buffer { //this is the active EP buffer pEP1 = (BYTE*)OEP3_X_BUFFER_ADDRESS; CdcReadCtrl.pCT1 = &tOutputEndPointDescriptorBlock[EDB(CDC_OUTEP_ADDR)].bEPBCTX; //second EP buffer CdcReadCtrl.pEP2 = (BYTE*)OEP3_Y_BUFFER_ADDRESS; CdcReadCtrl.pCT2 = &tOutputEndPointDescriptorBlock[EDB(CDC_OUTEP_ADDR)].bEPBCTY; } else { //this is the active EP buffer pEP1 = (BYTE*)OEP3_Y_BUFFER_ADDRESS; CdcReadCtrl.pCT1 = &tOutputEndPointDescriptorBlock[EDB(CDC_OUTEP_ADDR)].bEPBCTY; //second EP buffer CdcReadCtrl.pEP2 = (BYTE*)OEP3_X_BUFFER_ADDRESS; CdcReadCtrl.pCT2 = &tOutputEndPointDescriptorBlock[EDB(CDC_OUTEP_ADDR)].bEPBCTX; } // how many byte we can get from one endpoint buffer nTmp1 = *CdcReadCtrl.pCT1; while(nTmp1 == 0) { nTmp1 = *CdcReadCtrl.pCT1; } if(nTmp1 & EPBCNT_NAK) { nTmp1 = nTmp1 &0x7f; // clear NAK bit CdcReadCtrl.nBytesInEp = nTmp1; // holds how many valids bytes in the EP buffer CopyUsbToBuff(pEP1, CdcReadCtrl.pCT1); nTmp1 = *CdcReadCtrl.pCT2; //try read data from second buffer if ((CdcReadCtrl.nBytesToReceiveLeft > 0) && // do we have more data to send? (nTmp1 & EPBCNT_NAK)) // if the second buffer has received data? { nTmp1 = nTmp1 &0x7f; // clear NAK bit CdcReadCtrl.nBytesInEp = nTmp1; // holds how many valids bytes in the EP buffer CopyUsbToBuff(CdcReadCtrl.pEP2, CdcReadCtrl.pCT2); CdcReadCtrl.pCT1 = CdcReadCtrl.pCT2; } } if (CdcReadCtrl.nBytesToReceiveLeft == 0) // the Receive opereation is completed { CdcReadCtrl.pUserBuffer = NULL; // no more receiving pending if (wUsbEventMask & kUSB_receiveCompletedEvent) { bWakeUp = USBCDC_handleReceiveCompleted(1); } if (CdcReadCtrl.nBytesInEp) // Is not read data still available in the EP? { if (wUsbEventMask & kUSB_dataReceivedEvent) { bWakeUp = USBCDC_handleDataReceived(1); } } } return bWakeUp; }