//this function is used only by USB interrupt. //It fills user receiving buffer with received data BOOL HidToBufferFromHost() { BYTE * pEP1; BYTE nTmp1; BYTE bWakeUp = FALSE; // per default we do not wake up after interrupt if (HidReadCtrl.nBytesToReceiveLeft == 0) // do we have somtething to receive? { HidReadCtrl.pUserBuffer = NULL; // no more receiving pending return bWakeUp; } // No data to receive... if (!((tOutputEndPointDescriptorBlock[EDB(HID_OUTEP_ADDR)].bEPBCTX | tOutputEndPointDescriptorBlock[EDB(HID_OUTEP_ADDR)].bEPBCTY) & 0x80)) { return bWakeUp; } if (HidReadCtrl.bCurrentBufferXY == X_BUFFER) //X is current buffer { //this is the active EP buffer pEP1 = (BYTE*)OEP1_X_BUFFER_ADDRESS; HidReadCtrl.pCT1 = &tOutputEndPointDescriptorBlock[EDB(HID_OUTEP_ADDR)].bEPBCTX; //second EP buffer HidReadCtrl.pEP2 = (BYTE*)OEP1_Y_BUFFER_ADDRESS; HidReadCtrl.pCT2 = &tOutputEndPointDescriptorBlock[EDB(HID_OUTEP_ADDR)].bEPBCTY; } else { //this is the active EP buffer pEP1 = (BYTE*)OEP1_Y_BUFFER_ADDRESS; HidReadCtrl.pCT1 = &tOutputEndPointDescriptorBlock[EDB(HID_OUTEP_ADDR)].bEPBCTY; //second EP buffer HidReadCtrl.pEP2 = (BYTE*)OEP1_X_BUFFER_ADDRESS; HidReadCtrl.pCT2 = &tOutputEndPointDescriptorBlock[EDB(HID_OUTEP_ADDR)].bEPBCTX; } // how many byte we can get from one endpoint buffer nTmp1 = *HidReadCtrl.pCT1; if(nTmp1 & EPBCNT_NAK) { nTmp1 = nTmp1 &0x7f; // clear NAK bit HidReadCtrl.nBytesInEp = *(pEP1+1); // holds how many valid bytes in the EP buffer if (HidReadCtrl.nBytesInEp > nTmp1-2) { HidReadCtrl.nBytesInEp = nTmp1-2; } pEP1 += 2; // here starts user data HidCopyUsbToBuff(pEP1, HidReadCtrl.pCT1); nTmp1 = *HidReadCtrl.pCT2; //try read data from second buffer if ((HidReadCtrl.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 HidReadCtrl.nBytesInEp = *(pEP1+1); // holds how many valid bytes in the EP buffer if (HidReadCtrl.nBytesInEp > nTmp1-2) { HidReadCtrl.nBytesInEp = nTmp1-2; } HidReadCtrl.pEP2 += 2; // here starts user data HidCopyUsbToBuff(HidReadCtrl.pEP2, HidReadCtrl.pCT2); HidReadCtrl.pCT1 = HidReadCtrl.pCT2; } } if (HidReadCtrl.nBytesToReceiveLeft == 0) // the Receive opereation is completed { HidReadCtrl.pUserBuffer = NULL; // no more receiving pending if (wUsbEventMask & kUSB_receiveCompletedEvent) { bWakeUp = USBHID_handleReceiveCompleted(1); } if (HidReadCtrl.nBytesInEp) // Is not read data still available in the EP? { if (wUsbEventMask & kUSB_dataReceivedEvent) { bWakeUp = USBHID_handleDataReceived(1); } } } return bWakeUp; }
__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: //send saved bytes from buffer... bWakeUp = HidToHostFromBuffer(HID0_INTFNUM); break; case USBVECINT_INPUT_ENDPOINT2: 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: //call callback function if no receive operation is underway if (!HidIsReceiveInProgress(HID0_INTFNUM)) { if (wUsbEventMask & kUSB_dataReceivedEvent) { bWakeUp = USBHID_handleDataReceived(HID0_INTFNUM); } } else { //complete receive opereation - copy data to user buffer bWakeUp = HidToBufferFromHost(HID0_INTFNUM); } break; case USBVECINT_OUTPUT_ENDPOINT2: 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 HidToBufferFromHost (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 (HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft == 0){ //do we have somtething to receive? HidReadCtrl[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 (HidReadCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY == X_BUFFER){ //X is current buffer //this is the active EP buffer pEP1 = (BYTE*)stUsbHandle[intfNum].oep_X_Buffer; HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX; //second EP buffer HidReadCtrl[INTFNUM_OFFSET(intfNum)].pEP2 = (BYTE*)stUsbHandle[intfNum].oep_Y_Buffer; HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY; } else { //this is the active EP buffer pEP1 = (BYTE*)stUsbHandle[intfNum].oep_Y_Buffer; HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY; //second EP buffer HidReadCtrl[INTFNUM_OFFSET(intfNum)].pEP2 = (BYTE*)stUsbHandle[intfNum].oep_X_Buffer; HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX; } //how many byte we can get from one endpoint buffer nTmp1 = *HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1; if (nTmp1 & EPBCNT_NAK){ nTmp1 = nTmp1 & 0x7f; //clear NAK bit HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = *(pEP1 + 1); //holds how many valid bytes in the EP buffer if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp > nTmp1 - 2){ HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = nTmp1 - 2; } pEP1 += 2; //here starts user data HidCopyUsbToBuff(pEP1, HidReadCtrl[INTFNUM_OFFSET( intfNum)].pCT1,intfNum); nTmp1 = *HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2; //try read data from second buffer if ((HidReadCtrl[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 HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = *(pEP1 + 1); //holds how many valid bytes in the EP buffer if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp > nTmp1 - 2){ HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = nTmp1 - 2; } HidReadCtrl[INTFNUM_OFFSET(intfNum)].pEP2 += 2; //here starts user data HidCopyUsbToBuff(HidReadCtrl[INTFNUM_OFFSET( intfNum)].pEP2, HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2,intfNum); HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 = HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2; } } if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft == 0){ //the Receive opereation is completed HidReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer = NULL; //no more receiving pending if (wUsbEventMask & kUSB_receiveCompletedEvent){ bWakeUp = USBHID_handleReceiveCompleted(intfNum); } if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp){ //Is not read data still available in the EP? if (wUsbEventMask & kUSB_dataReceivedEvent){ bWakeUp = USBHID_handleDataReceived(intfNum); } } } return (bWakeUp); }